非续订订阅沙箱模式重复购买异常及多用户设备适配问题咨询
Hey there, let’s tackle your non-renewing subscription questions one by one—since you’re in sandbox testing, some of these behaviors are specific to Apple’s test environment, so let’s break it down clearly!
Non-renewing subscriptions are designed to be purchasable multiple times, so that sandbox prompt ("This In-App purchase has already been bought...") is just Apple’s test environment protecting you from accidental duplicate purchases. Here’s how to let users re-subscribe:
- Separate Purchase vs. Restore Flows: Don’t rely on automatic restoration for repeat purchases. Build two distinct actions in your UI: one for "Buy New Subscription" and another for "Restore Purchases". When a user selects "Buy New", directly initiate a new purchase request instead of triggering restoration.
- Reset Sandbox Test Accounts: To test repeat purchases with the same test user, head to App Store Connect → Users and Access → Sandbox Testers, find your test account, and click "Reset Purchase History". This clears their sandbox purchase records, letting you buy the same product again.
- Code Example (Swift):
In production, users will be able to buy the same non-renewing product as long as it’s configured to allow repeat purchases (which is the default)—the sandbox prompt won’t appear here.func startNewPurchase(for product: SKProduct) { let payment = SKPayment(product: product) SKPaymentQueue.default().add(payment) } func restoreExistingPurchases() { SKPaymentQueue.default().restoreCompletedTransactions() }
The key here is to tie subscription state to user accounts, not the device. Non-renewing subscriptions don’t get managed by Apple’s subscription system, so you’ll need to handle this entirely on your backend:
- Sync Subscription State on Login: When a new user logs in, never trust local cached subscription data. Fetch the user’s subscription history directly from your backend—this ensures you’re loading the correct data for the logged-in user, not the previous one on the device.
- Clear Local Cache on User Switch: When a user logs out, wipe any local storage related to their subscriptions (like cached purchase receipts or active subscription status) to prevent cross-user data leaks.
- Bind Restore Actions to the Current User: When a user taps "Restore Purchases", send the restored receipt to your backend. Your backend should validate the receipt and link the subscription to the currently logged-in user’s account—not the device. This way, restoring only pulls in the current user’s past purchases.
- Test with Multiple Sandbox Accounts: Use different sandbox tester accounts to log in and out of your app, verifying that each user’s subscriptions are isolated and don’t overlap.
A quick reminder: Unlike auto-renewable subscriptions, Apple doesn’t track non-renewing subscription status for you. You’ll need to store all purchase details (receipts, expiration dates, user associations) in your backend to make multi-user scenarios work reliably.
内容的提问来源于stack exchange,提问作者Krishna Maru

