Production & Sandbox
How Rovenue separates test purchases from real revenue — per-transaction environments, the dashboard toggle, and what stays production-only.
Every purchase Rovenue records carries an environment: PRODUCTION or
SANDBOX. Environment is a property of the transaction, not the user —
the same subscriber can hold a sandbox subscription from testing and a
production one from paying, and each is reported on its own side. Test
traffic never inflates revenue figures, and it never needs deleting.
Where the environment comes from
Each store reports test mode its own way; Rovenue normalizes all of them at ingestion time:
- Apple — the signed transaction's
environment(SandboxvsProduction), verified as part of the StoreKit JWS chain. - Google Play —
testPurchaseon product purchases and the voided / test flags on subscription purchases. Promo-code and rewarded-ad acquisitions stayPRODUCTION(real users, not license tests) but book $0 revenue — no money moved, so the list price must not land as revenue. - Stripe — the event's
livemode, matched against the connected account's own mode. A test event arriving on a live connection (or vice versa) is acknowledged but not processed (mode_mismatch), so a misconfigured endpoint can never pollute either side.
Rows written before environment recording shipped read as production, including historical Apple sandbox rows. This is accepted and stable — there is no backfill, so old test traffic stays where it always was.
Sandbox still grants access
A sandbox purchase is a fully processed purchase: it creates the subscription, writes revenue rows, and grants entitlements exactly like production. Your app unlocks for test buyers the same way it does for paying ones. The only difference is where the numbers show up.
Reading one environment: ?env=
Analytics defaults to production. Append ?env=sandbox to any scoped
read — MRR, revenue summary, LTV, charts, transactions, subscriptions,
credits, cohorts, retention — to see the sandbox side instead:
GET /dashboard/projects/:id/metrics/revenue?env=sandbox # cash collected
GET /dashboard/projects/:id/metrics/mrr?env=sandbox # MRR, from paid terms
GET /dashboard/projects/:id/subscriptions?scope=all&env=sandboxThe dashboard's topbar toggle sends ?env= with every request, so
flipping it switches the whole page's data at once. The toggle is
persisted per project.
What stays production-only
A few surfaces deliberately take no env parameter:
- Experiments and placements — exposures carry no environment, so a sandbox revenue slice would divide by a production denominator.
- LTV prediction, leaderboards, and digest emails — forecasts and rankings over real business only.
- Subscriber lists and engagement — user counts, not revenue.
- Billing usage (MTR) — you are billed on production revenue.
The metrics CSV export follows the same ?env= you pass it.