We have some users who have upgraded to iOS 26 beta3. Currently, we observe that when these users make in-app purchases, our code calls [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; method, and we clearly receive the successful removal callback in the delegate method - (void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray<SKPaymentTransaction *> *)transactions. However, when users click on products with the same productId again, the method - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions still returns information about previously removed transactions, preventing users from making further in-app purchases.
In-App Purchase
RSS for tagOffer extra content, digital goods, and features directly within your app using in-app purchases.
Posts under In-App Purchase tag
200 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
On iOS 26 beta 3, after a user purchases an item, initiating a second order for the same product fails to process payment. The system returns the same transaction ID and displays an interface message stating: "You've already purchased this In-App Purchase. It will be restored for free."
I’ve tested this – not only did the legacy StoreKit finishTransaction method fail to work, but StoreKit2 finish method also malfunctioned.
When will Apple fix this issue? If unresolved, it will prevent a large number of users from making purchases normally, leading to disastrous consequences.
I’m stuck in a loop where my in-app purchase (IAP) product cannot be reviewed because my app version is in “Rejected” status.
In order to submit the IAP for review, I need to submit a new app version and select the IAP product. But since the current version is rejected, I can't select the IAP during submission.
As a result, RevenueCat can't fetch the IAP products, and the app appears to not use in-app purchases, which leads to another rejection.
I’d like to know the correct steps to break this cycle and properly submit both the app and the IAP for review.
Any guidance is appreciated!
Hi, we have published a flutter app on the App Store offering additional content via one-time in-app purchases. Everything is working as expected when distributing the app via TestFlight but we're reportedly having issues with users not being able to restore purchases on some devices with the app loaded from the Apple App Store.
We noticed the issue when some user were unable to unlock the in-app purchases via promotion codes we supplied for marketing reasons. Most of them were able to unlock the purchases using the promotion codes without a problem. Some had to try several times using a new code each time but for some users (on some of their devices) it's not working at all and we can't seem to find the reason for it.
Here is one users case in detail:
the user tried to unlock our "complete bundle" using a promo code
first code did not seem to work, so I provided a new code
it seems that both codes were redeemed correctly because both of the show up in the users purchase history in his App Store profile
Now, the user is unable to unlock the content inside our app on his iPhone, he is however able to unlock it on its iPad without a problem. Both devices run the same iOS version, same Apple ID and the exact same app version. Even stranger: when using the TestFlight version of the app, again everything is working correctly even on the users iPhone.
I took a look at the device logs and here's what I found:
This is a snapshot of the users iPad. As you can see
products are found and listed correctly
storekitd seems to find and return products in receipt with the correct identifier
we get the correct information and are able to restore the correct purchase
14:48:17.032895+0200 Runner flutter: Found id: de.BUNDLEID.01, title: TITLE 1, price: €29.99
14:48:17.032922+0200 Runner flutter: Found id: de.BUNDLEID.bundle, title: TITLE Gesamtpaket, price: €59.99
14:48:17.032975+0200 Runner flutter: Found id: de.BUNDLEID.02, title: TITLE 2, price: €29.99
14:48:17.033001+0200 Runner flutter: Found id: de.BUNDLEID.extension, title: TITLE Plus, price: €9.99
14:48:20.656702+0200 storekitd [70D5C079]: Found 2 products in receipt with ID de.BUNDLEID.bundle
14:48:20.667793+0200 Runner flutter: Called purchaseListener (purchaseDetailsList: 1)
14:48:20.667838+0200 Runner flutter: Purchase restored
14:48:20.667869+0200 Runner flutter: Unlock permission TITLE_1
14:48:20.667892+0200 Runner flutter: Update TITLE_1 with true
14:48:20.672199+0200 Runner flutter: Unlock permission TITLE_2
14:48:20.672243+0200 Runner flutter: Update TITLE_2 with true
14:48:20.677849+0200 Runner flutter: Unlock permission TITLE_3
14:48:20.677897+0200 Runner flutter: Update TITLE_3 with true
14:48:20.679079+0200 Runner flutter: Calling completePurchase...
Same exact behavior can be observed on the users iPhone when running the TestFlight version of the app.
However, running the app from the Apple App Store on the users iPhone (same Apple ID, same OS and app version), the log looks like this:
14:23:26.150484+0200 Runner flutter: Found id: de.BUNDLEID.bundle, title: TITLE Gesamtpaket, price: €59.99
14:23:26.150513+0200 Runner flutter: Found id: de.BUNDLEID.02, title: TITLE 2, price: €29.99
14:23:26.150619+0200 Runner flutter: Found id: de.BUDNLEID.extension, title: TITLE Plus, price: €9.99
14:23:26.150657+0200 Runner flutter: Found id: de.BUNDLEID.01, title: TITLE 1, price: €29.99
14:23:27.125353+0200 dasd com.apple.icloud.searchpartyd.ProductInfoManager:C25423:[ (name: Thundering Herd Policy, policyWeight:
14:23:27.376336+0200 storekitd [Client] (Runner) Initialized with server Production bundle ID de.ds-infocenter.guk and request bundl
14:23:27.390026+0200 storekitd AMSURRequestEncoder: (7BA6012D] Encoding request for URL: https://mzstorekit.itunes.apple.com/inApps/
14:23:27.984831+0200 storekitd [7BA6012D]: Found 2 products in receipt with ID de.BUNDLEID.bundle
14:23:27.990235+0200 Runner flutter: Called purchaseListener (purchaseDetailsList: 0)
14:23:27.990271+0200 Runner flutter: Purchase details list is empty!
StoreKit seems to return the same exact products but for some reason the purchaseDetails list seems to be empty this time.
Here is the code responsible for restoring the purchases. Nothing fancy going on here if you ask me.
@override
void initState() {
super.initState();
db = context.read<Database>();
inAppPurchase = InAppPurchase.instance;
inAppPurchase.purchaseStream.listen(
purchaseListener,
onError: (error) {
print('Purchase stream error: $error');
showErrorDialog();
},
cancelOnError: true,
);
queryProductInformation().then((value) {
if (value == null) {
print('value in queryProductInformation is null!');
updateProcessing(false);
return;
}
setState(() {
for (var details in value.productDetails) {
products[details.id] = details;
}
});
updateProcessing(false);
});
}
Future<void> restorePurchases() async {
updateProcessing(true);
await inAppPurchase.restorePurchases();
}
void purchaseListener(List<PurchaseDetails> purchaseDetailsList) async {
print(
'Called purchaseListener (purchaseDetailsList: ${purchaseDetailsList.length})');
if (purchaseDetailsList.isEmpty) {
print('Purchase details list is empty!');
updateProcessing(false);
return;
}
for (var purchaseDetails in purchaseDetailsList) {
switch (purchaseDetails.status) {
case PurchaseStatus.purchased:
print('Purchase successful: ${purchaseDetails.productID}');
completePurchase(purchaseDetails.productID);
break;
case PurchaseStatus.canceled:
print('Purchase was canceled');
updateProcessing(false);
break;
case PurchaseStatus.restored:
print('Purchase restored');
completePurchase(purchaseDetails.productID);
break;
case PurchaseStatus.pending:
print('Purchase pending');
break;
case PurchaseStatus.error:
print('Purchase error');
showErrorDialog();
break;
}
print('Calling completePurchase...');
await inAppPurchase.completePurchase(purchaseDetails);
}
}
Could this be an issue on Apples API or flutters in_app_purchase package?
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect
Tags:
StoreKit
In-App Purchase
TestFlight
App Store Receipts
有一个用户反馈7月8日充值了3笔后一直无法发起新的购买,总是提示已经购买。我们查了是之前的交易无法结束,我们使用StoreKit2,已经调用await transaction.finish()成功结束交易了,但是每次发起新支付时,Transaction.unfinished还会返回之前已完成的交易信息。
是设备或AppleID的问题么?用户尝试了重启设备、重新登录AppleID都没用。有什么办法解决呢?
用户无法结束的苹果交易id为:200002703899379、200002703900716、200002703902023。
A user reported that after making 3 purchases on July 8th, they have been unable to initiate new purchases, always receiving a prompt that the item has already been purchased. Upon investigation, we found that the previous transactions couldn't be finalized. We use StoreKit2 and have successfully called await transaction.finish() to end the transactions. However, every time a new payment is initiated, Transaction.unfinished still returns information about the previously completed transactions.
Could this be an issue with the device or Apple ID? The user has tried restarting the device and re-logging into their Apple ID, but these attempts were unsuccessful. Is there any way to resolve this?
The Apple transaction IDs that the user is unable to finalize are: 200002703899379, 200002703900716, 200002703902023.
The question is related to getting rejected by Apple when the app does only have Subscriptions but no In-App Purchases. My understanding is that an in-app purchase is consumable or non-consumable as that's how the UI on appstoreconnect shows it. My app has 3 tier subscription, paid monthly, and that's it. But "We are unable to complete the review of the app because one or more of the in-app purchase products have not been submitted for review." Which I have none?
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect
Tags:
Subscriptions
In-App Purchase
Hi all, Our app has been rejected several times without any clear explanation of what we need to do.
The latest rejection reason is as follows:
The app accesses digital content purchased outside the app, such as Tracker data plans, but that content isn't available to purchase using in-app purchase. Apps must use in-app purchase to unlock features or functionality within the app. Apps on the United States storefront may include buttons, external links, or other calls to action to direct users to payment mechanisms other than in-app purchase.
Next Steps
The paid digital content, services, or subscriptions included in or accessed by your app must be available for purchase in the app using only in-app purchase.
As noted above, apps on the United States storefront may include buttons, external links, or other calls to action to payment mechanisms other than in-app purchase. To learn more about the recent changes to the App Review Guidelines, see the News post on Apple Developer.
We plan to implement payments outside of IAP, and here is the business scenario of our app:
Our app is designed to control an external hardware device. However, the device has a built-in SIM card, so to use the device, a data plan must be activated for it to function properly. These data plans are used to pay mobile network operators.
Different data plans incur different fees and activate different hardware features of the device.
In addition, since the hardware device will only be linked to the app after successful activation, the control buttons in the app for managing the hardware remain disabled until activation is complete.
Therefore, we believe using non-IAP payments is justified under Guideline 3.1.4 – Hardware-Specific Content:
I have repeatedly explained these points to the App Review team, but they still rejected the submission. I have asked multiple times which specific details are considered violations of 3.1.1, but they have not provided any concrete explanation. They also have not clarified whether 3.1.4 is deemed inapplicable in our case.
Therefore, I am reaching out here for help. Thank you very much.
We are facing a serious issues with in app purchases in our app.
We offer 3 IAP: auto-renewable subscription 1W, auto-renewable subscription 1Y, non-consumable one-time purchase (LifeTime access)
In our case 90-95% of transactions fail and we mostly get SKError code=2 .
Sometime purchase fails several times for the same user so it’s very hard to believe that user intentionally cancels transaction for the same product 4 or even 5 times in a row.
It happens regardless iOS version, device model, our app version.
We've checked multiple threads with the same issue but coudn't find any solution.
We do not offer any promotions, product identifiers are valid... Some users are able to make a purchases without any issues.
We are trying to develop a coupon/offer code module where our app users can avail a free trail offer for 2 months period after applying the code. We already had a subscription module with monthly & yearly subscriptions with 7 day free trial period. Now, we want to implement a offer/coupon module, where, a user can either select monthly or yearly subscription, and upon entering the offer/coupon code, they will get 2 months free trial (or) a discount on the chosen subscription. (this will overwrite the existing 7 day free trial).
We are confused on choosing the type of “offer/coupon” from AppStore connect. In App Store connect, we have introductory offers, promotional offer & Offer codes. Based on our requirements, we have done research and found that we cannot implement the offer code & promotional codes in the develop environment as there is no possibility to test in Sandbox environment. We observed that we need to push the app to App store and upon approval, we need to implement “offer/coupon” module.
Can some one please suggest or guide us on choosing the best solution for our requirement?
Thanks in advance.
Topic:
App & System Services
SubTopic:
Apple Pay
Tags:
Subscriptions
App Store Connect
In-App Purchase
Hello,
I am consistently receiving the error message "In-app purchases are not allowed on this device" whenever I try to make an in-app purchase on my iOS device. Despite following all the recommended solutions I could find online, the issue remains unresolved.
Here is a list of the steps I have already taken:
Checked Screen Time Settings:
I navigated to Settings > Screen Time > Content & Privacy Restrictions > iTunes & App Store Purchases.
I have confirmed that "In-App Purchases" is set to "Allow." I have also tried toggling this setting off and on again.
Signed Out & In of Apple ID:
I signed out of my Apple ID via Settings > [Your Name] > Media & Purchases, restarted the device, and then signed back in.
Restarted the Device:
I have force-restarted my device multiple times.
Updated iOS:
I have ensured my device is running the latest version of iOS (checked via Settings > General > Software Update).
Verified Payment Method:
I have confirmed that my payment method on file is valid and up-to-date.
Created a New Sandbox Account:
I also created a new Sandbox Tester account in App Store Connect and tested with it, but the result was the same.
Device Information:
Device Model: iPhone 15, iPhone 13
iOS Version: iOS 17.5, iOS 18
Even after performing all of these steps, the problem persists. Has anyone else encountered such a stubborn issue, or does anyone have a different solution I could try?
Thank you in advance for your help.
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
Subscriptions
StoreKit Test
StoreKit
In-App Purchase
I am trying to launch a PWA as an application on App Store, and got rejected cause of In-App Purchases. Application is about content generation and selling subscriptions for premium content. So thats why needed to implement In-App Purchases.
I have created wrapper via PWABuilder. And it is looking great so far, now my question is about How can I implement In-App Purchases in the bundle which is already created.
Any suggestions will be appreciated.
More clarification:-
I have that product running on Web right now, we have integrated Stripe for payment handling for subscriptions. If there is nothing we can do for In-App Purchases then we have to make purchases on website and then user will be able to experience the changes. We tried that, but then we got rejected for showing locked premium content on user's feed. Also can't show any CTA or Subscribe text or button.
Hello,
I am seeking clarification regarding App Store policy requirements for In-App Purchases (IAP) in the following scenario:
We are developing a wallet-based super app that allows users to access third-party storefronts (mini-apps) from within our app via embedded WebViews or similar in-app experiences. These storefronts are web-based and branded by external merchant partners.
In this model:
The mini-app storefront is embedded within our wallet app, but technically hosted externally by the merchant.
The user browses and selects digital goods (e.g., in-game currency, subscription vouchers, virtual items) from the merchant’s mini-app.
When the user proceeds to purchase, the payment is processed using a saved payment method from the wallet app, not through the App Store’s IAP system.
The digital goods are for use in a separate third-party app, not within the wallet app itself.
The wallet app does not directly fulfill or deliver the purchased digital goods.
We would like to confirm whether this flow is subject to IAP policy enforcement, or whether using our own wallet payment method is permitted in this context, given that:
The purchase is initiated within our app,
The goods are digital but are fulfilled in a third-party service or app,
And the wallet provider is not the developer of the destination app.
We are happy to provide more details or a flow diagram if needed.
Thank you
Over two months ago, one of my apps (My desktop web) was rejected during its first submission due to 2.1 - App Completeness. The reviewer said that the in-app purchase information was not visible, and that the purchase button showed “null(null)”. However, during both Xcode debugging and TestFlight testing, I was able to see all the in-app purchase information correctly.
After multiple rounds of communication with the reviewer, the app was finally approved — although I never figured out why. It might be because I submitted the in-app purchase for review first, and then submitted the app itself. In any case, it was eventually approved.
Now, I’m facing the exact same issue with my new app. The in-app purchase code is exactly the same (except for the Product IDs), but again, the reviewer cannot see the product information. The relevant line of code is very straightforward — I can successfully retrieve one product, but the reviewer sees zero:
self.products = try await Product.products(for: [productId])
I’ve already contacted DTS, and they said:
“You should make sure that StoreKit 2 effectively returns the display price and name of your product object and that these values still exist when you are about to display them.”
Yes, I’ve verified that — I can see the in-app purchase information. But the reviewer cannot.
I even scheduled a call and spoke with a reviewer based in San Jose, California. She confirmed that everything looks normal from the submission process side, and suggested I either check the app’s implementation again or continue working with DTS.
One more thing I noticed: throughout the entire review process, the in-app purchase product always remains in the “Waiting for Review” state, no matter how the app's status changes. The reviewer said that’s expected behavior.
At this point, I honestly don’t know what’s wrong anymore — I’m completely overwhelmed. Everything works perfectly in both Xcode and TestFlight, and I have no idea what else I can do to test or verify it.
Xcode and TestFlight screenshot:
Reviewer screenshot:
Appstore connect:
I implemented consumable in-app purchases in an iPhone app using ProductView().
When I tap the payment button in ProductView(), I am taken to the payment screen and once the payment is completed the next code seems to be executed, so there doesn't seem to be a problem, but if I tap the payment button in ProductView() again, the next code is executed without taking me to the payment screen.
This means that a single payment can be made multiple times.
Can someone help?
ProductView(id: "geminiOneMatch")
.productViewStyle(.compact)
.padding()
.onInAppPurchaseCompletion { product, result in
if case .success(.success(_)) = result {
// 課金が成功した場合の処理
gemini.addOneMatch(amount: 20)
popUpVM.geminiOneMatchPopUp = false
dataManageVM.generateRespons(locale: locale)
}
}
We scheduled for a price rise for July 3rd.
We have >90% of subscribers on a standard monthly subscription (without trials or offers), and we gave more than the requisite notice (we scheduled these on May 20).
We also chose in the price increase flow to apply the new price to existing subscribers.
On July 3rd, the price for new subscribers went up as expected.
However, we are still seeing all our renewals at the old price. My own subscription to the app renewed today (July 15th) - but at the old price. In my Settings app, I can see that the next renewal (August 15th) will be at the new price. I also haven't had any notifications/email from Apple about the rise (which should happen 27 days before the rise, so will likely happen for me on July 19th....but that should've been June 19th).
So it appears that while the new price will be applied to existing subscribers, it is happening a month after the scheduled price rise. Some of our customers are being contacted by Apple about the price rise...for August, when it should have already taken place.
Given that we scheduled this way more than 27 days ahead, why would the price rise for existing subscribers not take place at the planned date? Are there other reasons that are not documented? The only two reasons we can see are a) insufficient planning notice and b) trial periods being respected - neither of which apply here.
We can see significant cancellations from July 3rd in countries where customers have to opt-in for a price rise, primarily Germany. So it seems that the price rise definitely came into effect for our existing subscribers, causing opt-in cancellations, but the customers aren't actually paying the higher price for another cycle.
Any ideas?
Topic:
App Store Distribution & Marketing
SubTopic:
General
Tags:
Subscriptions
App Store Connect
In-App Purchase
We have some users who have upgraded to iOS 26 beta3. Currently, we observe that when these users make in-app purchases, our code calls [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; method, and we clearly receive the successful removal callback in the delegate method - (void)paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray<SKPaymentTransaction *> *)transactions. However, when users click on products with the same productId again, the method - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions still returns information about previously removed transactions, preventing users from making further in-app purchases.
I want to add in-app purchasing to my app, but I can't figure out what part of my workflow is wrong.
I created a product for my app in iTunes Connect (the product ID is com.mycompany.products.***) and it's in "Ready to submit" status.
I created a sandbox test user for this app.
I connected to iTunes on a real device using the sandbox AppleID.
I went back to XCode and added in-app purchasing to my app.
I turned on developer mode on the real device and logged in as the sandbox user.
I built the app and ran it on a real device (not the simulator).
I tried to get product information (com.mycompany.products.***) but nothing was returned.
In-app purchasing is registered in App Store Connect and the status is "Ready to submit".
The code only retrieves product information in a simple way, so I don't think there's a problem.
inAppPurchase.getProducts(["com.mycompany.products.***"]).then(console.log).catch(console.error);
But it only returns an empty array.
What could be wrong?
Any help would be much appreciated.
Hello,
Since updating to iOS 26 Beta 3, I’ve been experiencing an issue where transactions purchased through the normal in-app purchase flow continue to be reported as updated and unfinished—even after calling the finish() function. Please resolve this promptly.
We are seeking clarification on the behavior of App Store Server Notifications V2.
Summary
In our production environment, we received a notification with notificationType: DID_FAIL_TO_RENEW and subtype: GRACE_PERIOD. However, the gracePeriodExpiresDate field in the payload was null.
We understand this notification indicates that a user's subscription has entered a grace period. The null value for its expiration date is unexpected, and we are looking for an official explanation of this behavior and the correct way to handle it.
The Scenario
Here are the details of the notification we received:
Notification Type: DID_FAIL_TO_RENEW
Notification Subtype: GRACE_PERIOD
Environment: Production
Upon decoding the signedRenewalInfo JWS from the responseBodyV2, we found that the gracePeriodExpiresDate field inside the JWSRenewalInfoDecodedPayload was null.
The notificationUUID for this event was in the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
Our Implementation and its Impact
Our backend is designed to ensure service continuity during a grace period, as recommended in the documentation.
Current Logic:
Receive the DID_FAIL_TO_RENEW / GRACE_PERIOD notification.
Extract the gracePeriodExpiresDate.
Extend the user's subscription expiration date in our database to match this date.
Because the gracePeriodExpiresDate was null in this case, our logic failed, creating a risk of service interruption for the user.
Context and Investigation
We have performed the following checks:
App Store Connect Settings: We have confirmed that Billing Grace Period is enabled for the relevant subscription group.
Sandbox Environment: We have been unable to reproduce this scenario in the Sandbox.
User Context: We believe the user in this case was experiencing a failed payment when attempting to renew for the first time after a free trial period.
Questions
To ensure we handle this scenario correctly, we would appreciate clarification on the following points:
Conditions for Null: Under what specific conditions does a DID_FAIL_TO_RENEW notification with a GRACE_PERIOD subtype contain a null gracePeriodExpiresDate?
Expected Behavior: Is this null value an expected behavior for certain scenarios, such as the first failed renewal after a free trial?
Best Practice: If this is an expected behavior, what is the correct way to handle it? How should our backend interpret a null gracePeriodExpiresDate to ensure service continuity for the user?
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
Subscriptions
In-App Purchase
App Store Server Notifications
Hi everyone,
I’ve been struggling for days with a recurring issue in my iOS app build. The build fails with the following error:
Provisioning profile "iOS Team Provisioning Profile: com.myapp.bundleid" doesn't include the com.apple.InAppPurchase entitlement.
Here’s what I’ve already tried:
Created a new Bundle ID with correct capabilities (In-App Purchase, Push Notifications, Sign in with Apple).
Created a new provisioning profile manually from Apple Developer Console.
Used EAS CLI (Expo) and Xcode to regenerate all certificates and provisioning profiles.
Ensured that the In-App Purchase capability is enabled in the App ID (it's greyed out but enabled).
Made sure all subscriptions and products in App Store Connect are “Ready to Submit”.
Followed all steps from RevenueCat and Apple documentation.
Cleaned entitlements in .entitlements file and tried both and variations.
Tried building both locally and with EAS – same error every time.
Sent multiple tickets to Apple Developer Support, but no helpful reply yet.
Extra Notes:
I'm using react-native-purchases and RevenueCat, already integrated and working before this started.
The error began randomly; before that, I was able to build successfully with in-app purchases.
Even creating a completely fresh app from scratch results in the same entitlement missing error.
Has anyone faced this exact problem where the provisioning profile fails to include com.apple.InAppPurchase, even though everything is correctly set up?
Any help or insights would be greatly appreciated.
Thanks in advance!