Different transaction IDs for the same purchase between SKPaymentTransaction and receipt latest_receipt_info

Hello,

I am investigating a case where two different transaction IDs appear to refer to the same purchase, and I would like clarification on whether this behavior is expected.

Additional context

  • StoreKit version: StoreKit 1 (SKPaymentTransaction)
  • Environment: Production
  • Product type: Auto-renewable subscription

Transaction sources

The values are obtained from the following APIs:

  • transaction_id from SKPaymentTransaction

https://developer.apple.com/documentation/storekit/skpaymentqueue

  • receipt_data from the App Store receipt

https://developer.apple.com/documentation/foundation/bundle/appstorereceipturl

Observed behavior

  1. After an In-App Purchase completes, the app receives:
    • a transaction_id from SKPaymentTransaction
    • the corresponding receipt_data for the purchase
  2. When inspecting the receipt, the transaction_id inside latest_receipt_info differs from the transaction_id received directly from the purchase transaction.

For clarity:

  • A = transaction_id received from the purchase flow (SKPaymentTransaction)
  • A' = transaction_id found in receipt_data.latest_receipt_info

The two values are different, but they differ only by 1.

Additional observation

  • The original_transaction_id for A and A' is identical, which suggests that both transaction IDs belong to the same subscription purchase chain.

Pattern observation on the ID difference

We have observed that the difference between A and A' is consistently exactly 1 (i.e., A' = A + 1) across multiple transactions, not just a single case. This appears to be a reproducible pattern rather than a coincidence. This observation raises an additional question (Question 6 below).

API verification

When calling: GET /inApps/v1/transactions/{transactionId}

Both A and A' return what appears to be the same purchase record. The response data is effectively identical except for the transactionId field.

However, when calling: GET /inApps/v2/history/{transactionId}

  • A does not appear in the transaction history
  • only A' appears in the history response

Questions

  1. If A does not appear in transaction history, where does this transaction ID originate from?
  2. Why does Get Transaction Info (/inApps/v1/transactions/{transactionId}) return a valid response for A even though it is not present in the transaction history?
  3. Why do A and A' both resolve to what appears to be the same purchase?
  4. In this situation, which transaction ID should be treated as the canonical transaction ID for server-side validation?
  5. Is this difference related to how StoreKit 1 (SKPaymentTransaction) and the App Store Server API represent transactions?
  6. Is the consistent off-by-one difference between the transaction_id from SKPaymentTransaction and the one recorded in latest_receipt_info an intentional behavior of StoreKit 1's internal transaction ID assignment?

Specifically, we are wondering whether StoreKit 1 applies some form of internal offset when delivering the transaction ID to the client, while the App Store server records a different (adjacent) ID in the receipt. If so, is this documented anywhere?

Note

We are currently in the process of migrating to StoreKit 2, but this behavior was observed while investigating our existing StoreKit 1 implementation. Any clarification would help us better understand the correct transaction model during the migration.

Different transaction IDs for the same purchase between SKPaymentTransaction and receipt latest_receipt_info
 
 
Q