You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

付费iOS应用服务器端服务的收据校验与防重放攻击问询

iOS Paid App Receipt Validation & Replay Attack Prevention

Hey there! Let's walk through how to validate user validity with your ProductionSandbox receipt and block replay attacks, since you're working with a paid iOS app (no in-app purchases, just upfront payment).

Validating User Effectiveness

First, let's break down how to confirm the receipt is legitimate for your app:

  • Send receipts to the correct Apple endpoint: For ProductionSandbox receipts, you must send validation requests to https://sandbox.itunes.apple.com/verifyReceipt (production uses https://buy.itunes.apple.com/verifyReceipt). Sending a sandbox receipt to the production endpoint will trigger a 21007 error, so double-check this.
  • Verify core app identifiers: Even though fields like adam_id and app_item_id show 0 in sandbox receipts (this is normal for testing!), confirm the bundle_id matches your app's exact bundle ID (e.g., com.example.myapp) and application_version aligns with your app's current version. This ensures the receipt was generated for your app specifically.
  • Check the receipt_type: For sandbox testing, this should be ProductionSandbox; in production, it'll be Production. This helps you confirm you're handling the right environment.
  • Validate the Apple response status: After sending the receipt, Apple returns a status field. A value of 0 means the receipt is valid. Other codes indicate specific issues:
    • 21002: Malformed receipt data
    • 21003: Receipt can't be authenticated
    • 21007: Sandbox receipt sent to production endpoint (switch to the sandbox URL!)
  • Confirm purchase timestamps: Check receipt_creation_date and original_purchase_date to ensure the purchase is a valid, non-expired transaction (for paid apps, this is a one-time purchase, so these timestamps just confirm the transaction occurred).

Preventing Replay Attacks

Replay attacks happen when an attacker reuses a valid receipt to access your service multiple times. Here's how to stop them:

  • Track unique transaction IDs: Every valid receipt (even sandbox ones) has an original_transaction_id (found in the in_app array of Apple's validation response, or in the main receipt fields for paid app purchases). This ID is unique to each user's original purchase and won't repeat.
  • Store verified IDs in your database: When you successfully validate a receipt, save the original_transaction_id along with the receipt_type (to separate sandbox/production records) in your server's database. Mark it as "already verified".
  • Check for existing IDs before validation: Every time you receive a new receipt validation request, first query your database for the original_transaction_id. If it exists, reject the request—this means the receipt has already been used. If it doesn't exist, proceed with validation, then store the ID once it passes.
  • Optional: Add device context (carefully): While not as reliable as transaction IDs, you can optionally pair the transaction ID with a user's device identifier (like the app's vendor ID) for extra security. Just note that device identifiers can change if the user reinstalls the app, so don't rely on this alone.

Key Notes

  • Never validate receipts client-side: Client-side code can be tampered with, so all validation must happen on your server.
  • Handle retries gracefully: Apple's verification service might return 5xx errors temporarily. Implement a retry mechanism with exponential backoff to avoid being throttled.
  • Sandbox testing quirks: Sandbox receipts often have placeholder values (like 0 for adam_id)—this is expected and doesn't mean the receipt is invalid.

内容的提问来源于stack exchange,提问作者Dan Fabulich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:21:36