Senteur is a specialized e-commerce engine for boutique fragrance retailers. Built with a custom PHP 8.3 MVC architecture, it provides a high-performance shopping experience paired with a robust administrative suite for managing complex fragrance metadata.
A specialized storefront for fragrance discovery and seamless checkout.
- Olfactory Discovery: Filter and search the catalog by specific scent notes (Top, Heart, Base).
- Commerce Flow: Session-persistent cart, secure customer profiles, and saved address management.
- Integrated Payments: Full Stripe Checkout integration with automated webhook handling for order fulfillment.
- Catalog Management: Detailed control over fragrance concentrations, brands, and availability.
- Fragrance Metadata: Dedicated tools to manage the library of scent notes and olfactory families.
- Order Fulfillment: Real-time order tracking and customer status management.
📸 View Interface Showcases (Click to expand)
| Product Detail Page | Administrative Workspace |
|---|---|
![]() |
![]() |
| Gallery, reviews, and scent notes | Managing inventory and metadata |
| Layer | Technology |
|---|---|
| Language | PHP 8.3 (Strictly typed) |
| Architecture | Custom MVC with Service/Repository layers |
| Web Server | Nginx |
| Infrastructure | PHP-FPM & Docker Compose |
| Tunneling | Cloudflare Tunnel (Optional Quick Tunnel support) |
| Database | MySQL 8.0 |
| Payments | Stripe API (stripe/stripe-php) |
The application implements a decoupled MVC pattern to separate concerns and improve testability:
- Request Pipeline: Nginx →
index.php→ Bootstrapper → Regex Router → Controller. - Service Layer: Controllers remain lean, delegating all domain logic and third-party integrations (like Stripe) to specialized Services.
- Data Persistence: Repositories encapsulate PDO queries, ensuring the core remains independent of the database schema.
- View Layer: Server-side rendered PHP templates with a shared layout system.
senteur/
├── docker/ # Container configuration (PHP, Nginx, MySQL)
├── docs/ # Architecture diagrams and technical deep-dives
├── public/ # Web root, assets, and runtime uploads
├── src/ # Core Logic: Controllers, Services, Repositories, Views
└── resources/ # Raw demo assets and seeding data
- Docker & Docker Compose
- Port
8080and3306available
- Environment Setup:
cp .env.example .env- Launch Containers:
docker compose up --build- Access the App: Navigate to
http://localhost:8080
The system is seeded with the following accounts for testing:
- Admin:
admin@example.com/password123 - Customer:
mario@example.com/password123
To test the payment flow, configure your Stripe keys in .env:
STRIPE_SECRET_KEY=sk_test_...
STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...Webhook Local Forwarding:
stripe listen --forward-to localhost:8080/webhooks/stripeTo expose the application securely for testing (e.g., for Stripe Webhooks) without configuring port forwarding:
- Enable the profile in your
.env:COMPOSE_PROFILES=cloudflare - Start the stack:
docker compose up - Retrieve the temporary
trycloudflare.comURL from thecloudflaredservice logs.
- Fragrantica: Scent profiles and olfactory data.

