1 · MUST path
Objective — walk the launch-blocking spine of Phase 8 in order — brand & core settings, transactional mail with DNS auth, a payment gateway with verified webhooks, plans & feature flags, then a full seed + verify pass — so the product is provably sellable.
Background
Section titled “Background”The launch-blocking spine of Phase 8: do these in order and the product is sellable. Each step summarizes the MUST work and links to the deep page for the SHOULD/OPTIONAL depth. If you only have one afternoon, this is the page.
flowchart LR A["1. Brand & settings"] --> B["2. Transactional mail"] B --> C["3. Payment gateway"] C --> D["4. Verify webhook signature"] D --> E["5. Plans & feature flags"] E --> F["6. Seed + verify every flow"] F --> G(["Launch-ready"])1. Lock the brand & core settings
Section titled “1. Lock the brand & core settings”Set the visual identity and the core application values before anything downstream (mail templates, checkout branding) consumes them.
-
Lock the brand kit. Logo light/dark, favicon, OG image, and a color palette run through a WCAG 4.5:1 contrast check, plus heading/body fonts. (Deep page: Brand kit.)
- ✅ Logo set, favicon, OG image, and a WCAG-checked palette are ready.
-
Enter the core values in the admin panel. App name, default locale/timezone, primary color.
- ✅ App name, locale, timezone, and primary color saved in the admin UI.
-
Save brand values as reproducible reference files in your project context — not just in the UI.
- ✅ Brand values exist as versioned reference files, not only in the admin panel.
2. Wire transactional mail
Section titled “2. Wire transactional mail”Pick one provider, authenticate the sending domain via DNS, then wire credentials as placeholders and prove a real send lands in the inbox.
-
Wire the mail credentials as placeholders in the production environment.
Terminal window # .env — placeholders only; real values come from your secrets managerMAIL_MAILER=smtpMAIL_HOST=<smtp-host>MAIL_PORT=587MAIL_USERNAME=<smtp-username>MAIL_PASSWORD=<smtp-api-key>MAIL_ENCRYPTION=tlsMAIL_FROM_ADDRESS=noreply@<your-domain>MAIL_FROM_NAME="<App Name>"# Expected: env loads with the MAIL_* placeholders present, real values from the vault- ✅ The
MAIL_*block is wired with placeholders; real values stay in the secrets manager.
- ✅ The
-
Send a real test and confirm it lands in the inbox (not spam) with authentication passing.
Terminal window php artisan tinker>>> Mail::raw('Test '.now(), fn($m) => $m->to('you@<your-domain>')->subject('Mail test'));# Expected: arrives in inbox; headers show spf=pass, dkim=pass, dmarc=pass- ✅ The test email arrives in the inbox with
spf=pass,dkim=pass,dmarc=pass.
- ✅ The test email arrives in the inbox with
3. Connect a payment gateway
Section titled “3. Connect a payment gateway”Create the external account, generate test keys first, enter them in the admin panel (built-in module) or wire env placeholders (custom integration), then register the webhook endpoint and store its signing secret.
-
Generate test keys and wire them — paste into the admin panel module, or set env placeholders for a custom integration.
Terminal window # .env — placeholders; never commit real keysSTRIPE_KEY=<pk_test_xxx>STRIPE_SECRET=<sk_test_xxx>STRIPE_WEBHOOK_SECRET=<whsec_xxx># Expected: the three placeholders are present; real keys live in the vault- ✅ Test keys are in place (admin panel or env) and the webhook signing secret is stored.
4. Verify the webhook signature (critical)
Section titled “4. Verify the webhook signature (critical)”A handler that trusts unverified POST bodies lets anyone upgrade themselves to enterprise for free. Confirm signature verification runs, then exercise it locally.
-
Forward and trigger a webhook to confirm the signature verifies.
Terminal window stripe listen --forward-to https://<app>.test/stripe/webhookstripe trigger checkout.session.completed# Expected: handler runs, signature verifies, subscription row created/updated- ✅ The handler runs, the signature verifies, and a subscription row is created or updated.
5. Define plans & feature flags
Section titled “5. Define plans & feature flags”Define tiers, intervals, and prices in the admin plans manager (or seed them in code), and map each tier to the features it unlocks. The provider-side Products/Prices must also exist in the gateway dashboard — a plan that exists only in your DB will 500 at checkout.
-
Define the plans in the admin plans manager, or seed them in code when no admin UI exists.
Terminal window # Code-based fallback only — when no admin plans UI existsphp artisan make:seeder PlansSeederphp artisan db:seed --class=PlansSeeder# Expected: the seeder runs and the plan rows exist- ✅ Tiers, intervals, and prices exist, and each tier maps to the features it unlocks.
-
Confirm the provider-side Products/Prices exist in the gateway dashboard, matching the DB price IDs.
- ✅ Each plan’s price maps to a real provider-side Price ID — no DB-only plans.
6. Seed + verify every flow
Section titled “6. Seed + verify every flow”Prove the product end-to-end in staging before launch. This is the gate: nothing ships until every flow is proven.
-
Exercise the upgrade and decline paths. Test card
4242 4242 4242 4242upgrades a user; declined card4000 0000 0000 0002shows an error and does not upgrade.- ✅ The test card upgrades the user; the declined card errors and does not upgrade.
-
Confirm
/pricingrenders correctly. All tiers show with correct prices, and each price maps to a real provider-side Price ID.- ✅
/pricingrenders every tier with correct prices mapped to real Price IDs.
- ✅
-
Confirm the transactional emails arrive. Password reset and welcome emails arrive and render in Gmail, Outlook, and an iOS client.
- ✅ Password reset and welcome emails arrive and render across Gmail, Outlook, and iOS.
-
Run a small live payment, then refund it. A real charge confirms the live keys work end-to-end.
- ✅ A small live payment succeeds and is refunded cleanly.
Checklist
Section titled “Checklist”Do not mark this step done until every box below is checked.
- 🔀 Brand applied — set in the admin panel and saved as reproducible reference files.
- 🔀 Test mail lands — arrives in the inbox with
spf/dkim/dmarc=pass. - 🔀 Payment gateway connected — test keys wired; webhook signature verified.
- 👤 Plans render —
/pricingshows correct prices; gateway Products/Prices exist. - 🔀 Every flow proven in staging — upgrade, decline, emails, live charge + refund.