Fix: RevenueCat Sandbox Purchases Not Working on iOS

Sandbox purchases failing with RevenueCat usually trace to the sandbox Apple ID, the wrong StoreKit testing environment, or account state. Here are the real causes and concrete fixes.

Understand the Two Testing Environments

Before debugging, be clear about which testing environment you are actually in, because RevenueCat and StoreKit support two very different ones and mixing them up causes most sandbox confusion. The first is Apple's sandbox environment, which uses real StoreKit servers with special sandbox Apple ID accounts you create in App Store Connect; purchases here exercise the true App Store flow without real charges. The second is Xcode's local StoreKit testing, driven by a StoreKit configuration file in your project, which simulates purchases entirely on-device without contacting Apple's servers at all. These behave differently, surface different errors, and require different setup. A purchase that fails in one may work in the other. Many reported sandbox failures are really a developer testing in Xcode's local mode while expecting sandbox behavior, or the reverse. Identify which environment your run is using first, since the correct fix depends entirely on that. The rest of this guide addresses each environment's common failures, but the single most valuable step is to nail down, before anything else, whether the scheme is pointing at a local configuration file or at real StoreKit.

Cause 1: Not Signed Into a Sandbox Apple ID

For true Apple sandbox testing, you must purchase using a dedicated sandbox Apple ID, never your personal or developer Apple ID. Create sandbox testers in App Store Connect under Users and Access, in the Sandbox section, using an email address not already associated with any Apple ID. On the device, the sign-in flow has changed across iOS versions: on recent iOS you sign into the sandbox account through the Settings app, in the App Store or Developer section under a Sandbox Account option, rather than signing out of your main Apple ID. When you attempt a purchase, iOS should present the sandbox account, and the payment sheet typically indicates you are in the sandbox environment. If you are signed into a normal Apple ID, sandbox purchases will fail or behave unexpectedly. Verify you created a sandbox tester, that it is set as the active sandbox account on the device, and that you are actually using it when the purchase sheet appears. A frequent mistake is creating the tester but never selecting it on the device, so the purchase attempt falls back to a production Apple ID and fails.

Cause 2: Testing in the Wrong StoreKit Mode

A frequent cause of confusion is your Xcode scheme's StoreKit Configuration setting silently putting you in local testing instead of sandbox, or the reverse. If your scheme has a StoreKit configuration file selected, purchases run entirely locally against that file and never touch Apple's sandbox, so a sandbox Apple ID is irrelevant and any server-dependent behavior you expect will not occur. If instead you intend to test against Apple's real sandbox, the scheme's StoreKit Configuration must be set to None so StoreKit uses the live environment with your sandbox account. Check this under Product, then Scheme, then Edit Scheme, then Run, then Options. Decide deliberately which environment you want: local StoreKit testing is fast and offline and great for UI iteration, while Apple sandbox exercises the real purchase and receipt-validation path that RevenueCat's backend depends on. Setting this wrong is one of the most common reasons a purchase behaves nothing like you expect during testing, and it is worth confirming this setting at the very start of any sandbox debugging session rather than assuming it is what you last set it to.

Cause 3: RevenueCat and Local StoreKit Testing

There is an important nuance when combining RevenueCat with Xcode's local StoreKit configuration file. Local StoreKit testing simulates transactions on-device without producing the real App Store receipts that RevenueCat's backend normally validates, so entitlement behavior may differ from sandbox or production. RevenueCat does support testing with StoreKit configuration files, but you should confirm your SDK version and setup follow their current guidance, and understand that some server-side lifecycle events will not occur locally. If your goal is to verify that a purchase correctly activates an entitlement through RevenueCat's full pipeline, Apple's sandbox is the more faithful environment because it produces genuine receipts that reach RevenueCat's servers. Use local StoreKit testing for rapid UI and flow iteration, then validate the true entitlement path in sandbox before release. Being explicit about what each environment does and does not exercise prevents the frustrating situation where a purchase appears to succeed but the entitlement never activates because you were testing locally. Treat local testing as a way to iterate on presentation and flow, and treat sandbox as the environment where you certify that the money-to-entitlement path actually works end to end.

Cause 4: Sandbox Account or Agreement State

Sandbox purchases also fail when the underlying account or agreement state is not ready. Even in sandbox, your Paid Applications Agreement must be active in App Store Connect, and your products must be in a state that makes them available; a product still missing metadata may not be purchasable in sandbox. Additionally, a specific sandbox tester account can get into a stuck or exhausted state after repeated testing, for example after many renewal cycles of an accelerated sandbox subscription. If one sandbox account consistently fails, create a fresh sandbox tester and try again, which resolves many mysterious per-account failures quickly. Also confirm the sandbox account's region and the device region are sensible, since regional restrictions can affect availability. Check that the product you are trying to buy is actually mapped correctly in RevenueCat and exists in App Store Connect with the exact identifier. When purchases fail only in sandbox and only for one account, swapping to a new sandbox tester is often the fastest fix before deeper investigation, because sandbox account state is a common and easily overlooked culprit that no amount of code inspection will reveal.

Cause 5: Accelerated Renewals and Timing

Auto-renewable subscriptions behave differently in sandbox: Apple accelerates their duration dramatically, so a one-month subscription might renew every few minutes and only renew a limited number of times before stopping. Developers new to this sometimes interpret the rapid expiration or the eventual stop of renewals as a purchase failure, when it is actually expected sandbox behavior. When testing subscription flows, account for this acceleration in your expectations and in how you read RevenueCat's CustomerInfo, since an entitlement may flip to inactive far sooner than a real month. If you are checking whether a subscription is active, do so promptly after purchasing rather than after a delay that, in sandbox time, may already exceed the accelerated period and expired the subscription. Understanding the accelerated clock prevents a class of false failure reports where a working integration looks broken purely because of sandbox timing. If you need to test long-running subscription behavior more realistically, some scenarios are better validated with StoreKit configuration files, which let you control subscription timing and renewal behavior deliberately for specific test cases.

Cause 6: Network, Environment, and Caching Issues

Finally, transient and environmental issues cause sandbox failures that look worse than they are. Sandbox servers occasionally have degraded periods, and network interruptions on the device can cause a purchase to appear to fail even though it partially processed. If a purchase fails once, retry before concluding there is a defect. Enable RevenueCat debug logging with Purchases.logLevel = .debug and read the exact error the SDK reports, since it often distinguishes a user cancellation, a network error, and a genuine configuration problem, which call for very different responses. Confirm the device actually has connectivity to both Apple and RevenueCat. If entitlements seem stale after a sandbox purchase, the SDK's cache may need a refresh via a fresh customerInfo() call or by observing the CustomerInfo stream. Do not treat a normal user cancellation as an error to fix, since surfacing it as a failure confuses testers and, later, real users. Reading the precise error message is the fastest way to tell a real failure apart from expected sandbox behavior or a simple retriable network hiccup, and it should be your reflex before you start changing configuration.

A Sandbox Debugging Checklist

Work through sandbox failures methodically. First, determine your environment by checking the scheme's StoreKit Configuration setting: a file means local testing, None means real sandbox. Second, if using real sandbox, confirm you created a sandbox tester in App Store Connect and set it as the active sandbox account on the device. Third, verify the Paid Applications Agreement is active and your products are in a sellable state, since even sandbox requires this. Fourth, enable debug logging and read the exact error, separating cancellations and network issues from configuration problems. Fifth, if one sandbox account misbehaves, create a fresh tester. Sixth, remember subscriptions renew on an accelerated clock and stop after a limited number of cycles, which is normal and not a bug. Seventh, retry transient failures and refresh CustomerInfo if entitlements look stale. Following this order, and consulting RevenueCat's sandbox documentation and Apple's StoreKit testing guide, resolves the vast majority of sandbox purchase problems without guesswork. The discipline that saves the most time is simply confirming, first and explicitly, which of the two testing environments you are in before you interpret any error at all.

Frequently Asked Questions

Do I need a special account to test sandbox purchases?

Yes. Create a dedicated sandbox tester in App Store Connect under Users and Access, Sandbox, using an email not tied to any existing Apple ID. On the device, set it as the active sandbox account in Settings. Never test sandbox purchases with your personal or developer Apple ID.

Why does my purchase behave nothing like the real App Store?

You may be in Xcode's local StoreKit testing instead of Apple's sandbox. Check Edit Scheme, Run, Options, StoreKit Configuration. A selected file means local simulation with no real receipts; set it to None to test against Apple's sandbox with a sandbox Apple ID.

Why does my sandbox subscription expire almost immediately?

That is expected. Apple accelerates subscription durations in sandbox, so a monthly subscription may renew every few minutes and stop after a limited number of cycles. Check entitlement status promptly after purchase, and account for the accelerated clock when reading CustomerInfo.

One sandbox account keeps failing. What should I do?

Sandbox accounts can get into a stuck or exhausted state after heavy testing. Create a fresh sandbox tester in App Store Connect and try again. Also confirm the Paid Applications Agreement is active and your products are in a sellable state, since sandbox still requires this.

Do local StoreKit tests exercise RevenueCat's full pipeline?

Not entirely. Local StoreKit testing simulates transactions on-device without the real receipts RevenueCat's backend validates, so some server-side lifecycle behavior does not occur. Use local testing for fast UI iteration, then verify the true entitlement path in Apple's sandbox before release.