In-app purchase testing trips people up because there are three places to do it, and they overlap. A local StoreKit file in Xcode, the Sandbox, and TestFlight all let you buy without being charged, but they differ in which account they use, where the products come from, and whether you can reset a purchase. Sorting that out is the difference between confident testing and a surprise rejection. Here is how the three compare and when to use each.
Short answer
There are three environments. StoreKit Testing in Xcode uses a local configuration file with no network, for fast logic testing. The Sandbox uses Apple's servers with a dedicated Sandbox Apple Account and your real App Store Connect products. TestFlight also uses the sandbox backend, but with the tester's real Apple ID, and purchases there cannot be cleared. All three are free, and subscriptions renew at an accelerated rate. Use the local file early for logic, the Sandbox to test your real products, and TestFlight before release to confirm the flow end to end.
What you should know
- Three environments, not one: local StoreKit config, Sandbox, and TestFlight each behave differently.
- TestFlight uses the sandbox backend: but with the tester's real Apple ID, not a sandbox account.
- All are free: no real charges in any of the three testing environments.
- TestFlight purchases cannot be cleared: unlike the Sandbox, where you can reset purchase history.
- Subscriptions renew fast: testing accelerates renewals to minutes instead of months.
What are the three in-app purchase testing environments?
Each suits a different stage. StoreKit Testing in Xcode runs against a local configuration file you define, with no network and no Apple servers, so you can test the purchase flow before you even create products in App Store Connect. The Sandbox runs against Apple's real sandbox servers using a dedicated Sandbox Apple Account, and it pulls your actual App Store Connect products, so it tests your real configuration. TestFlight uses the same sandbox backend, but the tester buys with their real Apple ID. The table sorts them.
| Environment | Account used | Backend | Products from | Reset purchases? |
|---|---|---|---|---|
| StoreKit config in Xcode | None, local only | Local, no network | A local StoreKit file you define | Yes, in Xcode |
| Sandbox | A Sandbox Apple Account | Apple sandbox servers | App Store Connect | Yes, in device settings |
| TestFlight | The tester's real Apple ID | Apple sandbox servers | App Store Connect | No |
How is TestFlight different from the Sandbox?
Mainly in the account and in what you can undo. Both use Apple's sandbox backend and neither charges real money, but a Sandbox test signs in with a dedicated Sandbox Apple Account you create in App Store Connect, while a TestFlight tester buys with their normal Apple ID, the one in their Media and Purchases settings. The other key difference is that purchases made through a TestFlight build cannot be cleared, whereas the Sandbox lets you reset purchase history from device settings. That makes the Sandbox better for repeated test runs, and TestFlight better as a final, production-like check.
When should you use each one?
In order, as the product matures. Use StoreKit Testing in Xcode early, while you are building the purchase logic, because it is fast, local, and needs no accounts. Move to the Sandbox once your products exist in App Store Connect, to confirm the real product identifiers, prices, and the receipt flow against Apple's servers with a sandbox account you can reset between runs. Then use TestFlight before release, to confirm the whole experience with real testers on the production-like sandbox backend. Each step is closer to what a buyer, and a reviewer, will actually hit. A common workflow is to do most of the iteration in the local StoreKit file, where there are no accounts and no waiting, then validate once against the Sandbox before inviting TestFlight testers, so you are not debugging a product-configuration problem with real testers watching.
What about subscription renewals during testing?
They run on an accelerated clock, which is intentional. So you do not wait a month to see a renewal, the testing environments shorten subscription periods dramatically, so a monthly subscription renews in minutes and a yearly one in roughly an hour, at the default sandbox rate that TestFlight also uses. This lets you watch several renewal cycles, and a few renewals end automatically, in a single session. Plan your tests around that: a subscription you bought a few minutes ago may already have renewed several times, which is the expected behavior, not a bug. The accelerated clock also compresses free trials and introductory offers, so a three-day trial may end in a few minutes of testing, which is exactly what you want when you are verifying that your app handles the transition from trial to paid correctly.
What to watch out for
The first surprise is that TestFlight purchases cannot be reset, so if you need to test the first-time buy flow repeatedly, use the Sandbox or a local StoreKit file instead. The second is that a product has to be in the Ready to Submit state to appear for a TestFlight tester, so a missing product usually means a configuration gap, not a code bug. Testing thoroughly across these environments is also how you avoid an in-app purchase rejection under Guideline 3.1.1, since a reviewer tests the same sandbox flow. If you also wired a third-party payment processor, a pre-submission scan such as PTKD.com (https://ptkd.com) reads the compiled IPA against OWASP MASVS for a hardcoded payment key, which is a separate, binary-level check from the purchase testing itself.
What to take away
- There are three in-app purchase testing environments: a local StoreKit file, the Sandbox, and TestFlight, and all three are free.
- TestFlight uses the sandbox backend with the tester's real Apple ID, and its purchases cannot be cleared, unlike the Sandbox.
- Use the local file for logic, the Sandbox to test real products with a resettable account, and TestFlight before release.
- Expect accelerated subscription renewals, and test thoroughly so the same sandbox flow does not fail when a reviewer runs it under Guideline 3.1.1.



