App Store Server API

RSS for tag

Call this REST API from your server to request and provide information about your customers' in-app purchases.

Posts under App Store Server API tag

200 Posts

Post

Replies

Boosts

Views

Activity

Production subscription remains Active after failed payment and no funds deducted
Hello, We are investigating an auto-renewable monthly subscription in the Production environment. Timeline and observed behavior: On June 29, 2026, the user initiated the first subscription purchase. The Apple Account used WeChat Pay as its payment method. The WeChat charge failed because the balance was insufficient, and no funds were deducted from any available payment source. Nevertheless, StoreKit returned a verified transaction, the subscription purchase succeeded in the app, and App Store Connect Sales Analytics reports proceeds for the purchase. We grant entitlement based only on Apple's signed transaction and subscription status, so the user currently has access. As of July 20, 2026, Get All Subscription Statuses from App Store Server API returns: environment: Production status: 1 (Active) expiresDate: 2026-07-29T03:37:11Z autoRenewStatus: 1 no gracePeriodExpiresDate no revocationDate no expirationIntent no billing retry indication Our App Store Server Notifications endpoint has received only: SUBSCRIBED / INITIAL_BUY We have not received DID_FAIL_TO_RENEW, EXPIRED, REFUND, or REVOKE. Questions: Is it expected for Apple to issue a valid production initial-purchase transaction and report proceeds even when the underlying WeChat Pay charge failed and no money was deducted? Could this be an unpaid Apple Account balance or delayed settlement that is invisible to the developer? While the Server API returns status 1, should the developer continue granting entitlement until expiresDate? Is there another authoritative App Store Server API or signed field that indicates the payment has not actually been collected? If renewal or collection later fails, when should we expect DID_FAIL_TO_RENEW or a change to billing retry or expired status? We have intentionally omitted transaction IDs and account identifiers from this public post. I can provide them privately to Apple Support if needed. Thanks
1
0
262
2m
REFUND_REVERSED for auto-renewable subscriptions: is revocationDate cleared, and does auto-renew resume?
We handle App Store Server Notifications V2 for an auto-renewable subscription. When we receive REFUND for the current period, we revoke the customer's access. We now want to reinstate access on REFUND_REVERSED, as the documentation says: "If your app revoked content or services as a result of the related refund, it needs to reinstate them." Before reinstating, our server verifies the transaction in signedTransactionInfo and rejects it if revocationDate is present or expiresDate is in the past. We'd like to confirm a few behaviors so that the reinstatement doesn't get rejected by our own checks: In a REFUND_REVERSED notification, does the signedTransactionInfo still contain revocationDate (and revocationReason), or are they removed? Likewise, after the reversal, does Get Transaction Info / Get All Subscription Statuses return the transaction without revocationDate? An App Store Commerce Engineer explained in thread/757119 that when a customer requests a refund, the subscription's auto-renew status is set to false. Does this apply to every refund path (for example, refunds initiated by Apple or via chargebacks), or only to refunds requested by the customer? After REFUND_REVERSED, does the auto-renew status stay off, or can it be turned back on automatically? If it stays off, is the customer expected to re-enable auto-renew themselves? We have seen reports that REFUND_REVERSED can arrive weeks after REFUND, even when expiresDate has already passed. In that case, is it correct to reinstate access only up to the original expiresDate (i.e. nothing to reinstate if it has already passed)? Thank you.
0
0
2
2h
Questions on App Store Server API behaviors: Production accounts in Sandbox, and Cleared Sandbox data
Hello, I would like to clarify the exact technical behavior of the App Store Server API (V2) and StoreKit under the following two specific scenarios: Case A (Production Account on Sandbox Endpoint): If a user with a production Apple Account attempts to purchase through a build pointing to the Apple Sandbox environment (or Sandbox API), how does the Apple server handle this transaction and its data lifecycle? (Does StoreKit block this at the client-side, or does the API return a specific error code?) Case B (Restoring Cleared Sandbox Data): If a Sandbox tester's purchase history is cleared/deleted on the Apple server, and the app subsequently requests a "Restore Purchase" or queries the App Store Server API using a previously valid transactionID from that account, what specific error code (such as 4040010 TransactionNotFound) or empty response does the Apple server return? I would highly appreciate your confirmation or any technical insights on these behaviors. Thank you!
0
0
178
1d
Best practices for backend server transition timing to Production App Store Server API
Hello, I would like to clarify the best practices and timing for our backend server to transition its main connection to the production App Store Server API. Currently, we are considering the following approach: We plan to switch our backend’s primary API endpoint from Sandbox to Production once our app passes the App Store review and its status changes to "Ready for Sale." Could you please confirm if this timing is standard and correct? Additionally, to handle App Store reviews (which run in the Sandbox environment) and TestFlight tests seamlessly without manual configuration changes, we are planning to implement an automatic fallback mechanism: Our backend always requests the Production App Store Server API first. If it returns a "TransactionNotFound" (e.g., 4040010) error, the backend automatically retries the request using the Sandbox API. Is this automatic fallback from Production to Sandbox considered a safe and recommended practice by Apple, especially for App Store reviews and post-release testing? Any advice or insights on backend transition timing and fallback strategies would be highly appreciated. Thank you!
0
0
48
1d
Is dynamic fallback to Sandbox API correct when receiving error 4040010 (TransactionIdNotFoundError) during App Review?
Hi, During the App Review process, a test purchase was made using what appeared to be a production Apple account. When our app server sent this transactionId to the Production App Store Server API, it returned the error code 4040010 (TransactionIdNotFoundError). To handle this gracefully and prevent review rejections, we are considering implementing a dynamic fallback mechanism on our app server. Specifically, when the Production API returns 4040010, the server will automatically retry the request using the Sandbox App Store Server API URL. Could you please clarify the following points regarding this design? Is it expected behavior for an App Review purchase to return 4040010 on the Production API, and can it be successfully verified by routing it to the Sandbox API? Is this dynamic fallback logic (Production API ➔ if 4040010 ➔ Sandbox API) a recommended and officially supported best practice for handling App Review and TestFlight transactions? Any confirmation or advice from Apple engineers or the community would be greatly appreciated.Thank you.
0
0
18
1d
Is transactionId unique across Production and Sandbox environments for DB design?
Hi, I am designing a database schema to store App Store transaction data for our backend system, and I have a question regarding the uniqueness of transactionId. According to the documentation (apple.com), transactionId is a unique identifier for a transaction. However, it is not explicitly clear whether this uniqueness is guaranteed across different environments.Could you please clarify the following points? Is transactionId guaranteed to be unique across both the Production and Sandbox environments? (i.e., Is there any possibility that the exact same transactionId is generated in both environments?) For database design, is it safe to use transactionId alone as a Primary Key? Or is it strongly recommended to use a composite key consisting of both environment and transactionId? Any insights or best practices from Apple engineers or the community would be highly appreciated.Thank you.
0
0
13
1d
Sandbox test notification returns 4040007 after notification URL is saved and verified
For our app, we saved a sandbox App Store Server Notifications URL with V2 enabled and independently read the configuration back. A subsequent test-notification request returned HTTP 404 / 4040007. An authenticated sandbox notification-history request shortly beforehand returned HTTP 200. We restored the original settings after collecting diagnostics. The recorded failure is covered by Feedback Assistant report FB24885397. What could explain this discrepancy, and what additional diagnostics would help Apple investigate?
0
0
77
1d
ASSN V2: purchaseDate ~8 hours later than signedDate inside the same Apple-signed JWS (FB24820430)
Following the guidance in the locked thread "Reporting your App Store Server Notifications issue" (https://developer.apple.com/forums/thread/774053) and a DTS support request on the same topic, I am posting this issue with the Feedback Assistant ID requested there: FB24820430. Summary: This is a content anomaly in Apple-signed App Store Server payloads, not a notification delivery problem — our server receives and verifies every notification; the defect is in the field values themselves. For a stable subset of subscription families, purchaseDate in JWSTransactionDecodedPayload is consistently ~8 hours later than the signedDate of the very same JWS — a purchase recorded as happening after the signed document reporting it existed. Reproducible field comparison inside one and the same Apple-signed JWS: Field relation Affected transactions Unaffected (control) transactions purchaseDate − signedDate +7h54m … +7h59m (never ≤ 0) ≈ 0 (seconds) Webhook arrival at our server ≈ signedDate (seconds to minutes), never ≈ purchaseDate ≈ signedDate originalPurchaseDate carries the same ~8h shift (renewals inherit it) no shift expiresDate − purchaseDate exactly one subscription period exactly one subscription period expiresDate − signedDate period + ~8h period All fields are documented as "UNIX time, in milliseconds". Our iOS client passes StoreKit 2 Transaction.purchaseDate through unmodified; our backend stores the epoch-millisecond values verbatim as UTC with no timezone conversion. These payloads are generated and signed by Apple infrastructure. Scale (production, as of 2026-09-14): ≈710 subscription families (distinct originalTransactionId lineages), ≈2,700 transactions — roughly three quarters of all families with renewals. Affected purchases span early March 2026 to present, ~30–45 new affected transactions per day. Observed across US, PH, ID and GB storefronts and across app build versions. Sandbox is unaffected. Our interpretation (inference, not confirmed): the offset varies between 7h54m and 7h59m rather than being exactly 8h, consistent with a local wall-clock time in a UTC+8 environment having been encoded as if it were UTC when the original transaction record was created, then inherited by all renewals of that family. Questions for Apple engineers: Is this a known issue in App Store Server data, and is there a reference we can track? What conditions cause a family's purchaseDate to be recorded this way (storefronts/regions, purchase channels, offer types, original-receipt formats)? When purchaseDate and signedDate disagree, which field is authoritative for "when the customer was charged"? The public documentation defines each field only as "UNIX time, in milliseconds" and does not define its relationship. Is remediation planned on Apple's side, or what is the recommended way to obtain the true charge time? Evidence: A focused sample project (a ~85-line Swift tool plus four unmodified signedTransactionInfo JWS samples — three affected families and one unaffected control, each carrying Apple's x5c certificate chain) is included in Feedback Assistant report FB24820430, together with the raw HTTP notification bodies for an affected and a control notification, exactly as delivered to our endpoint. Thank you.
1
0
166
6d
Request a Test Notification returns 401 with an active In-App Purchase key and Apple Java Server Library
Hello Apple Developer Forums, We are unable to authorize the Production App Store Server API Request a Test Notification endpoint. Environment: Production API: Request a Test Notification Library: Apple App Store Server Library for Java 5.2.0 Client: AppStoreServerAPIClient Result: HTTP 401 Unauthorized before a testNotificationToken is returned. We have verified the following: The key is an active In-App Purchase key created in App Store Connect under Users and Access > Integrations > In-App Purchase. The production server uses the matching .p8 private key, Key ID, Issuer ID, and bundle ID. The bundle ID is com.ansio.serviceproof.ios. The server clock is NTP-synchronized. The request uses the official Apple Java Server Library rather than a manually generated JWT. We rotated the production In-App Purchase key once and received the same 401 result. The notification URL is configured for the Production environment, uses HTTPS, and is reachable. Sandbox uses an independent key and notification configuration. We intentionally do not include the private key, JWT, Key ID, or Issuer ID publicly. According to the documentation, HTTP 401 means the JWT is invalid. Since the official library creates the JWT and the active In-App Purchase key configuration has been verified, could Apple clarify: Is any additional App Store Connect role, agreement, team activation, or entitlement required for a Production In-App Purchase key to authorize App Store Server API requests? Is there a known propagation or authorization issue that can cause a newly created active In-App Purchase key to return 401? What non-sensitive diagnostic details can help distinguish a JWT construction issue from a team-level authorization issue? Thank you.
0
0
61
1w
All auto-renewable subscriptions returning expirationIntent = 5 after resolving an agreement issue (StoreKit 1 and StoreKit 2)
Hello, We are currently seeing errors when validating receipts for every auto-renewable subscription purchased through both StoreKit 1 and StoreKit 2. Details below. Case 1 — StoreKit 1 Calling https://buy.itunes.apple.com/verifyReceipt with the subscription receipt returns: "status": 21006, "expiration_intent": "5" Case 2 — StoreKit 2 Calling https://api.storekit.itunes.apple.com/inApps/v1/subscriptions and reading the most recent transaction (LastTransactionsItem) returns status 3. Within JWSRenewalInfoDecodedPayload: autoRenewStatus = 1, expirationIntent = 5 Timeline We believe renewals stopped processing for essentially all auto-renewing subscribers of our app as of 2026-09-18 09:30 KST (UTC+9). After resolving an agreement/licensing issue on our side, new purchases and some receipt validations recovered as of 2026-09-21 11:49 KST. However, most existing receipts still return expirationIntent = 5 when we query receipt validation or subscription status. Questions Is any action required on our side — a server-side change, a configuration change in App Store Connect, or a further review of our agreements? Now that the agreement issue is resolved, when are the renewals that were left pending during the outage expected to be processed? Any guidance would be appreciated. Thank you.
0
0
89
1w
App Store Server API mass renewal date extension remains incomplete for 11 days
Hello, I submitted a mass subscription renewal date extension request using the App Store Server API on September 9, 2026. The request was accepted successfully. However, when I check the request using getStatusOfSubscriptionRenewalDateExtensions, the status continues to return: complete: false As of September 20, the request has remained incomplete for 11 days. Request details: Extension: 1 day Reason: temporary service interruption Environment: Production The documentation states that a mass renewal date extension may take hours or even days to complete, but I have not been able to find guidance for a request that remains incomplete this long. Only three subscribers were affected by the service interruption, and I have their originalTransactionId values. I am considering using the individual subscription renewal date extension API instead. My questions are: Is it expected for a mass renewal date extension request to remain complete: false for 11 days? Could this mass request still complete at a later date? Is there any way to cancel or determine whether this mass request is stuck? If I extend the three affected subscriptions individually now, is there a risk that the pending mass request could later complete and extend them a second time? I would like to compensate the affected subscribers as soon as possible while avoiding duplicate extensions. Thank you for any guidance.
0
0
281
1w
In-App Purchase key returns 401 (4010000) on Advanced Commerce API but 200/404 on App Store Server API
Environment: Sandbox Bundle ID: com.fosssocial.app Key ID: L7DZYHGM62 Issuer ID: cf1f7bc7-452f-4bb8-a925-31ca29175fac Summary Our In-App Purchase key is accepted by the App Store Server API but rejected by the Advanced Commerce API, using the exact same bearer token. This appears to be an authorization grant that was never applied to the key, rather than a signing or request-format problem on our side. Reproduction — one token, two API families GET /inApps/v1/subscriptions/1 -> 404, errorCode 4040010 (token ACCEPTED, resource simply not found) POST /advancedCommerce/v1/subscription/changeMetadata/1 -> 401, errorCode 4010000 (token REJECTED) Same JWT, same key, issued seconds apart. A 401 on one family and a 404 on the other isolates this to key authorization. On-device symptom A signed SubscriptionCreateRequest passed to StoreKit as advancedCommerceData fails with StoreKitError.unknown / "Unable to Complete Request". No payment sheet appears and no InvalidRequestError is returned, so there is no field-level error to act on. What we have already verified JWS header: alg ES256, kid, typ JWT Claims: iss, iat, aud "advanced-commerce-api", bid, nonce, request No exp claim (per Apple's documentation) The request claim uses standard padded base64, not base64url Key ID and .p8 file confirmed to be a matching pair Key regenerated after receiving the Advanced Commerce access-granted email; the 401 is unchanged AdvancedCommerceProduct(id:) resolves successfully on device, which confirms the PRODUCT has Advanced Commerce access Question Does the In-App Purchase key require a separate authorization for the Advanced Commerce API beyond the product-level access we were granted? If so, how is that applied to an existing key?
0
0
212
3w
Cancel subscription not working in TestFlight
Hi, I have deployed my app on Test Flight, I have two subscriptions, monthly and yearly. User can have one of them at a time and upgrade, downgrade to the other. Upgrade, downgrade, cancel from the Apple Settings worked fine in the sandbox environment when testing locally. Now when I have deployed the app on TestFlight, I was able to purchase the subscription successfully from my app. Now when I want to cancel my subscription from the Apple Settings it gives me the following error after confirming cancellation, 'Your request is temporarily unable to be processed. Please try again later.' Also the other subscription offer (yearly) is also not shown to which I could upgrade, even though in the sandbox I was able to upgrade downgrade from the settings. Another thing I have noticed is that the app Icon or name is not shown anywhere in settings with the subscription. Instead of app icon only empty square is shown. Even though app icon shows fine everywhere else. Can someone please help me figure out this issue?
23
15
5.3k
Aug ’26
App Store Server Notification returns successful purchase while customer's payment remains Pending
App Store Server Notification returns successful purchase while customer's payment remains Pending We have encountered an edge case with a Non-Renewing Subscription and would appreciate clarification on the expected developer behavior. Steps to reproduce User initiates an in-app purchase using a credit card. The purchase succeeds in the app. Our backend receives an App Store Server Notification V2 (ONE_TIME_CHARGE). We successfully verify the signed JWS transaction. The same transaction is also returned by the App Store Server API. Based on the verified transaction, we grant the user's entitlement. However, on the customer's Apple account: The purchase is shown as Pending in Purchase History / Report a Problem. The customer reports that their credit card has not yet been charged. Question From a developer's perspective, should entitlement be granted immediately after receiving a valid App Store Server Notification and successfully verifying the transaction, even if the customer's purchase is still shown as Pending? Is there any App Store Server API or transaction field that indicates the payment has not yet been settled, allowing developers to delay granting entitlement until the payment is finalized? Or is the expected implementation to grant entitlement upon successful transaction verification and revoke it only if Apple later sends a refund notification? Any clarification on the expected workflow would be greatly appreciated. Thanks in advance. :)
0
0
554
Jul ’26
Apple-signed Production transactions return 404 (4040010) on every App Store Server API endpoint
Environment: Production. Bundle ID: com.filmixpro.filmix. (Team ID / notification URL available privately or via Feedback Assistant.) We received 7 App Store Server Notifications V2 (SUBSCRIBED) whose JWS signatures we successfully verified against Apple root CAs (decoded payloads show environment=Production, bundleId=com.filmixpro.filmix). However, querying the App Store Server API (production) for these originalTransactionIds returns 404 (4040010) "Transaction id not found" on EVERY endpoint: Get All Subscription Statuses, Get Transaction Info, Get Transaction History, Get Refund History, and Get Notification History (filtered by transactionId). The same API key resolves all other transactions correctly (these are 7 out of 3231 chains scanned). The IDs are also absent from the global Get Notification History (last 180 days). Sandbox returns 404 as well. One of them, 520002039865757, previously generated a REFUND_DECLINED notification (a refund was requested and DECLINED — i.e. not refunded), yet it too now returns 404 on every endpoint including Get Refund History, so the disappearance is not explained by a refund. Affected originalTransactionIds: 590002039736765, 590002053449909, 430002231597484, 70003114793852, 100002338147592, 520002039865757, 340001586213801 Questions: Why do Apple-signed, Production transactions return 404 "Transaction id not found" on all App Store Server API endpoints? Have these transactions been removed/invalidated (fraud, chargeback, account deletion, refund reversal)? If so, which category? We recently signed a previously-unsigned Paid Applications Agreement — does this affect API visibility of historical transactions, and what is the propagation time? How should we reconcile entitlement for transactions that were signed/notified but are not found in the Server API?
1
0
623
Jul ’26
Cannot load products in Sandbox
Hi, I'm trying to hook up some test in app purchases to test purchase code between our app and our app's backend. When I try to load products (requestProductData) with my Sandbox account, my product identifiers come back in the invalid product identifiers member of the response. My product says it's in "waiting for review" status in app store connect, and I'm logged in to the app store with my sandbox account on my device. We just accepted the paid apps agreement as well--is there some propagation time to that? The product ID I'm using (both in app store connect and in-app) is test_durable. Do I need to append the package name to that or something? I've dug through the docs and through the forums here and come up empty. I tried using the Xcode storekit test harness and the issue there is that because that doesn't actually talk to the store apis, I can't use that to test my backend correctly validating/processing the transactions. Thanks!
0
0
444
Jul ’26
Can Product.products / SKProductsRequest be used only for display metadata when EU storefront uses ExternalPurchaseCustomLink only?
This is a StoreKit / ExternalPurchaseCustomLink clarification. Apple DTS asked me to post the follow-up question here. We are designing an SDK for apps that support EU external purchase. In EU storefronts, the app will use ExternalPurchaseCustomLink only: No App Store In-App Purchase will be offered to users. No Product.purchase() will be called. No SKPaymentQueue.add(_:) will be called. The actual purchase will happen only on our external website through the ExternalPurchaseCustomLink flow. Question: In this EU ExternalPurchaseCustomLink-only setup, is it acceptable and supported to call Product.products(for:) / SKProductsRequest only to fetch product display metadata from App Store Connect? The metadata would only be used to display the product list UI, for example: product title / display name localized price currency / priceLocale formatting information The returned Product / SKProduct would not be used to start an App Store purchase. Or should apps avoid Product.products(for:) / SKProductsRequest entirely in EU storefronts where only ExternalPurchaseCustomLink is offered, and use their own product catalog instead?
1
0
543
Jun ’26
App Store Server Notification v2: how to distinguish a resubscription that happened in-app from one that happened in Settings → Subscriptions?
Context We're handling App Store subscriptions on the server side using App Store Server Notification v2. Our pipeline currently identifies each event by transactionId and originalTransactionId. A few notes about our client: Our app is built with Flutter and uses the standard in_app_purchase plugin layer to drive App Store purchases (StoreKit 1 under the hood). We have not migrated to StoreKit 2 on the client yet. We have not been setting SKPayment.applicationUsername on outgoing purchases, so every transaction we've ever produced has appAccountToken: null in its v2 notification. This question is purely about what the server-side notification can tell us, given the current client state above. What we're trying to figure out A user can resubscribe to an expired subscription in two different places: In-app — the user opens our app and re-purchases through our normal in-app purchase flow. App Store — the user goes to Settings → Apple ID → Subscriptions and resubscribes from the system UI, without ever returning to the app. Both paths trigger a SUBSCRIBED notification (subtype RESUBSCRIBE) with structurally identical payloads as far as we can tell — same shape for data.transactionInfo, data.renewalInfo, etc. From the notification alone we can't decide which path produced it. The reason this matters: in our system, the two paths require different business handling: In-app path: the user may have signed in to a different business account in our app. The new subscription should be attributed to whoever paid in the app just now, not to the previous owner of originalTransactionId. App Store path: there is no in-app signal, so the business owner can only be inferred from the previous originalTransactionId mapping. If we get it wrong, the subscription's entitlement ends up on the wrong business account. What we do today Because we can't tell the paths apart from the notification, we defer processing for a few minutes and check whether an in-app order for the same transaction has arrived in the meantime: If an in-app order shows up → it's the in-app path; attribute to the in-app account. If nothing shows up after the delay → assume App Store path; fall back to the previous owner mapping. This works but adds latency to entitlement activation and forces us to build a deferred-retry queue with idempotency against the in-app callback path. Possible direction: appAccountToken / applicationUsername We noticed that v2 notifications carry transactionInfo.appAccountToken, and the docs suggest that StoreKit 1's SKPayment.applicationUsername (when it's a valid UUID) is mirrored into this field. In theory, if we start setting it on every in-app purchase from the Flutter client, the field could double as a path discriminator on the server: appAccountToken != null → in-app path (only the app can set it), and we even get the business user id for free appAccountToken == null → App Store path (no UI to populate it) But we have some open questions before committing to this direction: Questions Is there an existing signal in ResponseBodyV2 / JWSTransactionDecodedPayload / JWSRenewalInfoDecodedPayload that distinguishes these two paths, that I might be missing? Can the same distinction be obtained via getAllSubscriptionStatuses / getTransactionHistory / any other Server API endpoint? Is applicationUsername (StoreKit 1) still a reliable way to populate appAccountToken on v2 notifications today? Specifically: Are there format constraints beyond "valid UUID" that cause Apple to drop the value? Any known differences between sandbox and production in how it's mirrored? Does the App Store path ever strip or overwrite a previously-set value when the same originalTransactionId is reused? For existing subscriptions where applicationUsername was never set (which is all of ours today, since we've never polient), is there any way to retroactively distinguish the in-app vs App Store path? Or is timing-based deferred matching theonly option for that cohort, even after we start setting the value on new purchases? If neither (1) nor (2) is currently possible, is the timing-based heuristic we use today the pattern Apple expects developers to follow, or is there a recommended approach we're missing? A small suggestion, if it turns out there's no existing way If the information genuinely isn't exposed today, it might be worth surfacing a salesChannel-style field on the transaction, similar to what Google Play Developer API exposes on Order.salesChannel (IN_APP, PLAY_STORE, etc.). That would let server-side handlers route each event to the correct business owner immediately, regardless of whether appAccountToken was set, and would also cover legacynt never had a chance to populate it. Thanks — happy to share sample payloads or more detail if helpful.
1
0
1.1k
May ’26
How to validate App Store receipts and check subscription status from my server?
Hello, I have an app on the App Store that offers in-app purchases (consumable, non-consumable) and auto-renewable subscriptions. My goal is to verify the validity of purchase receipts on my own backend server, to prevent fraudulent transactions. My questions: Does Apple provide an API that allows my server to validate a receipt (the one generated after a purchase) and confirm whether it is genuine? For auto-renewable subscriptions, can I retrieve renewal dates, expiration dates, and current renewal status using that same API? From reading the documentation, I understand that Apple provides the App Store Server API and the App Store Server Notifications. Is this the correct approach for receipt validation and subscription status checking? Any clarification or code example would be greatly appreciated. Thank you.
1
0
1.1k
May ’26
Production subscription remains Active after failed payment and no funds deducted
Hello, We are investigating an auto-renewable monthly subscription in the Production environment. Timeline and observed behavior: On June 29, 2026, the user initiated the first subscription purchase. The Apple Account used WeChat Pay as its payment method. The WeChat charge failed because the balance was insufficient, and no funds were deducted from any available payment source. Nevertheless, StoreKit returned a verified transaction, the subscription purchase succeeded in the app, and App Store Connect Sales Analytics reports proceeds for the purchase. We grant entitlement based only on Apple's signed transaction and subscription status, so the user currently has access. As of July 20, 2026, Get All Subscription Statuses from App Store Server API returns: environment: Production status: 1 (Active) expiresDate: 2026-07-29T03:37:11Z autoRenewStatus: 1 no gracePeriodExpiresDate no revocationDate no expirationIntent no billing retry indication Our App Store Server Notifications endpoint has received only: SUBSCRIBED / INITIAL_BUY We have not received DID_FAIL_TO_RENEW, EXPIRED, REFUND, or REVOKE. Questions: Is it expected for Apple to issue a valid production initial-purchase transaction and report proceeds even when the underlying WeChat Pay charge failed and no money was deducted? Could this be an unpaid Apple Account balance or delayed settlement that is invisible to the developer? While the Server API returns status 1, should the developer continue granting entitlement until expiresDate? Is there another authoritative App Store Server API or signed field that indicates the payment has not actually been collected? If renewal or collection later fails, when should we expect DID_FAIL_TO_RENEW or a change to billing retry or expired status? We have intentionally omitted transaction IDs and account identifiers from this public post. I can provide them privately to Apple Support if needed. Thanks
Replies
1
Boosts
0
Views
262
Activity
2m
REFUND_REVERSED for auto-renewable subscriptions: is revocationDate cleared, and does auto-renew resume?
We handle App Store Server Notifications V2 for an auto-renewable subscription. When we receive REFUND for the current period, we revoke the customer's access. We now want to reinstate access on REFUND_REVERSED, as the documentation says: "If your app revoked content or services as a result of the related refund, it needs to reinstate them." Before reinstating, our server verifies the transaction in signedTransactionInfo and rejects it if revocationDate is present or expiresDate is in the past. We'd like to confirm a few behaviors so that the reinstatement doesn't get rejected by our own checks: In a REFUND_REVERSED notification, does the signedTransactionInfo still contain revocationDate (and revocationReason), or are they removed? Likewise, after the reversal, does Get Transaction Info / Get All Subscription Statuses return the transaction without revocationDate? An App Store Commerce Engineer explained in thread/757119 that when a customer requests a refund, the subscription's auto-renew status is set to false. Does this apply to every refund path (for example, refunds initiated by Apple or via chargebacks), or only to refunds requested by the customer? After REFUND_REVERSED, does the auto-renew status stay off, or can it be turned back on automatically? If it stays off, is the customer expected to re-enable auto-renew themselves? We have seen reports that REFUND_REVERSED can arrive weeks after REFUND, even when expiresDate has already passed. In that case, is it correct to reinstate access only up to the original expiresDate (i.e. nothing to reinstate if it has already passed)? Thank you.
Replies
0
Boosts
0
Views
2
Activity
2h
Questions on App Store Server API behaviors: Production accounts in Sandbox, and Cleared Sandbox data
Hello, I would like to clarify the exact technical behavior of the App Store Server API (V2) and StoreKit under the following two specific scenarios: Case A (Production Account on Sandbox Endpoint): If a user with a production Apple Account attempts to purchase through a build pointing to the Apple Sandbox environment (or Sandbox API), how does the Apple server handle this transaction and its data lifecycle? (Does StoreKit block this at the client-side, or does the API return a specific error code?) Case B (Restoring Cleared Sandbox Data): If a Sandbox tester's purchase history is cleared/deleted on the Apple server, and the app subsequently requests a "Restore Purchase" or queries the App Store Server API using a previously valid transactionID from that account, what specific error code (such as 4040010 TransactionNotFound) or empty response does the Apple server return? I would highly appreciate your confirmation or any technical insights on these behaviors. Thank you!
Replies
0
Boosts
0
Views
178
Activity
1d
Best practices for backend server transition timing to Production App Store Server API
Hello, I would like to clarify the best practices and timing for our backend server to transition its main connection to the production App Store Server API. Currently, we are considering the following approach: We plan to switch our backend’s primary API endpoint from Sandbox to Production once our app passes the App Store review and its status changes to "Ready for Sale." Could you please confirm if this timing is standard and correct? Additionally, to handle App Store reviews (which run in the Sandbox environment) and TestFlight tests seamlessly without manual configuration changes, we are planning to implement an automatic fallback mechanism: Our backend always requests the Production App Store Server API first. If it returns a "TransactionNotFound" (e.g., 4040010) error, the backend automatically retries the request using the Sandbox API. Is this automatic fallback from Production to Sandbox considered a safe and recommended practice by Apple, especially for App Store reviews and post-release testing? Any advice or insights on backend transition timing and fallback strategies would be highly appreciated. Thank you!
Replies
0
Boosts
0
Views
48
Activity
1d
Is dynamic fallback to Sandbox API correct when receiving error 4040010 (TransactionIdNotFoundError) during App Review?
Hi, During the App Review process, a test purchase was made using what appeared to be a production Apple account. When our app server sent this transactionId to the Production App Store Server API, it returned the error code 4040010 (TransactionIdNotFoundError). To handle this gracefully and prevent review rejections, we are considering implementing a dynamic fallback mechanism on our app server. Specifically, when the Production API returns 4040010, the server will automatically retry the request using the Sandbox App Store Server API URL. Could you please clarify the following points regarding this design? Is it expected behavior for an App Review purchase to return 4040010 on the Production API, and can it be successfully verified by routing it to the Sandbox API? Is this dynamic fallback logic (Production API ➔ if 4040010 ➔ Sandbox API) a recommended and officially supported best practice for handling App Review and TestFlight transactions? Any confirmation or advice from Apple engineers or the community would be greatly appreciated.Thank you.
Replies
0
Boosts
0
Views
18
Activity
1d
Is transactionId unique across Production and Sandbox environments for DB design?
Hi, I am designing a database schema to store App Store transaction data for our backend system, and I have a question regarding the uniqueness of transactionId. According to the documentation (apple.com), transactionId is a unique identifier for a transaction. However, it is not explicitly clear whether this uniqueness is guaranteed across different environments.Could you please clarify the following points? Is transactionId guaranteed to be unique across both the Production and Sandbox environments? (i.e., Is there any possibility that the exact same transactionId is generated in both environments?) For database design, is it safe to use transactionId alone as a Primary Key? Or is it strongly recommended to use a composite key consisting of both environment and transactionId? Any insights or best practices from Apple engineers or the community would be highly appreciated.Thank you.
Replies
0
Boosts
0
Views
13
Activity
1d
Sandbox test notification returns 4040007 after notification URL is saved and verified
For our app, we saved a sandbox App Store Server Notifications URL with V2 enabled and independently read the configuration back. A subsequent test-notification request returned HTTP 404 / 4040007. An authenticated sandbox notification-history request shortly beforehand returned HTTP 200. We restored the original settings after collecting diagnostics. The recorded failure is covered by Feedback Assistant report FB24885397. What could explain this discrepancy, and what additional diagnostics would help Apple investigate?
Replies
0
Boosts
0
Views
77
Activity
1d
ASSN V2: purchaseDate ~8 hours later than signedDate inside the same Apple-signed JWS (FB24820430)
Following the guidance in the locked thread "Reporting your App Store Server Notifications issue" (https://developer.apple.com/forums/thread/774053) and a DTS support request on the same topic, I am posting this issue with the Feedback Assistant ID requested there: FB24820430. Summary: This is a content anomaly in Apple-signed App Store Server payloads, not a notification delivery problem — our server receives and verifies every notification; the defect is in the field values themselves. For a stable subset of subscription families, purchaseDate in JWSTransactionDecodedPayload is consistently ~8 hours later than the signedDate of the very same JWS — a purchase recorded as happening after the signed document reporting it existed. Reproducible field comparison inside one and the same Apple-signed JWS: Field relation Affected transactions Unaffected (control) transactions purchaseDate − signedDate +7h54m … +7h59m (never ≤ 0) ≈ 0 (seconds) Webhook arrival at our server ≈ signedDate (seconds to minutes), never ≈ purchaseDate ≈ signedDate originalPurchaseDate carries the same ~8h shift (renewals inherit it) no shift expiresDate − purchaseDate exactly one subscription period exactly one subscription period expiresDate − signedDate period + ~8h period All fields are documented as "UNIX time, in milliseconds". Our iOS client passes StoreKit 2 Transaction.purchaseDate through unmodified; our backend stores the epoch-millisecond values verbatim as UTC with no timezone conversion. These payloads are generated and signed by Apple infrastructure. Scale (production, as of 2026-09-14): ≈710 subscription families (distinct originalTransactionId lineages), ≈2,700 transactions — roughly three quarters of all families with renewals. Affected purchases span early March 2026 to present, ~30–45 new affected transactions per day. Observed across US, PH, ID and GB storefronts and across app build versions. Sandbox is unaffected. Our interpretation (inference, not confirmed): the offset varies between 7h54m and 7h59m rather than being exactly 8h, consistent with a local wall-clock time in a UTC+8 environment having been encoded as if it were UTC when the original transaction record was created, then inherited by all renewals of that family. Questions for Apple engineers: Is this a known issue in App Store Server data, and is there a reference we can track? What conditions cause a family's purchaseDate to be recorded this way (storefronts/regions, purchase channels, offer types, original-receipt formats)? When purchaseDate and signedDate disagree, which field is authoritative for "when the customer was charged"? The public documentation defines each field only as "UNIX time, in milliseconds" and does not define its relationship. Is remediation planned on Apple's side, or what is the recommended way to obtain the true charge time? Evidence: A focused sample project (a ~85-line Swift tool plus four unmodified signedTransactionInfo JWS samples — three affected families and one unaffected control, each carrying Apple's x5c certificate chain) is included in Feedback Assistant report FB24820430, together with the raw HTTP notification bodies for an affected and a control notification, exactly as delivered to our endpoint. Thank you.
Replies
1
Boosts
0
Views
166
Activity
6d
Request a Test Notification returns 401 with an active In-App Purchase key and Apple Java Server Library
Hello Apple Developer Forums, We are unable to authorize the Production App Store Server API Request a Test Notification endpoint. Environment: Production API: Request a Test Notification Library: Apple App Store Server Library for Java 5.2.0 Client: AppStoreServerAPIClient Result: HTTP 401 Unauthorized before a testNotificationToken is returned. We have verified the following: The key is an active In-App Purchase key created in App Store Connect under Users and Access > Integrations > In-App Purchase. The production server uses the matching .p8 private key, Key ID, Issuer ID, and bundle ID. The bundle ID is com.ansio.serviceproof.ios. The server clock is NTP-synchronized. The request uses the official Apple Java Server Library rather than a manually generated JWT. We rotated the production In-App Purchase key once and received the same 401 result. The notification URL is configured for the Production environment, uses HTTPS, and is reachable. Sandbox uses an independent key and notification configuration. We intentionally do not include the private key, JWT, Key ID, or Issuer ID publicly. According to the documentation, HTTP 401 means the JWT is invalid. Since the official library creates the JWT and the active In-App Purchase key configuration has been verified, could Apple clarify: Is any additional App Store Connect role, agreement, team activation, or entitlement required for a Production In-App Purchase key to authorize App Store Server API requests? Is there a known propagation or authorization issue that can cause a newly created active In-App Purchase key to return 401? What non-sensitive diagnostic details can help distinguish a JWT construction issue from a team-level authorization issue? Thank you.
Replies
0
Boosts
0
Views
61
Activity
1w
All auto-renewable subscriptions returning expirationIntent = 5 after resolving an agreement issue (StoreKit 1 and StoreKit 2)
Hello, We are currently seeing errors when validating receipts for every auto-renewable subscription purchased through both StoreKit 1 and StoreKit 2. Details below. Case 1 — StoreKit 1 Calling https://buy.itunes.apple.com/verifyReceipt with the subscription receipt returns: "status": 21006, "expiration_intent": "5" Case 2 — StoreKit 2 Calling https://api.storekit.itunes.apple.com/inApps/v1/subscriptions and reading the most recent transaction (LastTransactionsItem) returns status 3. Within JWSRenewalInfoDecodedPayload: autoRenewStatus = 1, expirationIntent = 5 Timeline We believe renewals stopped processing for essentially all auto-renewing subscribers of our app as of 2026-09-18 09:30 KST (UTC+9). After resolving an agreement/licensing issue on our side, new purchases and some receipt validations recovered as of 2026-09-21 11:49 KST. However, most existing receipts still return expirationIntent = 5 when we query receipt validation or subscription status. Questions Is any action required on our side — a server-side change, a configuration change in App Store Connect, or a further review of our agreements? Now that the agreement issue is resolved, when are the renewals that were left pending during the outage expected to be processed? Any guidance would be appreciated. Thank you.
Replies
0
Boosts
0
Views
89
Activity
1w
App Store Server API mass renewal date extension remains incomplete for 11 days
Hello, I submitted a mass subscription renewal date extension request using the App Store Server API on September 9, 2026. The request was accepted successfully. However, when I check the request using getStatusOfSubscriptionRenewalDateExtensions, the status continues to return: complete: false As of September 20, the request has remained incomplete for 11 days. Request details: Extension: 1 day Reason: temporary service interruption Environment: Production The documentation states that a mass renewal date extension may take hours or even days to complete, but I have not been able to find guidance for a request that remains incomplete this long. Only three subscribers were affected by the service interruption, and I have their originalTransactionId values. I am considering using the individual subscription renewal date extension API instead. My questions are: Is it expected for a mass renewal date extension request to remain complete: false for 11 days? Could this mass request still complete at a later date? Is there any way to cancel or determine whether this mass request is stuck? If I extend the three affected subscriptions individually now, is there a risk that the pending mass request could later complete and extend them a second time? I would like to compensate the affected subscribers as soon as possible while avoiding duplicate extensions. Thank you for any guidance.
Replies
0
Boosts
0
Views
281
Activity
1w
In-App Purchase key returns 401 (4010000) on Advanced Commerce API but 200/404 on App Store Server API
Environment: Sandbox Bundle ID: com.fosssocial.app Key ID: L7DZYHGM62 Issuer ID: cf1f7bc7-452f-4bb8-a925-31ca29175fac Summary Our In-App Purchase key is accepted by the App Store Server API but rejected by the Advanced Commerce API, using the exact same bearer token. This appears to be an authorization grant that was never applied to the key, rather than a signing or request-format problem on our side. Reproduction — one token, two API families GET /inApps/v1/subscriptions/1 -> 404, errorCode 4040010 (token ACCEPTED, resource simply not found) POST /advancedCommerce/v1/subscription/changeMetadata/1 -> 401, errorCode 4010000 (token REJECTED) Same JWT, same key, issued seconds apart. A 401 on one family and a 404 on the other isolates this to key authorization. On-device symptom A signed SubscriptionCreateRequest passed to StoreKit as advancedCommerceData fails with StoreKitError.unknown / "Unable to Complete Request". No payment sheet appears and no InvalidRequestError is returned, so there is no field-level error to act on. What we have already verified JWS header: alg ES256, kid, typ JWT Claims: iss, iat, aud "advanced-commerce-api", bid, nonce, request No exp claim (per Apple's documentation) The request claim uses standard padded base64, not base64url Key ID and .p8 file confirmed to be a matching pair Key regenerated after receiving the Advanced Commerce access-granted email; the 401 is unchanged AdvancedCommerceProduct(id:) resolves successfully on device, which confirms the PRODUCT has Advanced Commerce access Question Does the In-App Purchase key require a separate authorization for the Advanced Commerce API beyond the product-level access we were granted? If so, how is that applied to an existing key?
Replies
0
Boosts
0
Views
212
Activity
3w
Purchase your membership.
Hello. Despite making my membership payment (and accidentally twice!), my membership is still not activated even after 62 hours. I contacted their support system but received no response. Does anyone have any suggestions?
Replies
1
Boosts
0
Views
616
Activity
Aug ’26
Cancel subscription not working in TestFlight
Hi, I have deployed my app on Test Flight, I have two subscriptions, monthly and yearly. User can have one of them at a time and upgrade, downgrade to the other. Upgrade, downgrade, cancel from the Apple Settings worked fine in the sandbox environment when testing locally. Now when I have deployed the app on TestFlight, I was able to purchase the subscription successfully from my app. Now when I want to cancel my subscription from the Apple Settings it gives me the following error after confirming cancellation, 'Your request is temporarily unable to be processed. Please try again later.' Also the other subscription offer (yearly) is also not shown to which I could upgrade, even though in the sandbox I was able to upgrade downgrade from the settings. Another thing I have noticed is that the app Icon or name is not shown anywhere in settings with the subscription. Instead of app icon only empty square is shown. Even though app icon shows fine everywhere else. Can someone please help me figure out this issue?
Replies
23
Boosts
15
Views
5.3k
Activity
Aug ’26
App Store Server Notification returns successful purchase while customer's payment remains Pending
App Store Server Notification returns successful purchase while customer's payment remains Pending We have encountered an edge case with a Non-Renewing Subscription and would appreciate clarification on the expected developer behavior. Steps to reproduce User initiates an in-app purchase using a credit card. The purchase succeeds in the app. Our backend receives an App Store Server Notification V2 (ONE_TIME_CHARGE). We successfully verify the signed JWS transaction. The same transaction is also returned by the App Store Server API. Based on the verified transaction, we grant the user's entitlement. However, on the customer's Apple account: The purchase is shown as Pending in Purchase History / Report a Problem. The customer reports that their credit card has not yet been charged. Question From a developer's perspective, should entitlement be granted immediately after receiving a valid App Store Server Notification and successfully verifying the transaction, even if the customer's purchase is still shown as Pending? Is there any App Store Server API or transaction field that indicates the payment has not yet been settled, allowing developers to delay granting entitlement until the payment is finalized? Or is the expected implementation to grant entitlement upon successful transaction verification and revoke it only if Apple later sends a refund notification? Any clarification on the expected workflow would be greatly appreciated. Thanks in advance. :)
Replies
0
Boosts
0
Views
554
Activity
Jul ’26
Apple-signed Production transactions return 404 (4040010) on every App Store Server API endpoint
Environment: Production. Bundle ID: com.filmixpro.filmix. (Team ID / notification URL available privately or via Feedback Assistant.) We received 7 App Store Server Notifications V2 (SUBSCRIBED) whose JWS signatures we successfully verified against Apple root CAs (decoded payloads show environment=Production, bundleId=com.filmixpro.filmix). However, querying the App Store Server API (production) for these originalTransactionIds returns 404 (4040010) "Transaction id not found" on EVERY endpoint: Get All Subscription Statuses, Get Transaction Info, Get Transaction History, Get Refund History, and Get Notification History (filtered by transactionId). The same API key resolves all other transactions correctly (these are 7 out of 3231 chains scanned). The IDs are also absent from the global Get Notification History (last 180 days). Sandbox returns 404 as well. One of them, 520002039865757, previously generated a REFUND_DECLINED notification (a refund was requested and DECLINED — i.e. not refunded), yet it too now returns 404 on every endpoint including Get Refund History, so the disappearance is not explained by a refund. Affected originalTransactionIds: 590002039736765, 590002053449909, 430002231597484, 70003114793852, 100002338147592, 520002039865757, 340001586213801 Questions: Why do Apple-signed, Production transactions return 404 "Transaction id not found" on all App Store Server API endpoints? Have these transactions been removed/invalidated (fraud, chargeback, account deletion, refund reversal)? If so, which category? We recently signed a previously-unsigned Paid Applications Agreement — does this affect API visibility of historical transactions, and what is the propagation time? How should we reconcile entitlement for transactions that were signed/notified but are not found in the Server API?
Replies
1
Boosts
0
Views
623
Activity
Jul ’26
Cannot load products in Sandbox
Hi, I'm trying to hook up some test in app purchases to test purchase code between our app and our app's backend. When I try to load products (requestProductData) with my Sandbox account, my product identifiers come back in the invalid product identifiers member of the response. My product says it's in "waiting for review" status in app store connect, and I'm logged in to the app store with my sandbox account on my device. We just accepted the paid apps agreement as well--is there some propagation time to that? The product ID I'm using (both in app store connect and in-app) is test_durable. Do I need to append the package name to that or something? I've dug through the docs and through the forums here and come up empty. I tried using the Xcode storekit test harness and the issue there is that because that doesn't actually talk to the store apis, I can't use that to test my backend correctly validating/processing the transactions. Thanks!
Replies
0
Boosts
0
Views
444
Activity
Jul ’26
Can Product.products / SKProductsRequest be used only for display metadata when EU storefront uses ExternalPurchaseCustomLink only?
This is a StoreKit / ExternalPurchaseCustomLink clarification. Apple DTS asked me to post the follow-up question here. We are designing an SDK for apps that support EU external purchase. In EU storefronts, the app will use ExternalPurchaseCustomLink only: No App Store In-App Purchase will be offered to users. No Product.purchase() will be called. No SKPaymentQueue.add(_:) will be called. The actual purchase will happen only on our external website through the ExternalPurchaseCustomLink flow. Question: In this EU ExternalPurchaseCustomLink-only setup, is it acceptable and supported to call Product.products(for:) / SKProductsRequest only to fetch product display metadata from App Store Connect? The metadata would only be used to display the product list UI, for example: product title / display name localized price currency / priceLocale formatting information The returned Product / SKProduct would not be used to start an App Store purchase. Or should apps avoid Product.products(for:) / SKProductsRequest entirely in EU storefronts where only ExternalPurchaseCustomLink is offered, and use their own product catalog instead?
Replies
1
Boosts
0
Views
543
Activity
Jun ’26
App Store Server Notification v2: how to distinguish a resubscription that happened in-app from one that happened in Settings → Subscriptions?
Context We're handling App Store subscriptions on the server side using App Store Server Notification v2. Our pipeline currently identifies each event by transactionId and originalTransactionId. A few notes about our client: Our app is built with Flutter and uses the standard in_app_purchase plugin layer to drive App Store purchases (StoreKit 1 under the hood). We have not migrated to StoreKit 2 on the client yet. We have not been setting SKPayment.applicationUsername on outgoing purchases, so every transaction we've ever produced has appAccountToken: null in its v2 notification. This question is purely about what the server-side notification can tell us, given the current client state above. What we're trying to figure out A user can resubscribe to an expired subscription in two different places: In-app — the user opens our app and re-purchases through our normal in-app purchase flow. App Store — the user goes to Settings → Apple ID → Subscriptions and resubscribes from the system UI, without ever returning to the app. Both paths trigger a SUBSCRIBED notification (subtype RESUBSCRIBE) with structurally identical payloads as far as we can tell — same shape for data.transactionInfo, data.renewalInfo, etc. From the notification alone we can't decide which path produced it. The reason this matters: in our system, the two paths require different business handling: In-app path: the user may have signed in to a different business account in our app. The new subscription should be attributed to whoever paid in the app just now, not to the previous owner of originalTransactionId. App Store path: there is no in-app signal, so the business owner can only be inferred from the previous originalTransactionId mapping. If we get it wrong, the subscription's entitlement ends up on the wrong business account. What we do today Because we can't tell the paths apart from the notification, we defer processing for a few minutes and check whether an in-app order for the same transaction has arrived in the meantime: If an in-app order shows up → it's the in-app path; attribute to the in-app account. If nothing shows up after the delay → assume App Store path; fall back to the previous owner mapping. This works but adds latency to entitlement activation and forces us to build a deferred-retry queue with idempotency against the in-app callback path. Possible direction: appAccountToken / applicationUsername We noticed that v2 notifications carry transactionInfo.appAccountToken, and the docs suggest that StoreKit 1's SKPayment.applicationUsername (when it's a valid UUID) is mirrored into this field. In theory, if we start setting it on every in-app purchase from the Flutter client, the field could double as a path discriminator on the server: appAccountToken != null → in-app path (only the app can set it), and we even get the business user id for free appAccountToken == null → App Store path (no UI to populate it) But we have some open questions before committing to this direction: Questions Is there an existing signal in ResponseBodyV2 / JWSTransactionDecodedPayload / JWSRenewalInfoDecodedPayload that distinguishes these two paths, that I might be missing? Can the same distinction be obtained via getAllSubscriptionStatuses / getTransactionHistory / any other Server API endpoint? Is applicationUsername (StoreKit 1) still a reliable way to populate appAccountToken on v2 notifications today? Specifically: Are there format constraints beyond "valid UUID" that cause Apple to drop the value? Any known differences between sandbox and production in how it's mirrored? Does the App Store path ever strip or overwrite a previously-set value when the same originalTransactionId is reused? For existing subscriptions where applicationUsername was never set (which is all of ours today, since we've never polient), is there any way to retroactively distinguish the in-app vs App Store path? Or is timing-based deferred matching theonly option for that cohort, even after we start setting the value on new purchases? If neither (1) nor (2) is currently possible, is the timing-based heuristic we use today the pattern Apple expects developers to follow, or is there a recommended approach we're missing? A small suggestion, if it turns out there's no existing way If the information genuinely isn't exposed today, it might be worth surfacing a salesChannel-style field on the transaction, similar to what Google Play Developer API exposes on Order.salesChannel (IN_APP, PLAY_STORE, etc.). That would let server-side handlers route each event to the correct business owner immediately, regardless of whether appAccountToken was set, and would also cover legacynt never had a chance to populate it. Thanks — happy to share sample payloads or more detail if helpful.
Replies
1
Boosts
0
Views
1.1k
Activity
May ’26
How to validate App Store receipts and check subscription status from my server?
Hello, I have an app on the App Store that offers in-app purchases (consumable, non-consumable) and auto-renewable subscriptions. My goal is to verify the validity of purchase receipts on my own backend server, to prevent fraudulent transactions. My questions: Does Apple provide an API that allows my server to validate a receipt (the one generated after a purchase) and confirm whether it is genuine? For auto-renewable subscriptions, can I retrieve renewal dates, expiration dates, and current renewal status using that same API? From reading the documentation, I understand that Apple provides the App Store Server API and the App Store Server Notifications. Is this the correct approach for receipt validation and subscription status checking? Any clarification or code example would be greatly appreciated. Thank you.
Replies
1
Boosts
0
Views
1.1k
Activity
May ’26