Lemon Squeezy Failover Runbook
هذا المحتوى غير متوفر بلغتك بعد.
Lemon Squeezy Failover Runbook
Section titled “Lemon Squeezy Failover Runbook”Switch nSelf billing from Stripe to Lemon Squeezy in under 15 minutes. Existing Stripe subscriptions keep running — only new checkouts route through Lemon Squeezy.
When to use this
Section titled “When to use this”- Stripe experiences a regional outage or checkout degradation
- Stripe terminates the nSelf merchant account
- EU VAT or US sales-tax compliance requires a Merchant of Record
Prerequisites
Section titled “Prerequisites”The following must be configured in ping_api environment variables before starting:
| Variable | Where to find it |
|---|---|
LEMONSQUEEZY_API_KEY | Lemon Squeezy dashboard → Settings → API Keys |
LEMONSQUEEZY_STORE_ID | Dashboard URL: app.lemonsqueezy.com/stores/{id} |
LEMONSQUEEZY_WEBHOOK_SECRET | Dashboard → Webhooks → your endpoint secret |
LEMONSQUEEZY_VARIANT_ID_* | Dashboard → Products → each product → Variants |
Verify the webhook endpoint is registered at:
https://ping.nself.org/webhooks/lemonsqueezywith all subscription events enabled (subscription_created, subscription_updated,
subscription_cancelled, order_created).
Step-by-step activation (~10 min)
Section titled “Step-by-step activation (~10 min)”1. Verify LS credentials (2 min)
Section titled “1. Verify LS credentials (2 min)”source ~/.claude/vault.envcurl -s -o /dev/null -w "%{http_code}" \ -H "Authorization: Bearer $LEMONSQUEEZY_API_KEY" \ https://api.lemonsqueezy.com/v1/stores/$LEMONSQUEEZY_STORE_ID# Expected: 2002. Health-check the admin endpoint (1 min)
Section titled “2. Health-check the admin endpoint (1 min)”curl -s -H "X-Admin-Key: $PING_API_ADMIN_KEY" \ https://ping.nself.org/admin/payment-provider | jq .Expected output:
{ "active": "stripe", "persisted": "stripe", "stripe_configured": true, "lemonsqueezy_configured": true}If lemonsqueezy_configured is false, stop here — set the missing env vars and redeploy
ping_api before continuing.
3. Switch the active provider (1 min)
Section titled “3. Switch the active provider (1 min)”curl -s -X POST \ -H "X-Admin-Key: $PING_API_ADMIN_KEY" \ -H "Content-Type: application/json" \ -d '{"provider":"lemonsqueezy"}' \ https://ping.nself.org/admin/payment-provider | jq .Expected:
{ "previous": "stripe", "active": "lemonsqueezy", "message": "Payment provider switched to lemonsqueezy. New checkouts will use lemonsqueezy. Existing subscriptions continue unaffected."}4. Verify the switch took effect (1 min)
Section titled “4. Verify the switch took effect (1 min)”curl -s -H "X-Admin-Key: $PING_API_ADMIN_KEY" \ https://ping.nself.org/admin/payment-provider | jq .active# Expected: "lemonsqueezy"5. Test a checkout (5 min)
Section titled “5. Test a checkout (5 min)”Open https://cloud.nself.org/pricing in a private window and start a checkout.
Confirm the checkout page is hosted at checkout.lemonsqueezy.com rather than
checkout.stripe.com.
If Stripe Elements appear instead of the LS checkout page, the cloud frontend is
caching old provider state. Add a query param to bust the cache:
?_bust=$(date +%s).
6. Update status page (1 min)
Section titled “6. Update status page (1 min)”Post to status.nself.org (or nSentry status page if live):
Billing: switched to backup payment provider. Existing subscriptions unaffected.Coexistence during switchover
Section titled “Coexistence during switchover”While PAYMENT_PROVIDER=lemonsqueezy:
- New checkouts go through Lemon Squeezy
- Existing Stripe subscriptions keep renewing — Stripe webhooks (
/webhooks/stripe) continue processing renewals, cancellations, and payment failures - The
/webhooks/lemonsqueezyendpoint handles new LS events in parallel - License activation works identically for both providers
There is no need to migrate existing Stripe subscribers to Lemon Squeezy. They stay on Stripe until they cancel; new sign-ups go through LS.
Reverting to Stripe
Section titled “Reverting to Stripe”curl -s -X POST \ -H "X-Admin-Key: $PING_API_ADMIN_KEY" \ -H "Content-Type: application/json" \ -d '{"provider":"stripe"}' \ https://ping.nself.org/admin/payment-provider | jq .Environment variable alias
Section titled “Environment variable alias”The internal switch uses PAYMENT_PROVIDER. The admin panel and cloud frontend
also read BILLING_PROVIDER as an alias for display purposes — set either one.
The factory in payments/factory.ts reads PAYMENT_PROVIDER as the authoritative
source; BILLING_PROVIDER is surfaced in health checks only.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Check |
|---|---|
lemonsqueezy_configured: false | Missing one of the three required LS env vars |
| Checkout still goes to Stripe | Vercel may be caching a CDN response — check PAYMENT_PROVIDER in Vercel env |
| Webhook signature failures | LEMONSQUEEZY_WEBHOOK_SECRET mismatch — regenerate in LS dashboard and redeploy |
| License not activated after purchase | Check np_payment_events for the LS event ID; check ping_api logs |
503 Lemon Squeezy not fully configured | One of the three required vars is missing from the running ping_api process |