Sandbox testing and release readiness
Exercise purchase, renewal, refund, restore, authentication, and delivery flows.
Download this chapterOn this page
Test the full path from storefront evidence to protected application behavior. The dashboard's setup checkmarks and a successful credential upload are useful checkpoints, but neither proves the complete integration.
Establish a controlled test environment
Use a verified test account, a dedicated staging app/project, the staging API URL, staging app keys, and store-backed sandbox/test purchases. Verify bundle/package/app IDs and environment filters before creating evidence.
Use supported store testers and storefront builds. A local Xcode StoreKit fixture or a mocked Google purchase object is useful for client UI tests but is not a substitute for server-verifiable store evidence. The core has no runtime store-verification bypass.
Prepare a test product, access level, mapping, and current product set. Your backend must authenticate a real application user and mint a customer token for that user. Use a public HTTPS test receiver if verifying outbound webhooks.
End-to-end acceptance matrix
| Scenario | Expected evidence | Expected application behavior |
|---|---|---|
| First paid subscription | Verified transaction, customer binding, mapped active access | Feature unlocks after verification |
| Free trial | Trial state and expiry; no fabricated paid revenue | Access follows configured store grant |
| Renewal | Updated/next authoritative period and corresponding history | Access continues without a duplicate account |
| Auto-renewal cancelled | Cancellation intent but remaining valid paid period | Access remains until verified expiry |
| Expiry | Subscriber read evaluates expiry as inactive | Feature locks if no other active grant remains |
| Full refund/revocation | Store refund evidence and affected grant removal | Other valid grants still contribute |
| One-time product | Correct explicit product type and completion policy | Permanent/consumable behavior matches your product policy |
| Pending/cancelled purchase | No false paid receipt acceptance/completion | UI stays pending/cancelled, without premium fallback |
| Duplicate submission | Deduplicated receipt success, no duplicate sale | Completion can recover safely |
| Timeout after possible commit | Retry the same evidence | No second fabricated purchase |
| Restore to intended account | Verified purchase ownership behavior | Correct target user's access; no implicit full identity merge |
| Account switch | New token subject and cleared old UI cache | No previous user's access leaks into the new session |
| Expired customer token | One forced refresh, then success or clear failure | No server-secret fallback in the app |
| Bad app/key/subject | Authentication or validation rejection before store effects | Clear recoverable error |
| Receiver returns 5xx | Ordered retry record | Durable receiver dedupe prevents repeated side effects |
| Receiver returns 410 | Dead letter and disabled endpoint | Operator fixes/re-enables intentionally |
| Secret rotation | Overlap signatures accepted | Receiver remains available during rollout |
Test both stores independently. Google one-time purchases and subscriptions must use different API product types. For a cross-store access union, expire/refund one grant while keeping another active and verify the final access level remains correct.
Trace one purchase all the way through
Record the application user ID, store transaction/token reference in a safe diagnostic context, product ID, app ID, environment, and approximate UTC timestamps. Locate the transaction, its customer, the product mapping, and related event evidence in CherrySub. Confirm the SDK's resulting subscriber map matches the feature you actually unlock.
Do not include raw credentials or full purchase tokens in public bug reports. Use non-secret transaction IDs and redacted logs where sufficient.
Test reporting and exports
Use known purchases in a single currency, refunds with known timestamps, and trial/paid cohorts that have both mature and incomplete periods. Compare the chart's stated attribution rules to metric definitions. Verify custom ranges, previous-period comparisons, empty results, and missing accounting facts.
Save a chart/view, reopen it, and confirm the app and filters. Export aggregates separately from raw normalized history. Check requester privacy, email delivery, link expiry, and oversized-job failure.
Developer verification commands
From a source checkout, core checks include go test -race ./..., go vet ./..., formatting, static analysis, and vulnerability scanning. PostgreSQL integration tests require an explicit disposable TEST_DATABASE_URL; do not point them at a live database.
SDK checks are available through make sdk-test or the per-language targets. The web repository uses npm run build and Playwright tests. The CLI can validate a setup plan with --dry-run; real account provisioning must be tested separately by an authorized store operator.
Before a production rollout
Confirm a production deployment has its own secrets, database/recovery design, store endpoints, monitoring, and tested rollback. The current public preview is staging; the recorded production topology is a plan, not a live service guarantee. Registry distribution, Google OAuth setup, notification wiring, and known reporting boundaries are described in release status.