StoreKit

RSS for tag

Support in-app purchases and interactions with the App Store using StoreKit.

StoreKit Documentation

Posts under StoreKit subtopic

Post

Replies

Boosts

Views

Activity

Sandbox refund testing "Cannot connect" error
I'm running into a refund issue when testing in-app purchases in sandbox mode. I'm able to successfully purchase items but roughly 1 out of 3 times, when the refund window pops up, it says it cannot connect even though our webhook servers can verify the transaction id sent from apple. My internet connection is good and I've varied the wait period from purchase to refund from 15mins to 2 hours. Any help would be greatly appreciated.
1
0
159
Sep ’25
購入情報をサーバーで管理する場合は、アプリからサーバーに購入情報を渡す際にレシート検証する必要があるのか
アプリ内課金を実装しようとしていますが、サーバサイドのセキュリティに関してについて質問です。 StoreKit2を使えばアプリとApp Store Connect間のレシート検証は不要だが、 購入情報をサーバーで管理する場合は アプリからサーバーに購入情報を渡す際にレシート検証する必要があると考えるがその認識であっているか教えていただきたいです。
0
0
105
May ’25
Cannot see support instruction pages or entitlement request page for external purchase links.
Hello! I am trying to get my app set up to support external payments. The snag I am hitting at the moment is it seems that relevant pages are not accessible? There is this old EU doc https://developer.apple.com/support/apps-using-alternative-payment-providers-in-the-eu/ But the more updated US doc titled "Distributing apps in the U.S. that provide an external purchase link - Support" is not available where it should be https://developer.apple.com/support/storekit-external-entitlement-us/ In addition the link for requesting the entitlement seems to be broken https://developer.apple.com/contact/request/storekit-external-entitlement-us/ Any idea how one can access these? Perhaps this is just a temporary error?
0
0
121
May ’25
Inquiry regarding StoreKit Messages for Free Trial Conversion and Recurring Payment Consent in South Korea
Dear Apple Developer Support, Our iOS application offers subscriptions with a free trial period. We understand that in South Korea, due to local subscription regulations, users must explicitly provide consent for recurring payments before the subscription converts from a free trial to a paid period. We have the following questions regarding how StoreKit handles this scenario: When a free trial is about to convert to a paid subscription for a user in South Korea, does StoreKit send a StoreKit.Message (or SKStorefront.Message) to the application to obtain the required consent for recurring payments? If such a message is sent, would the Reason for this message be StoreKit.Message.Reason.priceIncreaseConsent, or would it be another specific reason related to initial recurring payment consent after a trial? If our application receives such a message and we choose to defer its display, what is the maximum recommended or permissible deferral period? Is it possible to save the data of a received StoreKit.Message and display it to the user at a later time, for instance, after the application has been closed and subsequently reopened? Are there any best practices or limitations regarding this? We need this information to ensure our application correctly handles these consent requirements in compliance with South Korean policies and provides a smooth user experience. Thank you for your guidance.
1
0
129
May ’25
Best practice to prevent users from switching between subscriptions in the same group?
Hello everyone, For example, our app currently has one subscription group in App Store Connect with 5 plans (2 annual, 2 monthly, and 1 quarterly). By default, users can go into Apple Subscriptions in Settings and freely switch between all of these plans. However, our business requirement is to only allow users to stay on one annual plan and one quarterly plan. We don’t want them to switch to the other plans. My questions are: Is there any best practice or recommended approach to restrict subscription switching within the same group? Would removing the unwanted products from sale be the correct approach, or are there any risks/downsides with this method? Has anyone faced a similar situation and found a practical solution? Any guidance or shared experience would be greatly appreciated. Thanks!
4
0
165
Sep ’25
Reporting to External Purchase Server API when using alternative PSP in the EU
Dear community, Context My company operates in the European Union, where not so long ago there appeared the possibility to accept an ["Alternative Terms Addendum for Apps in the EU"] (https://developer.apple.com/contact/request/download/alternate_eu_terms_addendum.pdf), which, among others, gives us the possibility to use an alternative payment provider, other than Apple's In App Purchase PSP system (ref: Apple docs). My company did accept it and was granted the StoreKit External Purchase Entitlement (com.apple.developer.storekit.external-purchase) entitlement, with which we integrated a different PSP, so now we want to incorporate the reporting to Apple's External Purchase Server API. We are currently integrating with the External Purchase Server API and have encountered a couple of issues I would appreciate clarification on: Question 1 Is there a way to retrieve an overview or summary of the current subscription states on Apple’s servers as a result of the submitted reports to External Purchase Server API? Specifically, I would like to verify the expected outcomes before the monthly invoice is issued by Apple and to understand the subscription states for the test users I used during this process and for future reference as well. Question 2 In one scenario, I initiated a one-year subscription, and in the middle of its period, I submitted a RENEWAL for one month with a higher price. I expected the request to fail due to overlapping periods and/or pricing conflicts, but both submissions were accepted without error. Do you have an idea about: What happens at the end of the renewed month? Will the subscription continue with the renewed (higher) amount, revert to the original (lower) annual rate, or be canceled? Where can I view the final state and billing plan for that subscription? Thank you for your assistance, we are looking forward for any kind of help or information regarding this topic.
0
0
130
Apr ’25
Verification failed with status INVALID_CHAIN_LENGTH
我正在通过集成app-store-server-library-java来实现 iap服务端校验。我参照了官网提供的Verification Usage 的代码,运行的时候异常信息如下: at com.apple.itunes.storekit.verification.ChainVerifier.verifyChainWithoutCaching(ChainVerifier.java:98) at com.apple.itunes.storekit.verification.ChainVerifier.verifyChain(ChainVerifier.java:71) at com.apple.itunes.storekit.verification.SignedDataVerifier.decodeSignedObject(SignedDataVerifier.java:186) at com.apple.itunes.storekit.verification.SignedDataVerifier.verifyAndDecodeTransaction(SignedDataVerifier.java:72) 我的代码如下: import com.apple.itunes.storekit.model.ResponseBodyV2DecodedPayload; import com.apple.itunes.storekit.verification.SignedDataVerifier; import com.apple.itunes.storekit.verification.VerificationException; import com.auth0.jwt.JWT; import com.auth0.jwt.interfaces.DecodedJWT; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.util.Base64; import java.util.Set; public class ExampleVerification { public static void main(String[] args) throws FileNotFoundException { String bundleId = "com.example"; Environment environment = Environment.SANDBOX; Set<InputStream> rootCAs = Set.of( new FileInputStream("AppleRootCA-G3.cer"), new FileInputStream("AppleRootCA-G2.cer") ); Long appAppleId = null; // appAppleId must be provided for the Production environment SignedDataVerifier signedPayloadVerifier = new SignedDataVerifier(rootCAs, bundleId, appAppleId, environment, true); String appTransactionJWS = "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6IkFwcGxlX1hjb2RlX0tleSIsIng1YyI6WyJNSUlCeXpDQ0FYR2dBd0lCQWdJQkFUQUtCZ2dxaGtqT1BRUURBakJJTVNJd0lBWURWUVFERXhsVGRHOXlaVXRwZENCVVpYTjBhVzVuSUdsdUlGaGpiMlJsTVNJd0lBWURWUVFLRXhsVGRHOXlaVXRwZENCVVpYTjBhVzVuSUdsdUlGaGpiMlJsTUI0WERUSTFNRFl3TXpFeE1UQXdNRm9YRFRJMk1EWXdNekV4TVRBd01Gb3dTREVpTUNBR0ExVUVBeE1aVTNSdmNtVkxhWFFnVkdWemRHbHVaeUJwYmlCWVkyOWtaVEVpTUNBR0ExVUVDaE1aVTNSdmNtVkxhWFFnVkdWemRHbHVaeUJwYmlCWVkyOWtaVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUFCTnZZZ3o1MW1CbEMweE5McW9rMUJCcithRWJEb1ZEeVkyaVRsejZsK1JjYVR4QStVY2ptMjBESTNncFFlM280a2doRGxSbGowdEo1enBGUHgyQWR2VCtqVERCS01CSUdBMVVkRXdFQlwvd1FJTUFZQkFmOENBUUF3SkFZRFZSMFJCQjB3RzRFWlUzUnZjbVZMYVhRZ1ZHVnpkR2x1WnlCcGJpQllZMjlrWlRBT0JnTlZIUThCQWY4RUJBTUNCNEF3Q2dZSUtvWkl6ajBFQXdJRFNBQXdSUUloQU40bUJWTHBoZkpjYjdweHF2b09XcjkyK1czYU5LRG9pazV5Vk9BT0NEVmxBaUFYWVF0czJubWZGMStGYzlSODJHXC96QWhaVU00aDNTXC9VdFE4Q1lPS2p3ZlE9PSJdfQ.eyJhcHBsaWNhdGlvblZlcnNpb24iOiIxIiwib3JpZ2luYWxQdXJjaGFzZURhdGUiOjAsImJ1bmRsZUlkIjoiYnJpZ2h0LnVuaWhhbmQuY24iLCJhcHBUcmFuc2FjdGlvbklkIjoiMCIsImRldmljZVZlcmlmaWNhdGlvbiI6IlRYdGRvMWZtNDhQVDdXUUh5cHU4K2l3TW55YmNoTTNNeG5XUnhOR1JqSFhQQnVqMXdUaldcL05zN3JtUmJlQTd3IiwicmVjZWlwdFR5cGUiOiJYY29kZSIsIm9yaWdpbmFsQXBwbGljYXRpb25WZXJzaW9uIjoiMSIsInJlcXVlc3REYXRlIjoxNzYxMDM1OTMzNTE3LCJvcmlnaW5hbFBsYXRmb3JtIjoiaU9TIiwicmVjZWlwdENyZWF0aW9uRGF0ZSI6MTc2MTAzNTkzMzUxNywiZGV2aWNlVmVyaWZpY2F0aW9uTm9uY2UiOiI1ZDhmNzM5Mi01N2YwLTQyM2YtOTMzNy1hZDQ0YTk5MDM4Y2EifQ.2ZO5xsx-yywP4IyaDz4KQ3mq181ZGwlX2uANSm-kHq50KIdMMUDveMsCrcZmHdzLH2rpfPsXKaIMdM25Hdcuuw"; DecodedJWT unverifiedJWT = JWT.decode(appTransactionJWS); String header = unverifiedJWT.getHeader(); System.out.println(new String(Base64.getDecoder().decode(header))); try { signedPayloadVerifier.verifyAndDecodeTransaction(appTransactionJWS); } catch (VerificationException e) { e.printStackTrace(); } } } 查看了ChainVerifier.java 源代码,发现 private static final int EXPECTED_CHAIN_LENGTH = 3; // <--- 关键常量 // ... PublicKey verifyChainWithoutCaching(String[] certificates, boolean performRevocationChecking, Date effectiveDate) throws VerificationException { // ... 解析证书代码 ... if (parsedCertificates.size() != EXPECTED_CHAIN_LENGTH) { throw new VerificationException(VerificationStatus.INVALID_CHAIN_LENGTH); // <--- 抛出异常点 } // ... 后续验证代码 ... } appTransactionJWS是来自客户端的沙盒环境。 我发现沙盒环境的jws总是包含一个证书,而后端验证又必须要求三个证书,请问这个问题如何解决。
0
0
89
Oct ’25
Unexpected ONE_TIME_CHARGE Refund Callback After Successful Purchase
We are using consumable in-app purchases. Starting from May 27th, we began receiving refund callbacks with the notificationType set to ONE_TIME_CHARGE immediately after users successfully completed a payment. { "notificationType": "ONE_TIME_CHARGE", "signedPayload": "..." } During this period, we did not make any changes to our App release or server-side purchase handling logic. Could this issue result in actual refunds being processed? What steps should we take to resolve this issue? We also noticed in your changelog that a new notification type ONE_TIME_CHARGE has been introduced. Can we safely ignore callbacks with the ONE_TIME_CHARGE notification type without affecting refund processing or user experience?
0
0
193
May ’25
I can't figure out how subscriptions work
Hi, This is the first time I'm submitting an app using IAP with auto-renewing subscriptions. Everything keeps getting rejected (specifically, my subscriptions), and instead of telling me what's wrong or what I need to fix, my reviewer just keeps regurgitating generic passages from the rules. Is there a site/tutorial/whatever that explains how to set these up and submit them? I haven't found anything that looks official/legit, so I'll settle on something recommended by someone who has been through the process. I would appreciate any help. I have been at this for DAYS and am at my wits end. Thanks.
1
0
93
Aug ’25
App Store Server Notifications Update
Hello Apple Support Team, We're a developer team that has created an app with subscription-based features, and we've been using App Store Server Notifications to receive updates about user subscription status changes. I'm reaching out to inquire about potential modifications to the App Store Server Notifications approach that might have improved notification delivery times for my app. So on our appstore app, when a user purchases a subscription, the apple server notifications reach our server and send us the complete detail of that user’s purchase for eg he upgraded or downgraded etc. And then based on the data we receive from app store server notifications, we save it in our database, along with updating the users subscription table in the database. Previously, we experienced delays in receiving the real time notifications from apple on our server, sometimes taking a few minutes, while other times they would arrive immediately. And because of this issue, the users faced delay in seeing their subscription updates, as our db was updated only after the app store server notification reached our server. However, recently, we've noticed a significant improvement, and notifications are now being delivered still in real-time, but without any noticeable delays. I'm wondering if Apple has made any changes to the App Store Server Notifications system that might have resolved the delay issue. Could you please confirm if any modifications were made in 2025, specifically from January onwards, that might have improved notification delivery times? Additionally, I'd like to know if these changes apply to both sandbox testing and production environments. If possible, could you please provide more information about the changes or direct me to a resource that might explain the updates? I'd appreciate your assistance in confirming this information, and I'm looking forward to hearing back from you.
0
0
141
May ’25
Guideline 2.1 - Performance - App Completeness
Apple review says , my app displayed an error when we attempted to purchase subscriptions. Please review the details and resources below and complete the next steps. Device type: iPad Air (5th generation) OS version: iPadOS 26.0.1 Next Steps When validating receipts on your server, your server needs to be able to handle a production-signed app getting its receipts from Apple’s test environment. The recommended approach is for your production server to always validate receipts against the production App Store first. If validation fails with the error code "Sandbox receipt used in production," you should validate against the test environment instead. Question: Is it due to Device being used by reviewer or is it really from my code. As my code relies on Apple infrastructure for purchases and all things. Initially i did had subscription reporting api for receipt handling and all.When i went through with ChatGPT it did say that issue is due to half baked subscription module on my server. So i decided not to send any Subscription related things to backend, now it's Apple only and on App side. Is it correct fix ? Or do i need to fix backend even though i have no use for it ? My team did test in sandbox env via internal testing that time we had no issues. And all was tested using Mobile devices, that's why i still have question just to be sure these errors are due to devices or not? Screenshot shared by Apple team did show they got a error popup saying Something went wrong : Unable to complete request. I am trying to reproduce in development but can't. Anyone had got same issue before and has information on how to resolve and test for it will be helpful. Thanks Shikhar Sahu
0
0
96
Oct ’25
Failed to get productIdentifier from StoreKit
I am currently developing an auto-renewal subscription in-app purchase for my app. Currently, the subscription items have already been approved in appStoreConnect, and the .store file is synced with appStoreConnect, so the subscription items are displayed well and the test is also progressing well. However, when I build without using the .store file to perform sandbox testing, the subscription items do not appear and response.invalidProductIdentifiers appears. Is there anything I need to do additionally so that the subscription items can appear in response.products? ps. The bank account item in the contract is in 'processing' status, and the paid app contract status is 'waiting for user information'.
1
0
193
May ’25
StoreKit Subscription Fails to Load During App Review, Works in Sandbox/TestFlight
Hi everyone, I’m facing a recurring issue with my macOS app being rejected during App Store review, and I’d really appreciate any guidance. The subscription flow in my app is implemented using StoreKit, and everything works perfectly in our development environment using a StoreKit configuration file. It also behaves as expected in Sandbox testing and TestFlight — I even had few beta testers confirm that the subscription information is displayed correctly and the purchase flow completes without issues. All required subscription details are configured in App Store Connect: • Subscription duration and the description of the services offered • Price and price per unit where applicable • Paid apps agreement and related forms are correctly filled However, when the app is submitted for review, the subscription screen fails to display the expected information. From what I can tell, the product information fails to load from the App Store in the review environment — even though everything is working fine on our side. We’ve already submitted a video to Apple showing the subscription UI working in the Sandbox environment, but the app continues to be rejected under guideline 3.1.2 due to missing subscription info in the binary. Is anyone else experiencing similar behavior during review? Could there be a caching issue or delay in StoreKit syncing for newly configured products? Any help or suggestions are very welcome. Thanks in advance!
0
0
124
Apr ’25
AppDistributor.current never returning
I try to access the AppDistributor.current (using try await) and the property never seem to return nor throw. The code I'm using looks like this: do { print("accessing current") let current = try await AppDistributor.current print("current obtained") switch(current) { case .appStore: return "AppStore" default: return "Unknown" } } catch { return "Exception: \(error)" } But the log only shows the accessing current and never the current obtained. Trying to step in the property starts with some assembly, but at some point, the debugger just never returned. I join a full Swift file of a sample test I'm using: SwiftMarketplaceTests.swift
0
0
150
Jun ’25
StoreKit2 caches local raw transactions and retrieval
FB19377002 I am looking to improve and review my subscription purchase handling logic, for the best user experience. Considering that StoreKit2 caches local raw transactions (in case user is offline), is it really necessary to persist "unlocked status" in UserDefaults or SwiftData Model or AppStorage? Are there significant delays when reading Transaction.currentEntitlements from locally stored cache, versus reading it from UserDefaults; or, as in the latest SKDemo example, even reading it from stored in SwiftData ? https://developer.apple.com/forums/thread/706450 I only have subscriptions ( I don't have noncosumable or consubale products). Do I still need to persist subscription status?
0
0
94
Aug ’25
Error setting install attribution pingback
Hi there, We have an app targeted for children and we want to use the SkAdNetwork to track installs for campaigns. We don't want to track further in-app events (purchase etc.), just the install event. We added the SDK to our Unity app, listed the network identifiers in the plist file, configured the external campaign according to their instructions, but struggle to see any events for several weeks now. We see the following logs in the app: Registering install attribution pingback. Failed to migrate Install Attribution database schema from 17001 => 17400. SkAdNetwork: No pingbacks found while attempting to register/update. Error setting install attribution pingback registered for app: 1509727806, error: Error Domain=ASDErrorDomain code=1208 How can we debug this further? What does the error mean? Thank you very much! (I hope I posted in the correct forum topic. Apologies if not)
0
0
60
Apr ’25
original transaction id not found
Hi everyone, I’ve been receiving App Store Server Notifications (webhooks) normally for a specific transaction. Everything was working fine — I could use the original_transaction_id to query transaction history, and transaction_id to look up specific transactions. However, starting recently, all API calls for that transaction (both Get Transaction Info and Get Transaction History) now return not found. • The webhooks used to arrive normally for this transaction. • I am sure I’m querying the correct environment (production vs sandbox). • The IDs I’m using are exactly the ones from the last webhook payload. • I haven’t changed my integration code. My questions: 1. Under what conditions does Apple’s API return “not found” for original_transaction_id that previously worked? 2. Can Apple actually purge transaction records (in production)? 3. Could this happen due to refunds, revocations, or other account actions? 4. Is this expected behavior, or should I file a DTS (Technical Support Incident)? Any insight would be appreciated. Thanks in advance!
1
0
158
Sep ’25
Adding In-App Purchase to app + review required?
I'm trying to understand the IAP development process. I created my first Product on App Store Connect and am trying to build my app to use it. However it keeps failing with "Invalid product ID.". From what I've read, this is because the product has not yet gone through review. But what I don't understand is, of course it hasn't gone through review yet, because trying to use it in any capacity fails, even though I'm using a real physical device and using a Sandbox User. Is this the correct workflow? It seems very backwards that I have to submit the product for review, even before I know how it's going to be used. I'm still building the screen for the product page, and haven't even started touching any backend APIs, yet it's asking for screenshots. Am I misunderstanding something here?
0
0
83
Apr ’25
Sandbox refund testing "Cannot connect" error
I'm running into a refund issue when testing in-app purchases in sandbox mode. I'm able to successfully purchase items but roughly 1 out of 3 times, when the refund window pops up, it says it cannot connect even though our webhook servers can verify the transaction id sent from apple. My internet connection is good and I've varied the wait period from purchase to refund from 15mins to 2 hours. Any help would be greatly appreciated.
Replies
1
Boosts
0
Views
159
Activity
Sep ’25
購入情報をサーバーで管理する場合は、アプリからサーバーに購入情報を渡す際にレシート検証する必要があるのか
アプリ内課金を実装しようとしていますが、サーバサイドのセキュリティに関してについて質問です。 StoreKit2を使えばアプリとApp Store Connect間のレシート検証は不要だが、 購入情報をサーバーで管理する場合は アプリからサーバーに購入情報を渡す際にレシート検証する必要があると考えるがその認識であっているか教えていただきたいです。
Replies
0
Boosts
0
Views
105
Activity
May ’25
Cannot see support instruction pages or entitlement request page for external purchase links.
Hello! I am trying to get my app set up to support external payments. The snag I am hitting at the moment is it seems that relevant pages are not accessible? There is this old EU doc https://developer.apple.com/support/apps-using-alternative-payment-providers-in-the-eu/ But the more updated US doc titled "Distributing apps in the U.S. that provide an external purchase link - Support" is not available where it should be https://developer.apple.com/support/storekit-external-entitlement-us/ In addition the link for requesting the entitlement seems to be broken https://developer.apple.com/contact/request/storekit-external-entitlement-us/ Any idea how one can access these? Perhaps this is just a temporary error?
Replies
0
Boosts
0
Views
121
Activity
May ’25
Inquiry regarding StoreKit Messages for Free Trial Conversion and Recurring Payment Consent in South Korea
Dear Apple Developer Support, Our iOS application offers subscriptions with a free trial period. We understand that in South Korea, due to local subscription regulations, users must explicitly provide consent for recurring payments before the subscription converts from a free trial to a paid period. We have the following questions regarding how StoreKit handles this scenario: When a free trial is about to convert to a paid subscription for a user in South Korea, does StoreKit send a StoreKit.Message (or SKStorefront.Message) to the application to obtain the required consent for recurring payments? If such a message is sent, would the Reason for this message be StoreKit.Message.Reason.priceIncreaseConsent, or would it be another specific reason related to initial recurring payment consent after a trial? If our application receives such a message and we choose to defer its display, what is the maximum recommended or permissible deferral period? Is it possible to save the data of a received StoreKit.Message and display it to the user at a later time, for instance, after the application has been closed and subsequently reopened? Are there any best practices or limitations regarding this? We need this information to ensure our application correctly handles these consent requirements in compliance with South Korean policies and provides a smooth user experience. Thank you for your guidance.
Replies
1
Boosts
0
Views
129
Activity
May ’25
Sandbox offer codes not working in sandbox environment
I've been testing the offer code feature for my non consumable in app purchase using a sandbox account, with sandbox offer codes and in the sandbox environment. However, the codes don't appear to work despite everything being in the sandbox. Any idea what I'm missing?
Replies
2
Boosts
0
Views
145
Activity
Oct ’25
BUG: Store kit configuration file processing macOS
The same store kit configuration file works in iOS and iPadOS, but not in macOS for the same multi platform application project with a single scheme. Here’s a more detailed write up with the sample code and screenshots. When the simple app is run on https://www.reddit.com/r/SwiftUI/s/KJsYcggWOa EDIT: I’m using Xcode 16.4
Replies
2
Boosts
0
Views
238
Activity
Sep ’25
Best practice to prevent users from switching between subscriptions in the same group?
Hello everyone, For example, our app currently has one subscription group in App Store Connect with 5 plans (2 annual, 2 monthly, and 1 quarterly). By default, users can go into Apple Subscriptions in Settings and freely switch between all of these plans. However, our business requirement is to only allow users to stay on one annual plan and one quarterly plan. We don’t want them to switch to the other plans. My questions are: Is there any best practice or recommended approach to restrict subscription switching within the same group? Would removing the unwanted products from sale be the correct approach, or are there any risks/downsides with this method? Has anyone faced a similar situation and found a practical solution? Any guidance or shared experience would be greatly appreciated. Thanks!
Replies
4
Boosts
0
Views
165
Activity
Sep ’25
Reporting to External Purchase Server API when using alternative PSP in the EU
Dear community, Context My company operates in the European Union, where not so long ago there appeared the possibility to accept an ["Alternative Terms Addendum for Apps in the EU"] (https://developer.apple.com/contact/request/download/alternate_eu_terms_addendum.pdf), which, among others, gives us the possibility to use an alternative payment provider, other than Apple's In App Purchase PSP system (ref: Apple docs). My company did accept it and was granted the StoreKit External Purchase Entitlement (com.apple.developer.storekit.external-purchase) entitlement, with which we integrated a different PSP, so now we want to incorporate the reporting to Apple's External Purchase Server API. We are currently integrating with the External Purchase Server API and have encountered a couple of issues I would appreciate clarification on: Question 1 Is there a way to retrieve an overview or summary of the current subscription states on Apple’s servers as a result of the submitted reports to External Purchase Server API? Specifically, I would like to verify the expected outcomes before the monthly invoice is issued by Apple and to understand the subscription states for the test users I used during this process and for future reference as well. Question 2 In one scenario, I initiated a one-year subscription, and in the middle of its period, I submitted a RENEWAL for one month with a higher price. I expected the request to fail due to overlapping periods and/or pricing conflicts, but both submissions were accepted without error. Do you have an idea about: What happens at the end of the renewed month? Will the subscription continue with the renewed (higher) amount, revert to the original (lower) annual rate, or be canceled? Where can I view the final state and billing plan for that subscription? Thank you for your assistance, we are looking forward for any kind of help or information regarding this topic.
Replies
0
Boosts
0
Views
130
Activity
Apr ’25
Verification failed with status INVALID_CHAIN_LENGTH
我正在通过集成app-store-server-library-java来实现 iap服务端校验。我参照了官网提供的Verification Usage 的代码,运行的时候异常信息如下: at com.apple.itunes.storekit.verification.ChainVerifier.verifyChainWithoutCaching(ChainVerifier.java:98) at com.apple.itunes.storekit.verification.ChainVerifier.verifyChain(ChainVerifier.java:71) at com.apple.itunes.storekit.verification.SignedDataVerifier.decodeSignedObject(SignedDataVerifier.java:186) at com.apple.itunes.storekit.verification.SignedDataVerifier.verifyAndDecodeTransaction(SignedDataVerifier.java:72) 我的代码如下: import com.apple.itunes.storekit.model.ResponseBodyV2DecodedPayload; import com.apple.itunes.storekit.verification.SignedDataVerifier; import com.apple.itunes.storekit.verification.VerificationException; import com.auth0.jwt.JWT; import com.auth0.jwt.interfaces.DecodedJWT; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.util.Base64; import java.util.Set; public class ExampleVerification { public static void main(String[] args) throws FileNotFoundException { String bundleId = "com.example"; Environment environment = Environment.SANDBOX; Set<InputStream> rootCAs = Set.of( new FileInputStream("AppleRootCA-G3.cer"), new FileInputStream("AppleRootCA-G2.cer") ); Long appAppleId = null; // appAppleId must be provided for the Production environment SignedDataVerifier signedPayloadVerifier = new SignedDataVerifier(rootCAs, bundleId, appAppleId, environment, true); String appTransactionJWS = "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6IkFwcGxlX1hjb2RlX0tleSIsIng1YyI6WyJNSUlCeXpDQ0FYR2dBd0lCQWdJQkFUQUtCZ2dxaGtqT1BRUURBakJJTVNJd0lBWURWUVFERXhsVGRHOXlaVXRwZENCVVpYTjBhVzVuSUdsdUlGaGpiMlJsTVNJd0lBWURWUVFLRXhsVGRHOXlaVXRwZENCVVpYTjBhVzVuSUdsdUlGaGpiMlJsTUI0WERUSTFNRFl3TXpFeE1UQXdNRm9YRFRJMk1EWXdNekV4TVRBd01Gb3dTREVpTUNBR0ExVUVBeE1aVTNSdmNtVkxhWFFnVkdWemRHbHVaeUJwYmlCWVkyOWtaVEVpTUNBR0ExVUVDaE1aVTNSdmNtVkxhWFFnVkdWemRHbHVaeUJwYmlCWVkyOWtaVEJaTUJNR0J5cUdTTTQ5QWdFR0NDcUdTTTQ5QXdFSEEwSUFCTnZZZ3o1MW1CbEMweE5McW9rMUJCcithRWJEb1ZEeVkyaVRsejZsK1JjYVR4QStVY2ptMjBESTNncFFlM280a2doRGxSbGowdEo1enBGUHgyQWR2VCtqVERCS01CSUdBMVVkRXdFQlwvd1FJTUFZQkFmOENBUUF3SkFZRFZSMFJCQjB3RzRFWlUzUnZjbVZMYVhRZ1ZHVnpkR2x1WnlCcGJpQllZMjlrWlRBT0JnTlZIUThCQWY4RUJBTUNCNEF3Q2dZSUtvWkl6ajBFQXdJRFNBQXdSUUloQU40bUJWTHBoZkpjYjdweHF2b09XcjkyK1czYU5LRG9pazV5Vk9BT0NEVmxBaUFYWVF0czJubWZGMStGYzlSODJHXC96QWhaVU00aDNTXC9VdFE4Q1lPS2p3ZlE9PSJdfQ.eyJhcHBsaWNhdGlvblZlcnNpb24iOiIxIiwib3JpZ2luYWxQdXJjaGFzZURhdGUiOjAsImJ1bmRsZUlkIjoiYnJpZ2h0LnVuaWhhbmQuY24iLCJhcHBUcmFuc2FjdGlvbklkIjoiMCIsImRldmljZVZlcmlmaWNhdGlvbiI6IlRYdGRvMWZtNDhQVDdXUUh5cHU4K2l3TW55YmNoTTNNeG5XUnhOR1JqSFhQQnVqMXdUaldcL05zN3JtUmJlQTd3IiwicmVjZWlwdFR5cGUiOiJYY29kZSIsIm9yaWdpbmFsQXBwbGljYXRpb25WZXJzaW9uIjoiMSIsInJlcXVlc3REYXRlIjoxNzYxMDM1OTMzNTE3LCJvcmlnaW5hbFBsYXRmb3JtIjoiaU9TIiwicmVjZWlwdENyZWF0aW9uRGF0ZSI6MTc2MTAzNTkzMzUxNywiZGV2aWNlVmVyaWZpY2F0aW9uTm9uY2UiOiI1ZDhmNzM5Mi01N2YwLTQyM2YtOTMzNy1hZDQ0YTk5MDM4Y2EifQ.2ZO5xsx-yywP4IyaDz4KQ3mq181ZGwlX2uANSm-kHq50KIdMMUDveMsCrcZmHdzLH2rpfPsXKaIMdM25Hdcuuw"; DecodedJWT unverifiedJWT = JWT.decode(appTransactionJWS); String header = unverifiedJWT.getHeader(); System.out.println(new String(Base64.getDecoder().decode(header))); try { signedPayloadVerifier.verifyAndDecodeTransaction(appTransactionJWS); } catch (VerificationException e) { e.printStackTrace(); } } } 查看了ChainVerifier.java 源代码,发现 private static final int EXPECTED_CHAIN_LENGTH = 3; // <--- 关键常量 // ... PublicKey verifyChainWithoutCaching(String[] certificates, boolean performRevocationChecking, Date effectiveDate) throws VerificationException { // ... 解析证书代码 ... if (parsedCertificates.size() != EXPECTED_CHAIN_LENGTH) { throw new VerificationException(VerificationStatus.INVALID_CHAIN_LENGTH); // <--- 抛出异常点 } // ... 后续验证代码 ... } appTransactionJWS是来自客户端的沙盒环境。 我发现沙盒环境的jws总是包含一个证书,而后端验证又必须要求三个证书,请问这个问题如何解决。
Replies
0
Boosts
0
Views
89
Activity
Oct ’25
Unexpected ONE_TIME_CHARGE Refund Callback After Successful Purchase
We are using consumable in-app purchases. Starting from May 27th, we began receiving refund callbacks with the notificationType set to ONE_TIME_CHARGE immediately after users successfully completed a payment. { "notificationType": "ONE_TIME_CHARGE", "signedPayload": "..." } During this period, we did not make any changes to our App release or server-side purchase handling logic. Could this issue result in actual refunds being processed? What steps should we take to resolve this issue? We also noticed in your changelog that a new notification type ONE_TIME_CHARGE has been introduced. Can we safely ignore callbacks with the ONE_TIME_CHARGE notification type without affecting refund processing or user experience?
Replies
0
Boosts
0
Views
193
Activity
May ’25
I can't figure out how subscriptions work
Hi, This is the first time I'm submitting an app using IAP with auto-renewing subscriptions. Everything keeps getting rejected (specifically, my subscriptions), and instead of telling me what's wrong or what I need to fix, my reviewer just keeps regurgitating generic passages from the rules. Is there a site/tutorial/whatever that explains how to set these up and submit them? I haven't found anything that looks official/legit, so I'll settle on something recommended by someone who has been through the process. I would appreciate any help. I have been at this for DAYS and am at my wits end. Thanks.
Replies
1
Boosts
0
Views
93
Activity
Aug ’25
App Store Server Notifications Update
Hello Apple Support Team, We're a developer team that has created an app with subscription-based features, and we've been using App Store Server Notifications to receive updates about user subscription status changes. I'm reaching out to inquire about potential modifications to the App Store Server Notifications approach that might have improved notification delivery times for my app. So on our appstore app, when a user purchases a subscription, the apple server notifications reach our server and send us the complete detail of that user’s purchase for eg he upgraded or downgraded etc. And then based on the data we receive from app store server notifications, we save it in our database, along with updating the users subscription table in the database. Previously, we experienced delays in receiving the real time notifications from apple on our server, sometimes taking a few minutes, while other times they would arrive immediately. And because of this issue, the users faced delay in seeing their subscription updates, as our db was updated only after the app store server notification reached our server. However, recently, we've noticed a significant improvement, and notifications are now being delivered still in real-time, but without any noticeable delays. I'm wondering if Apple has made any changes to the App Store Server Notifications system that might have resolved the delay issue. Could you please confirm if any modifications were made in 2025, specifically from January onwards, that might have improved notification delivery times? Additionally, I'd like to know if these changes apply to both sandbox testing and production environments. If possible, could you please provide more information about the changes or direct me to a resource that might explain the updates? I'd appreciate your assistance in confirming this information, and I'm looking forward to hearing back from you.
Replies
0
Boosts
0
Views
141
Activity
May ’25
Guideline 2.1 - Performance - App Completeness
Apple review says , my app displayed an error when we attempted to purchase subscriptions. Please review the details and resources below and complete the next steps. Device type: iPad Air (5th generation) OS version: iPadOS 26.0.1 Next Steps When validating receipts on your server, your server needs to be able to handle a production-signed app getting its receipts from Apple’s test environment. The recommended approach is for your production server to always validate receipts against the production App Store first. If validation fails with the error code "Sandbox receipt used in production," you should validate against the test environment instead. Question: Is it due to Device being used by reviewer or is it really from my code. As my code relies on Apple infrastructure for purchases and all things. Initially i did had subscription reporting api for receipt handling and all.When i went through with ChatGPT it did say that issue is due to half baked subscription module on my server. So i decided not to send any Subscription related things to backend, now it's Apple only and on App side. Is it correct fix ? Or do i need to fix backend even though i have no use for it ? My team did test in sandbox env via internal testing that time we had no issues. And all was tested using Mobile devices, that's why i still have question just to be sure these errors are due to devices or not? Screenshot shared by Apple team did show they got a error popup saying Something went wrong : Unable to complete request. I am trying to reproduce in development but can't. Anyone had got same issue before and has information on how to resolve and test for it will be helpful. Thanks Shikhar Sahu
Replies
0
Boosts
0
Views
96
Activity
Oct ’25
Failed to get productIdentifier from StoreKit
I am currently developing an auto-renewal subscription in-app purchase for my app. Currently, the subscription items have already been approved in appStoreConnect, and the .store file is synced with appStoreConnect, so the subscription items are displayed well and the test is also progressing well. However, when I build without using the .store file to perform sandbox testing, the subscription items do not appear and response.invalidProductIdentifiers appears. Is there anything I need to do additionally so that the subscription items can appear in response.products? ps. The bank account item in the contract is in 'processing' status, and the paid app contract status is 'waiting for user information'.
Replies
1
Boosts
0
Views
193
Activity
May ’25
StoreKit Subscription Fails to Load During App Review, Works in Sandbox/TestFlight
Hi everyone, I’m facing a recurring issue with my macOS app being rejected during App Store review, and I’d really appreciate any guidance. The subscription flow in my app is implemented using StoreKit, and everything works perfectly in our development environment using a StoreKit configuration file. It also behaves as expected in Sandbox testing and TestFlight — I even had few beta testers confirm that the subscription information is displayed correctly and the purchase flow completes without issues. All required subscription details are configured in App Store Connect: • Subscription duration and the description of the services offered • Price and price per unit where applicable • Paid apps agreement and related forms are correctly filled However, when the app is submitted for review, the subscription screen fails to display the expected information. From what I can tell, the product information fails to load from the App Store in the review environment — even though everything is working fine on our side. We’ve already submitted a video to Apple showing the subscription UI working in the Sandbox environment, but the app continues to be rejected under guideline 3.1.2 due to missing subscription info in the binary. Is anyone else experiencing similar behavior during review? Could there be a caching issue or delay in StoreKit syncing for newly configured products? Any help or suggestions are very welcome. Thanks in advance!
Replies
0
Boosts
0
Views
124
Activity
Apr ’25
AppDistributor.current never returning
I try to access the AppDistributor.current (using try await) and the property never seem to return nor throw. The code I'm using looks like this: do { print("accessing current") let current = try await AppDistributor.current print("current obtained") switch(current) { case .appStore: return "AppStore" default: return "Unknown" } } catch { return "Exception: \(error)" } But the log only shows the accessing current and never the current obtained. Trying to step in the property starts with some assembly, but at some point, the debugger just never returned. I join a full Swift file of a sample test I'm using: SwiftMarketplaceTests.swift
Replies
0
Boosts
0
Views
150
Activity
Jun ’25
StoreKit2 caches local raw transactions and retrieval
FB19377002 I am looking to improve and review my subscription purchase handling logic, for the best user experience. Considering that StoreKit2 caches local raw transactions (in case user is offline), is it really necessary to persist "unlocked status" in UserDefaults or SwiftData Model or AppStorage? Are there significant delays when reading Transaction.currentEntitlements from locally stored cache, versus reading it from UserDefaults; or, as in the latest SKDemo example, even reading it from stored in SwiftData ? https://developer.apple.com/forums/thread/706450 I only have subscriptions ( I don't have noncosumable or consubale products). Do I still need to persist subscription status?
Replies
0
Boosts
0
Views
94
Activity
Aug ’25
Error setting install attribution pingback
Hi there, We have an app targeted for children and we want to use the SkAdNetwork to track installs for campaigns. We don't want to track further in-app events (purchase etc.), just the install event. We added the SDK to our Unity app, listed the network identifiers in the plist file, configured the external campaign according to their instructions, but struggle to see any events for several weeks now. We see the following logs in the app: Registering install attribution pingback. Failed to migrate Install Attribution database schema from 17001 => 17400. SkAdNetwork: No pingbacks found while attempting to register/update. Error setting install attribution pingback registered for app: 1509727806, error: Error Domain=ASDErrorDomain code=1208 How can we debug this further? What does the error mean? Thank you very much! (I hope I posted in the correct forum topic. Apologies if not)
Replies
0
Boosts
0
Views
60
Activity
Apr ’25
original transaction id not found
Hi everyone, I’ve been receiving App Store Server Notifications (webhooks) normally for a specific transaction. Everything was working fine — I could use the original_transaction_id to query transaction history, and transaction_id to look up specific transactions. However, starting recently, all API calls for that transaction (both Get Transaction Info and Get Transaction History) now return not found. • The webhooks used to arrive normally for this transaction. • I am sure I’m querying the correct environment (production vs sandbox). • The IDs I’m using are exactly the ones from the last webhook payload. • I haven’t changed my integration code. My questions: 1. Under what conditions does Apple’s API return “not found” for original_transaction_id that previously worked? 2. Can Apple actually purge transaction records (in production)? 3. Could this happen due to refunds, revocations, or other account actions? 4. Is this expected behavior, or should I file a DTS (Technical Support Incident)? Any insight would be appreciated. Thanks in advance!
Replies
1
Boosts
0
Views
158
Activity
Sep ’25
Adding In-App Purchase to app + review required?
I'm trying to understand the IAP development process. I created my first Product on App Store Connect and am trying to build my app to use it. However it keeps failing with "Invalid product ID.". From what I've read, this is because the product has not yet gone through review. But what I don't understand is, of course it hasn't gone through review yet, because trying to use it in any capacity fails, even though I'm using a real physical device and using a Sandbox User. Is this the correct workflow? It seems very backwards that I have to submit the product for review, even before I know how it's going to be used. I'm still building the screen for the product page, and haven't even started touching any backend APIs, yet it's asking for screenshots. Am I misunderstanding something here?
Replies
0
Boosts
0
Views
83
Activity
Apr ’25