Billing
Upgrading from Free
Go to /app/billing in the dashboard and pick Developer ($19/mo) or Pro ($79/mo). You'll be redirected to Stripe Checkout. After the payment succeeds, your account is upgraded within seconds (via webhook) and the managed API unlocks.
Managing your subscription
Once you're on a paid plan, the same /app/billing page opens the Stripe customer portal where you can:
- Update your payment method
- Switch between Developer and Pro
- Download invoices
- Cancel the subscription
Changes take effect immediately for upgrades and at the end of the billing period for downgrades / cancellations. Your data is never deleted when you cancel — you just lose managed-API access and fall back to local-only mode.
Failed payments
If a payment fails, your plan_status flips to past_due. The API keeps working for 7 days (Stripe's default retry window). If payment still fails after that, Stripe cancels the subscription and the account drops to Free.
To fix a failed payment, open the customer portal and update your card.
Invoices and receipts
Stripe emails a receipt for every successful charge. Full invoice history is available in the customer portal under "Billing history".
Test mode vs live mode
OraMemory supports two Stripe modes simultaneously — you can develop against test keys, flip to live in one click when ready, flip back if you need to debug. Both key sets stay on the server; only the active one is used.
| Mode | Keys prefix | Purpose |
|---|---|---|
| test | sk_test_…, pk_test_… |
Dev + QA. Use Stripe's test cards. No real money. |
| live | sk_live_…, pk_live_… |
Real customers, real charges. |
A yellow banner on the billing page makes it obvious when test mode is active. Subscription state created in one mode is completely isolated from the other — each mode has its own id_stripe_customer and id_stripe_sub columns on the account.
Switching modes
The active mode lives in app_config.stripe_mode. An admin can flip it at any time from /admin/config — no env-file edits, no service restart.
Webhook events from both modes hit the same URL (/webhooks/stripe). The handler tries every configured signing secret and picks whichever matches the signature, so one endpoint serves both.
Self-hosted billing
Wire your own Stripe account by setting the key pairs in /etc/oramemory.env:
# Test mode
STRIPE_TEST_SECRET_KEY=sk_test_...
STRIPE_TEST_PUBLISHABLE_KEY=pk_test_...
STRIPE_TEST_WEBHOOK_SECRET=whsec_...
STRIPE_TEST_PRICE_DEVELOPER=price_...
STRIPE_TEST_PRICE_PRO=price_...
# Live mode
STRIPE_LIVE_SECRET_KEY=sk_live_...
STRIPE_LIVE_PUBLISHABLE_KEY=pk_live_...
STRIPE_LIVE_WEBHOOK_SECRET=whsec_...
STRIPE_LIVE_PRICE_DEVELOPER=price_...
STRIPE_LIVE_PRICE_PRO=price_...
Register the webhook endpoint at https://your-domain/webhooks/stripe once per mode in the Stripe dashboard. Subscribe each endpoint to:
customer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedinvoice.paidinvoice.payment_failed
Set the active mode at /admin/config (stripe_mode = test or live). After changing env values: systemctl reload php8.3-fpm. Switching modes via the admin UI needs no reload.
Go-live checklist
- Create Developer + Pro recurring prices in Stripe test mode.
- Fill in all five
STRIPE_TEST_*env vars. - Register the test webhook endpoint in Stripe dashboard and copy its signing secret to
STRIPE_TEST_WEBHOOK_SECRET. systemctl reload php8.3-fpm.- Sign up a test account, upgrade through
/app/billingwith card4242 4242 4242 4242, verify your plan flips todeveloper. - Repeat steps 1–4 in Stripe live mode with
STRIPE_LIVE_*vars. - Flip
stripe_modetoliveat/admin/config. Done.