A headless ecommerce platform for small businesses. Built with Laravel 13, Inertia.js v3, Vue 3, and Tailwind CSS v4.
Admin Dashboard
- Product management — CRUD, variants, images, categories, stock tracking, bulk actions, CSV/PDF export
- Product types — simple (no variants), variable (option/variant matrix), bundled (component products with calculated stock)
- Product tags — taggable system with colour-coded badges; full admin CRUD, product integration, storefront display
- Advanced product search — price range, description text, category, and availability filters on the storefront catalogue
- On-sale pricing — per-product
on_saleflag and sitewidesale_discount_percentagein store settings; storefront shows discounted prices - SEO fields — per-product meta title, meta description, and auto-generated slugs
- Related products — curated product relationships shown on storefront detail pages
- Order management — full lifecycle, manual order creation, invoice PDF, bulk status updates, email notifications
- Customer management — profiles, purchase history
- Coupon management — percentage and fixed discounts, expiry, usage limits
- Returns & refunds — approval/rejection workflow, refund processing
- Shipping — flat-rate methods and Canada Post calculated rates
- Tax — province-aware compliance engine with per-province rates at checkout
- Inventory alerts — automated low-stock threshold notifications per product and per variant
- Store settings — name, currency, tax configuration
- Revenue chart and KPI dashboard
- Activity log
- Role-based access —
super-admin,admin,manager,customer
Storefront
- Public product catalogue, detail pages, cart, and checkout
- "What's Included" section for bundled products
- Stripe and PayMongo payment integration
- AI-powered support chat (Laravel AI SDK)
Headless API (/api/v1/)
POST /api/v1/auth/register— create user + customer profile, returns Sanctum tokenPOST /api/v1/auth/login— validate credentials, returns tokenPOST /api/v1/auth/logout— revoke current access tokenGET /api/v1/user— authenticated user profile with customer dataGET /api/v1/orders— paginated order list scoped to authenticated userGET /api/v1/orders/{order}— single order detail with ownership enforcement- Auth and orders routes protected with
auth:sanctummiddleware
| Layer | Technology |
|---|---|
| Backend | PHP 8.4, Laravel 13 |
| Frontend | Vue 3, Inertia.js v3, Tailwind CSS v4 |
| Auth | Laravel Fortify (web), Laravel Sanctum (API) |
| Permissions | Spatie Laravel Permission |
| Payments | Stripe, PayMongo |
| AI | Laravel AI SDK (laravel/ai) |
| barryvdh/laravel-dompdf | |
| Routing (TS) | Laravel Wayfinder |
| Testing (PHP) | PHPUnit 12 |
| Testing (JS) | Vitest + @vue/test-utils |
| Database | SQLite (dev), MySQL/PostgreSQL (prod) |
- PHP 8.2+
- Node.js 20+
- Composer
1. Clone and install
git clone https://github.com/willard/minishop.git
cd minishop
composer setupThe composer setup command installs dependencies, copies .env.example to .env, generates an app key, runs migrations, installs npm packages, and builds assets.
2. Seed the database
php artisan db:seedThis runs all seeders including roles/permissions, sample products, categories, orders, coupons, and shipping methods.
3. Start the development server
composer run devThis starts Laravel (localhost:8000), Vite, the queue worker, and Pail log viewer concurrently.
Copy .env.example to .env and configure:
# Stripe
STRIPE_KEY=pk_test_...
STRIPE_SECRET=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
# PayMongo (optional)
PAYMONGO_PUBLIC_KEY=pk_test_...
PAYMONGO_SECRET_KEY=sk_test_...
# Mail (use log driver in development)
MAIL_MAILER=log
MAIL_FROM_ADDRESS=hello@minishop.com
# AI support chat
ANTHROPIC_API_KEY=sk-ant-...PHP
php artisan test --compactJavaScript
npm run test:runBoth (with Pint lint check)
composer testapp/
├── Actions/ # Single-purpose business logic classes
├── Enums/ # PHP 8.1 backed enums (OrderStatus, etc.)
├── Http/
│ ├── Controllers/
│ │ ├── Admin/ # Admin dashboard controllers
│ │ ├── Account/ # Customer account controllers
│ │ ├── Storefront/
│ │ └── Webhooks/ # Stripe & PayMongo webhook handlers
│ └── Requests/Admin/
├── Mail/ # Queued mailables
├── Models/
└── Policies/
resources/js/
├── actions/ # Wayfinder-generated TypeScript route functions
├── components/ # Shared Vue components (ui/, layout/)
├── pages/
│ ├── admin/ # Admin dashboard pages
│ └── storefront/ # Public storefront pages
└── tests/ # Vitest tests mirroring pages/ structure
routes/
├── web.php # All web routes (admin + storefront + account)
└── api.php # API routes (v1: auth, user, orders)
| Role | Access |
|---|---|
super-admin |
Full access including delete operations |
admin |
Full access except destructive actions |
manager |
Read/write access, no delete |
customer |
Storefront and account area only |
- All monetary values are stored as integers (cents)
Orderroute key isorder_number, notid- Admin routes are prefixed
/dashboardand namedadmin.* - Wayfinder generates typed TypeScript functions for all routes — never hardcode URLs in Vue files
- Run
vendor/bin/pint --dirtyafter modifying PHP files - Run
php artisan wayfinder:generateafter adding or changing routes
MIT