iOS自动续期订阅:如何识别购买用户?
Got it, let’s break down how to solve this—this is one of the most common hurdles when setting up Apple’s subscription webhooks, so you’re definitely not alone here. The core issue is that Apple’s server-to-server (S2S) callback doesn’t directly send your internal user ID, but there are reliable ways to bridge that gap:
1. Bind original_transaction_id to Your User ID on First Purchase
Every auto-renewable subscription has a unique original_transaction_id that stays consistent across all renewals, restores, and even plan changes. Here’s how to use it:
- When a user completes their first purchase (or restores a subscription), your app should send the full iTunes receipt to your backend.
- Your server then verifies this receipt with Apple’s verification endpoint (sandbox or production, depending on the environment).
- Extract the
original_transaction_idfrom the verified receipt response, and store it in your database linked to the user’s internal ID. - When Apple sends a S2S callback, the payload will include this same
original_transaction_id—you can use it to look up the associated user instantly.
2. Use the applicationUsername Field (Direct User Link)
Apple lets you attach a custom identifier to the payment request from your app, which gets embedded in the receipt:
- In your iOS app, when creating a
SKMutablePaymentobject, set theapplicationUsernameproperty to your internal user ID (you can encrypt it if needed for security):let product = // Your SKProduct for the subscription let payment = SKMutablePayment(product: product) payment.applicationUsername = "user_12345" // Replace with your actual user ID SKPaymentQueue.default().add(payment) - When you verify the receipt (either from the app’s initial submission or the callback’s
latest_receipt), the receipt data will include anapplication_usernamefield with the value you set. This lets you directly map the callback to the user without relying onoriginal_transaction_id(though combining both adds helpful redundancy).
3. Parse the latest_receipt in the Callback
If you miss the initial binding opportunity, the S2S callback still includes a latest_receipt field (base64-encoded). You can send this receipt to Apple’s verification endpoint to get the full transaction details, including:
original_transaction_id(to match your pre-stored user link)application_username(if you set it in the app)- Other transaction metadata like
transaction_idorpurchase_date
Key Notes to Avoid Headaches
- Idempotency: Apple retries callbacks if your server returns an error, so make sure your backend handles duplicate callbacks without creating duplicate records (use the
notification_idfrom the callback payload as a unique key). - Environment Matching: Always use the correct verification endpoint—sandbox receipts fail on production and vice versa.
- Receipt Validation: Never trust unvalidated receipt data, whether from the app or the callback. Always verify with Apple first to prevent fraud.
内容的提问来源于stack exchange,提问作者dashman

