Q2 2026 TECH SPEC
Smart Checkout
Act 1 and Continuation ship Q1. PM gate falls. Checkout unifies.
| Status | PLANNED — Q1 foundation in progress |
|---|---|
| Driver | Jared Goguen (engine), Frontend Engineering (UC expansion) |
| Repos | subscriptions-api (PM gate), billing-webhooks (event handling), stratus (UC + frontend) |
| Staffing | 2 engineers backend, 1 engineer frontend |
Q1 ships the foundation that makes everything in this spec safe. Act 1 sets Stripe parameters on every payment path so subscriptions confirm before committing state. The Continuation Workflow defers entitlement provisioning to payment success — if payment fails, nothing was granted, nothing to undo. Together they prove the core invariant: no entitlement without payment. With that proven, the PM gate becomes unnecessary.
- 0
- rollbacks after Continuation
- 0
- entitlements without payment
The Q1 foundation. Act 1 migrates all Stripe API call sites to confirm-before-commit parameters. The Continuation Workflow moves entitlement provisioning to the payment success path. Rollback code is deleted.
Two deliverables in sequence, one independent. Q1 foundation unlocks both.
- 6
- endpoints with PM gate checks
- 402
- HTTP status code (error 1210)
- ~160
- tickets/month from PM-related blocks
Six endpoints check for a valid payment method before allowing subscription changes. If no PM exists, or the PM is expired/invalid, the request fails with HTTP 402 (error 1210). This blocks legitimate users from subscribing — especially new customers who haven't added a payment method yet.
After: the engine returns a client_secret instead of blocking. The frontend uses Stripe.js to collect payment with the customer present. The subscription activates on payment success.
| Phase | What | Detail | Reversible? |
|---|---|---|---|
| 1 | PM validation softening | Downgrade 402 to warning in non-critical paths. Measure impact. | Yes |
| 2 | Gate removal | Remove PM checks from all 6 endpoints. Return client_secret on missing PM. | No — commitment point |
| 3 | Frontend integration | Dashboard renders Stripe.js when client_secret returned. Card, PayPal, 3DS inline. | Yes (feature flag) |
| 4 | Error handling | Payment failure UX. Retry flow. Expiry handling. | Yes |
| 5 | Monitoring | Alert on payment failure rates, conversion rates, time-to-payment. | Yes |
| 6 | Cleanup | Delete PM gate code, old error paths, 402 documentation. | No (forward only) |
Deploy backend first (API returns client_secret instead of 402 — old frontend still works), then frontend (Stripe.js Elements renders when client_secret detected). 5 subscription endpoints change from 402 to client_secret. Exception: billing profile allows update without PM.
- 9
- products joining UC in Q2
- 1
- Stripe.js component for all products
- 3
- checkout systems being replaced
Unified Checkout (UC) replaces three checkout systems: Multisku checkout, Billing Profile payment method management, and legacy per-product payment flows. One Stripe.js component handles card, PayPal, and 3DS for every product. Q2 adds 9 products. Independent of the PM gate chain — runs in parallel.
All 9 currently on Multisku. Medium complexity (usage-based pricing): Workers Paid, R2, Stream, Durable Objects. Low complexity (fixed pricing): Pages, Images, Queues, D1, Vectorize.
One new invariant enforced in Q2. The deliverable is not done until the invariant is enforced at all three tiers.
| # | Invariant | Property |
|---|---|---|
| I4 | No PM gate rejections | Zero 402/1210 responses across all 6 endpoints. client_secret returned instead. |
Inline: gate code deleted — absence IS enforcement. Batch: not needed. Alert: pm_gate_rejection_rate metric — alert if > 0 for 15+ minutes.
| Deliverable | Ships | Depends On | Δ/mo | Estimate |
|---|---|---|---|---|
| PM Gate Removal | Early Q2 | Continuation (Q1 ✓) | −20 | 1+1+2 weeks |
| UC Q2 Cohort | Q2 (parallel) | — | — | 9 products, ~1 week each |
| # | Decision | Owner | By When | Status | Recommendation | Risk if Wrong |
|---|---|---|---|---|---|---|
| 1 | Complete list of error 1210 consumers | Engineering | Jun 16 (PM P2) | OPEN | Code search + runtime monitoring | Critical — broken UX |
| 2 | PayPal UX through Stripe.js Elements | Engineering | Jun 23 (PM P3) | OPEN | End-to-end test | High — PayPal users blocked |
| 3 | Subscription conversion rate baseline | Product | Jun 9 (PM P1) | OPEN | Instrument before removing gate | Medium — can't measure impact |
| 4 | Multisku sunset — products remaining after Q2? | Frontend Eng | May 15 | OPEN | Track remaining products | Low — Multisku persists Q3 |
| Risk | Impact | Owner | Mitigation |
|---|---|---|---|
| Premature gate removal | Critical | Engine lead | Continuation workflow must be proven first. Removing the gate without payment ordering causes drift. |
| Unknown 1210 consumers | Critical | Frontend Eng | Audit all frontend and API consumers of error 1210 before Phase 2. Missed consumer = broken UX. |
| PayPal UX | High | Frontend Eng | PayPal through Stripe.js Elements — test end-to-end. Redirects may not work inline. |
| Conversion regression | Medium | Product | Phase 1 metrics before Phase 2 commitment. Investigate if conversion drops. |
| What | Why |
|---|---|
| Probation | Separate track. Probation customers already have service. Policy enforcement, not payment ordering. |
| Shadow billing / Reactor | Separate workstream. Validates the billing engine, but not part of this quarter's checkout scope. |
| Product-specific UC pricing | Each product may have custom pricing/display logic. Frontend team handles per-product testing. |
| Dunning / bad debt | Covered by the Honest Invoicing workstream. |
PM gate removed. Checkout unified. One Stripe.js component handles every product, every payment method.