Unity IAP 5.0.2 (iOS Sandbox) — Same receipt returned for all purchases after the first one

Unity IAP 5.0.2 receipts for Apple purchases do not refresh in the same way as IAP 4.13.0 because IAP 5.x uses Apple’s StoreKit 2, which fundamentally changes how transaction data is handled. Instead of a single, monolithic receipt file that gets updated (StoreKit 1 behavior in IAP 4.x), StoreKit 2 provides a unique JSON Web Signature (JWS) representation for each individual transaction.

Details:

  • IAP 4.x (StoreKit 1) Receipt Refresh: In older versions like IAP 4.13.0, which relied on Apple’s StoreKit 1, there was a single, large receipt file containing all transactions. This receipt could be “refreshed” to get the latest transaction information from Apple.
  • IAP 5.x (StoreKit 2) JWS Representation: With IAP 5.0.2, Unity has transitioned to StoreKit 2. This new system uses a more modern and flexible approach based on cryptographically signed transactions in JWS format. Each transaction has its own jwsRepresentation, which is a unique token. This eliminates the need for a manual “receipt refresh” as was required with StoreKit 1, because the receipt is no longer automatically updated in the same way

Performing Receipt Validation in IAP 5.0.2:

While StoreKit 2 provides a signed jwsRepresentation that guarantees authenticity and integrity, Unity IAP 5.0.2 does not automatically perform local validation of this signature or its contents. You are responsible for implementing the validation logic.

  1. Automatic StoreKit 2 Signature Verification:
  • Apple’s StoreKit 2 SDK performs an initial verification that the signature on the jwsRepresentation is genuine and originated from Apple.
  • If this signature verification fails, the OnPurchaseFailed callback will be triggered with PurchaseFailureReason.ValidationFailure.
  • If OnPurchasePending is called, you can be confident that the Apple receipt’s signature is genuine.
  1. Developer-Implemented Validation:
  • Local Validation (Less Secure): You can perform local validation by parsing the jwsRepresentation (available via OrderInfo.Apple.jwsRepresentation) to check its header and payload. This involves decoding the JWS components (header, payload, signature) and verifying details like the bundle ID and transaction ID.
    • Note: Local validation is less secure as client-side code can be tampered with.
  • Remote (Server-Side) Validation (Recommended): This is the most robust method. Your application sends the jwsRepresentation to a secure backend server. The server then communicates with Apple’s verification services to confirm the receipt’s authenticity before granting content.
    • Unity IAP does not provide a built-in remote validation service.
    • A recommended approach is to use a Cloud Code Module script to perform server validation of the jwsRepresentation with Apple, and then use Cloud Code to instruct Unity Economy to update the player’s currency.