Environments
Every transaction, subscription and event has an environment. Your backend decides what each one is worth.
| Environment | Comes from | Treat it as |
|---|---|---|
production |
Real purchases in the App Store, Google Play, Stripe live mode, real ad networks | Revenue |
sandbox |
App Store sandbox and TestFlight, Google test purchases (license testers), Stripe test mode (sk_test_ keys) |
Not revenue. App Review uses the sandbox, so do not reject it outright |
test |
The Kasskeep test store and test ads | Not revenue. Never grant real value in production |
How each channel decides
Section titled “How each channel decides”- Apple: from the signed transaction. With
apple_environmentset toproduction(the default) an app accepts both production and sandbox transactions and stores them separately. Withsandboxit accepts only sandbox. - Google: purchases with
testPurchase(subscriptions) ortestPurchaseContext(one-time products) are recorded assandbox. - Stripe: from the secret key prefix.
sk_test_meanssandbox,sk_live_meansproduction. A webhook whoselivemodedoes not match the key is rejected with400 livemode_mismatch. Use two Kasskeep apps for test and live keys. - Test store and test ads: always
test, withplatform: "test".
Filtering
Section titled “Filtering”GET /v1/customers/:app_user_id?environment=production returns only production records. Without the parameter every environment is returned and each record carries its own environment field.
Transactions are unique per environment, so a sandbox purchase can never overwrite a production one.