Post

Replies

Boosts

Views

Activity

Reply to Questions on App Store Server API behaviors: Production accounts in Sandbox, and Cleared Sandbox data
Based on my research, I have formed the following understanding; is this correct? Regarding Case A (behavior when a purchase is made using a production account connected to Apple's Sandbox environment): ① What kind of account do reviewers use for testing? Reviewers use Apple's internal review devices and dedicated Apple accounts for review purposes. Although the build being reviewed is a "production binary," StoreKit communication within the review environment is forcibly routed to the "Sandbox environment" by Apple's systems. The reviewers' accounts are configured within Apple's internal systems as "special tester accounts" authorized for Sandbox in-app purchase testing. ② Does StoreKit block this on the client side? It is not blocked. While regular users attempting to make a purchase using a production account in a development build would be rejected with a "Not a Sandbox account" error, Apple configures the system so that reviewer accounts successfully authenticate within the review sandbox. When a reviewer taps the purchase button, the purchase confirmation sheet (displaying "[Environment: Sandbox]") appears; authentication succeeds, and a successful purchase completion transaction is issued. Naturally, the reviewer is not actually charged. ③ Backend behavior (Why 4040010 is returned) Purchase transactions completed by the reviewer are recorded only on Apple's "Sandbox server." Consequently, when the backend queries the production App Store Server API using the transactionId sent from the app, it returns a 4040010 (TransactionIdNotFoundError) because the transaction does not exist in the production database. However, if the backend automatically falls back to querying the Sandbox API, it can successfully retrieve a "200 OK" response along with the transaction details (JWS). Case B: Behavior after Sandbox environment data is invalidated (clearing purchase history for pending reviews and testing "Restore Purchases") ① Behavior when "Restore Purchase" is executed within the app If the "Restore Purchase" button (calling AppStore.sync() or SKPaymentQueue.restoreCompletedTransactions()) is pressed immediately after the reviewer has deleted the purchase history from the device: Since no valid purchase history exists on the Apple server, StoreKit returns "0 transactions to restore" (an empty array). Points to note (to avoid app rejection): If the app misinterprets this state—where there are zero items to restore—as a "communication error" or "unknown error" and displays an error alert or enters an infinite loading loop, it becomes a common cause for rejection due to guideline violations (such as Guideline 2.1 or 3.1.1). Instead, the app must display a standard alert indicating that "no restorable purchases were found" and complete the process gracefully. ② Querying the App Store Server API using a previous transactionId If the backend subsequently queries Apple's Sandbox Server API using a transactionId received prior to the history being cleared: Because the record has been purged on Apple's end, the Sandbox API will return a 4040010 (TransactionIdNotFoundError) error. Client-side: Do not implement custom logic on the app side to restrict purchase processing based on whether the account is a production or sandbox account; instead, rely on the standard StoreKit flow. If "Restore Purchases" returns zero results, handle the UI flow normally—treating it as "no valid purchases" rather than an error. Server-side: Requests from reviewers appear to originate from a production build, but the underlying data consists of sandbox transactions. Therefore, having a mechanism in place that automatically falls back to the Sandbox API upon receiving a 4040010 error from the Production API is a prerequisite for passing the review smoothly.
Topic: App & System Services SubTopic: StoreKit Tags:
3w
Reply to Is transactionId unique across Production and Sandbox environments for DB design?
Based on my research, I have arrived at the following conclusion; is my understanding correct? [Regarding potential transactionId collisions between Apple's Production and Sandbox environments] Uniqueness across environments: Global uniqueness across Production and Sandbox environments is not guaranteed. Suitability as a single primary key: Using transactionId alone as a primary key (PK) is not recommended. Recommended schema design: A composite key of (environment, transactionId), or a surrogate key combined with a composite unique constraint. Scope of uniqueness: According to Apple's specifications, transactionId is guaranteed to be unique within each specific environment (Production or Sandbox). However, since the Production and Sandbox environments operate as independent systems, the architectural possibility of the same numeric string being assigned—however rare—cannot be ruled out. Database design best practice: Adopting a composite key: In your table design, include an environment column (Production/Sandbox) and configure a composite primary key (or composite unique index) based on (environment, transactionId). Separating Tables and Databases by Environment: Mixing production data with test or review data in the same tables can lead to errors in sales aggregation, KPI analysis, and user access management. To ensure safety, it is best practice—wherever possible—to logically or physically separate data storage locations for production and sandbox environments, or to design systems that mandate the inclusion of an environment = 'Production' condition in all views and extraction queries.
Topic: App & System Services SubTopic: StoreKit Tags:
3w
Reply to Questions on App Store Server API behaviors: Production accounts in Sandbox, and Cleared Sandbox data
Based on my research, I have formed the following understanding; is this correct? Regarding Case A (behavior when a purchase is made using a production account connected to Apple's Sandbox environment): ① What kind of account do reviewers use for testing? Reviewers use Apple's internal review devices and dedicated Apple accounts for review purposes. Although the build being reviewed is a "production binary," StoreKit communication within the review environment is forcibly routed to the "Sandbox environment" by Apple's systems. The reviewers' accounts are configured within Apple's internal systems as "special tester accounts" authorized for Sandbox in-app purchase testing. ② Does StoreKit block this on the client side? It is not blocked. While regular users attempting to make a purchase using a production account in a development build would be rejected with a "Not a Sandbox account" error, Apple configures the system so that reviewer accounts successfully authenticate within the review sandbox. When a reviewer taps the purchase button, the purchase confirmation sheet (displaying "[Environment: Sandbox]") appears; authentication succeeds, and a successful purchase completion transaction is issued. Naturally, the reviewer is not actually charged. ③ Backend behavior (Why 4040010 is returned) Purchase transactions completed by the reviewer are recorded only on Apple's "Sandbox server." Consequently, when the backend queries the production App Store Server API using the transactionId sent from the app, it returns a 4040010 (TransactionIdNotFoundError) because the transaction does not exist in the production database. However, if the backend automatically falls back to querying the Sandbox API, it can successfully retrieve a "200 OK" response along with the transaction details (JWS). Case B: Behavior after Sandbox environment data is invalidated (clearing purchase history for pending reviews and testing "Restore Purchases") ① Behavior when "Restore Purchase" is executed within the app If the "Restore Purchase" button (calling AppStore.sync() or SKPaymentQueue.restoreCompletedTransactions()) is pressed immediately after the reviewer has deleted the purchase history from the device: Since no valid purchase history exists on the Apple server, StoreKit returns "0 transactions to restore" (an empty array). Points to note (to avoid app rejection): If the app misinterprets this state—where there are zero items to restore—as a "communication error" or "unknown error" and displays an error alert or enters an infinite loading loop, it becomes a common cause for rejection due to guideline violations (such as Guideline 2.1 or 3.1.1). Instead, the app must display a standard alert indicating that "no restorable purchases were found" and complete the process gracefully. ② Querying the App Store Server API using a previous transactionId If the backend subsequently queries Apple's Sandbox Server API using a transactionId received prior to the history being cleared: Because the record has been purged on Apple's end, the Sandbox API will return a 4040010 (TransactionIdNotFoundError) error. Client-side: Do not implement custom logic on the app side to restrict purchase processing based on whether the account is a production or sandbox account; instead, rely on the standard StoreKit flow. If "Restore Purchases" returns zero results, handle the UI flow normally—treating it as "no valid purchases" rather than an error. Server-side: Requests from reviewers appear to originate from a production build, but the underlying data consists of sandbox transactions. Therefore, having a mechanism in place that automatically falls back to the Sandbox API upon receiving a 4040010 error from the Production API is a prerequisite for passing the review smoothly.
Topic: App & System Services SubTopic: StoreKit Tags:
Replies
Boosts
Views
Activity
3w
Reply to Is transactionId unique across Production and Sandbox environments for DB design?
Based on my research, I have arrived at the following conclusion; is my understanding correct? [Regarding potential transactionId collisions between Apple's Production and Sandbox environments] Uniqueness across environments: Global uniqueness across Production and Sandbox environments is not guaranteed. Suitability as a single primary key: Using transactionId alone as a primary key (PK) is not recommended. Recommended schema design: A composite key of (environment, transactionId), or a surrogate key combined with a composite unique constraint. Scope of uniqueness: According to Apple's specifications, transactionId is guaranteed to be unique within each specific environment (Production or Sandbox). However, since the Production and Sandbox environments operate as independent systems, the architectural possibility of the same numeric string being assigned—however rare—cannot be ruled out. Database design best practice: Adopting a composite key: In your table design, include an environment column (Production/Sandbox) and configure a composite primary key (or composite unique index) based on (environment, transactionId). Separating Tables and Databases by Environment: Mixing production data with test or review data in the same tables can lead to errors in sales aggregation, KPI analysis, and user access management. To ensure safety, it is best practice—wherever possible—to logically or physically separate data storage locations for production and sandbox environments, or to design systems that mandate the inclusion of an environment = 'Production' condition in all views and extraction queries.
Topic: App & System Services SubTopic: StoreKit Tags:
Replies
Boosts
Views
Activity
3w