Migrating From Stripe-Direct Billing
Many apps start with local auth, direct Stripe webhook handlers, and a few entitlement checks near route handlers. That works until multiple apps, admin grants, wallet state, local demos, or support debugging need the same answer: “what can this user do in this application right now?”
SPAPS gives that question a governed backend path.
What Usually Exists First
| Existing piece | Common location | Migration risk |
|---|---|---|
| User identity | App auth library or framework session | User IDs are not consistently tied to app identity |
| Stripe customer/subscription | App database plus webhook handler | Event replay and manual fixes can drift from entitlement checks |
| Entitlement checks | Route handlers, middleware, feature flags, or frontend guards | Different surfaces answer access questions differently |
| Admin override | Support scripts or direct database edits | No shared proof artifact for why access changed |
| Local demo mode | Fixture data or bypass flags | Local proof does not match production-shaped behavior |
Target Shape
Migration Sequence
-
Inventory every current access decision: route guards, frontend flags, webhook writes, support scripts, and scheduled jobs.
-
Name the SPAPS application, local runtime mode, publishable-key origins, and backend server boundary.
-
Run the local proof before changing production code:
npx spaps local npx spaps quickstart --json npx spaps verify --json -
Map Stripe events and manual grants to the entitlement model described in billing and entitlements.
-
Replace one low-risk entitlement check with a backend call through the documented API-key boundary.
-
Keep the old webhook-derived fields read-only until SPAPS verification output and app behavior agree.
-
Remove duplicated route checks only after deployment validation passes for the new path.
Rollback Notes
- Keep old Stripe webhook writes available until every critical access check has a SPAPS-backed equivalent.
- Preserve a read-only audit trail of customer, subscription, wallet, and entitlement identifiers during cutover.
- Treat mismatched local and production modes as a deployment blocker, not as a frontend bug.
Do not migrate by copying webhook conditionals into a new service. The value of SPAPS is one control-plane answer for app identity, user identity, billing state, and entitlements.