I've recently published an app, and while developing it, I could always get consistent entitlements from Transaction.currentEntitlements. But now I see some inconsistent behaviour for a subscribed device in the AppStore version. It looks like sometimes the entitlements do not emit value for the subscriptions.
It usually happens on the first couple tries when the device goes offline, or on the first couple tries when the device goes online. But it also happens randomly at other times as well.
Can there be a problem with Transaction.currentEntitlements when the connectivity was just changed?
Of course my implementation may also be broken. I will give you the details of my implementation below.
I have a SubscriptionManager that is observable (irrelevant parts of the entity is omitted):
final class SubscriptionManager: NSObject, ObservableObject {
private let productIds = ["yearly", "monthly"]
private(set) var purchasedProductIDs = Set<String>()
var hasUnlockedPro: Bool {
return !self.purchasedProductIDs.isEmpty
}
@MainActor
func updatePurchasedProducts() async {
var purchasedProductIDs = Set<String>()
for await result in Transaction.currentEntitlements {
guard case .verified(let transaction) = result else {
continue
}
if transaction.revocationDate == nil {
purchasedProductIDs.insert(transaction.productID)
} else {
purchasedProductIDs.remove(transaction.productID)
}
}
// only update if changed to avoid unnecessary published triggers
if purchasedProductIDs != self.purchasedProductIDs {
self.purchasedProductIDs = purchasedProductIDs
}
}
}
And I call the updatePurchasedProducts() when the app first launches in AppDelegate, before returning true on didFinishLaunchingWithOptions as:
Task(priority: .high) {
await DependencyContainer.shared.subscriptionManager.updatePurchasedProducts()
}
You may be wondering maybe the request is not finished yet and I fail to refresh my UI, but it is not the case. Because later on, every time I do something related to a subscribed content, I check the hasUnlockedPro computed property of the subscription manager, which still returns false, meaning the purchasedProductIDs is empty.
You may also be curious about the dependency container approach, but I ensured by testing multiple times that there is only one instance of the SubscriptionManager at all times in the app.
Which makes me think maybe there is something wrong with Transaction.currentEntitlements
I would appreciate any help regarding this problem, or would like to know if anyone else experienced similar problems.
Subscriptions
RSS for tagGive users access to content, services, or premium features in your app on an ongoing basis with subscriptions, a type of in-app purchase.
Posts under Subscriptions tag
200 Posts
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I'm using TestFlight to test an app with payment/subscription functionality. I created sandbox accounts in AppStore Connect accordingly to be able to test the subscriptions. I'm logged in with the sandbox account.
When I try to subscribe in the App the wrong account (this is my actual real AppleID) is used for the subscription although it is recognized that this is just a sandbox subscription.
I tried:
logging off/on into the sandbox account
creating a totally new sandbox account
trying to trigger the payment with no logged in sandbox account
The result is always: in the payment popup it is stated that the purchase account will be my original AppleID and not a sandbox account.
How can I switch the accounts? Is this a bug at Apple's side somehow?
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
Subscriptions
TestFlight
In-App Purchase
StoreKit
The sample code provided in https://developer.apple.com/wwdc21/10114 doesn't appear to call finish() on unverified transactions, and I haven't been able to find any documentation regarding what to do with unfinished transactions. However, Apple has always emphasized the importance of finishing transactions, and since a transaction object is provided even with the unverified state, I'd love some guidance!
Hi! I’m new in programming apps for Apple Store and I’m creating my first app. I already send my for review but I get an answer of problems with the subs flow. If there’s anyone who can help me fix this problem and implement my subscriptions in my app and test it out I would be thankful, I want the flow work like in the image!
Hello,
I am attempting to enroll in the Apple Developer Program and have already added $100 to my Apple account. However, every time I try to proceed with the enrollment, I encounter an error.
I have reached out to Apple Support multiple times, but the issue remains unresolved. Each time, the case is escalated to a senior representative, yet no clear solution has been provided. It feels as though the issue is being passed back and forth without accountability.
Furthermore, I’m receiving conflicting guidance—Apple.com refers me to developer.apple.com, and vice versa—leaving me stuck without a resolution.
I would appreciate your urgent assistance in identifying and resolving this issue so I can complete my enrollment.
Best regards,
Gulf Now
Topic:
Developer Tools & Services
SubTopic:
Apple Developer Program
Tags:
Subscriptions
Accounts
App Store
App Store Connect
In my understanding, with the latest court ruling in the US, iOS apps may decide to support web-based payments for subscriptions and in-app purchases. However, are we allowed to exclusively support web-based payments and not implement StoreKit at all?
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
Subscriptions
StoreKit
App Store Connect
In-App Purchase
Hello,
I'm encountering an issue when trying to use the subscriptionGroupLookups endpoint in the App Store Connect API.
Despite having the correct setup, I continue to receive a 404 NOT FOUND error when making requests to:
GET https://api.appstoreconnect.apple.com/v1/subscriptionGroupLookups
Here is the current state of my environment:
I am the Account Holder of the App Store Connect account
The App Store Connect API key has been successfully created
I have the correct Key ID, Issuer ID, and .p8 private key
I can authenticate and access the apps and subscriptionGroups endpoints
However, the subscriptionGroupLookups endpoint always returns:
{
"errors": [
{
"status": "404",
"code": "NOT_FOUND",
"title": "The specified resource does not exist"
}
]
}
I suspect that LookUp Keys (UUIDs) have not been assigned to our subscription groups, even though they were created and are active in App Store Connect.
There is no “Request Access” button visible under the Integrations tab (as mentioned in Apple support instructions), and my keys appear under “App Store Connect API” > “Keys” as active.
Questions:
How can I ensure that LookUp Keys are assigned to my subscription groups?
Is there a way to trigger this manually or via support?
Has anyone successfully resolved this?
Any advice or experience would be greatly appreciated.
Thank you!
Hello,
Does a customer may redeem the same promotional offer multiples times? For example, get 25% of our app subscription for one year, and then we give the customer the same promotional offer for a second year at 25% off?
Thank you
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect
Tags:
Subscriptions
In-App Purchase
In my APP for now contains IAP for one time purchase.
By adding to APP auto-renewable subscriptions can I ask from customers(that purchased on App Store and IAP ) to purchase subscription.
For customers that purchase IAP, ask to purchase subscription after year from IAP was purchased.
Topic:
App Store Distribution & Marketing
SubTopic:
General
Tags:
Subscriptions
StoreKit
In-App Purchase
App Store Receipts
Hi All,
We are trying to integrate Promotional Offer in our app, We have a React Native app and are using react-native-iap for handling our in app purchases, as per the documentation we are generating signature in our BE and passing the proper details to the function as well, but for subscription request which have offer applied we are getting the apple pop up properly as well with offer details but when trying to subscribe it gives us SKErrroDomain: 12,
for subscription without applying offer the subscription goes through but when we apply the offer we get the above error.
Our app is currently in Development Stages and has not been sent for review sam for our subscription plans as well.
Please let me know what could be the probable cause for this and help us resolve the issue.
This is the code snippet of ours for the front end :
export const buySubscription = async (subscriptionData: any) => {
try {
if (subscriptionData.offer_id) {
const response = await getSubscriptionSignature(
subscriptionData.productId,
subscriptionData.offer_id,
);
const offerData = response?.data;
const offer = {
identifier: offerData?.offer_id,
keyIdentifier: offerData?.key_id,
nonce: offerData?.nonce,
signature: offerData?.signature,
timestamp: Number(offerData?.timestamp),
};
await requestSubscription({
sku: subscriptionData.productId,
withOffer: offer,
});
} else {
await requestSubscription({ sku: subscriptionData.productId });
}
} catch (err) {
logger.error('Subscription error: ' + JSON.stringify(err));
throw err;
}
};
and
from my python Backend which generates the signature:
def generate_signature(self, product_id: str, offer_id: str) -> dict:
"""
Generate signature for Apple StoreKit promotional offers.
Args:
product_id: The product identifier from App Store Connect
offer_id: The promotional offer identifier
Returns:
dict: Contains signature and required metadata
Reference: https://developer.apple.com/documentation/storekit/in-app_purchase/original_api_for_in-app_purchase/subscriptions_and_offers/implementing_promotional_offers_in_your_app
"""
try:
# Generate UUID without dashes and use as nonce
nonce = str(uuid.uuid4())
timestamp = get_current_time_ms() # milliseconds
# Create the payload string in exact order required by Apple
payload_components = [
self.bundle_id, # App Bundle ID
self.key_id, # Key ID from App Store Connect
product_id, # Product identifier
offer_id, # Promotional offer identifier
nonce, # UUID without dashes
str(timestamp) # Current timestamp in milliseconds
]
payload_str = "\u2063".join(payload_components) # Use Unicode separator
logger.debug(f"Signing payload: {payload_str}")
# Create SHA256 hash of the payload
digest = hashes.Hash(hashes.SHA256())
digest.update(payload_str.encode('utf-8'))
payload_hash = digest.finalize()
# Sign the hash using ES256 (ECDSA with SHA-256)
signature = self.private_key.sign(
data=payload_hash,
signature_algorithm=ec.ECDSA(hashes.SHA256())
)
# Encode signature in base64
signature_b64 = base64.b64encode(signature).decode('utf-8')
logger.info(f"Generated signature for product {product_id} and offer {offer_id}")
return {
"key_id": self.key_id, # Changed to match Apple's naming
"nonce": nonce, # UUID without dashes
"timestamp": timestamp, # As integer
"signature": signature_b64, # Base64 encoded signature
"product_id": product_id, # Changed to match Apple's naming
"offer_id": offer_id # Changed to match Apple's naming
}
except Exception as e:
logger.error(f"Failed to generate signature: {str(e)}")
raise HTTPException(
status_code=500,
detail=f"Failed to generate signature: {str(e)}"
)
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
Subscriptions
StoreKit
App Store Connect
Advanced Commerce API
works perfectly on android but doesn't work at all on IOS and i have used the same bundle id and product ids on both stores.
The error that i get on IOS is : "IAP initialization failed: NoProductsAvailable - No Product returned from store"
Here are the things that i've done:
Created an App ID on the apple developer portal with the correct capabilities
I have enabled the correct capabilities on the xcode project Unity Framework is embed and signed, Storekit (do not embed)
In singin and capabilities in-app purchases is there
I am using testflight to submit the app with a distribution certificate that appears to be valid
I've checked the the bundle identifier and it's the same everywhere (unity project, xcode project, App ID)
All of the products are cleared for sale and are in the status "ready to submit"
I always uninstall the old app version before testing the new one
My banking updates are still processing does this effect TestFlight IAP
Paid Apps Agreement is in Pending User Info state does this effect also
I still haven't filled out the tax forms, so I'm wondering if I need to complete them before my app's in-app purchases (IAPs) work in TestFlight.
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
Subscriptions
In-App Purchase
Apple Unity Plug-Ins
Currently, over the xcode environment to do the testing of product subscriptions through appstore are working correctly using the storeKit.
When deployed in testflight to do the testing over the integration environment, the store response times are being excessively high, in excess of 20 minutes.
This behavior is not replicated on Xcode, and is happening on recent versions uploaded to testflight, as earlier versions that were already tested and are currently in production.
In addition the communication between the appstore webhook and the BE is also failing in this environment.
It is being blocked to generate any test to be able to launch to production.
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
Subscriptions
Developer Tools
App Store
StoreKit
My IAP and Subscriptions were rejected during review.
I went to see what the problem was and it was due to my localization descriptions.
So I removed Enlgish (Canada) no problem, created a new one, save.
Then there was only one left which is English (US) but when I try to remove this last one, I get an error saying 'There was an error with deleting the localization. Please try again later.' when I try to delete it.
This is happening for all my subscription and iap items, as well as the subscription group localization.
Seems that when there are multiple rejected localization items in a table, you aren't able to delete the last rejected row regardless of language.
Anyone else experience this? Any way to get around it? I would prefer not deleting my entire subscription group and iaps.
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect
Tags:
Subscriptions
App Store
In-App Purchase
Debugging
Hi, thanks for reading my question. I need help with some odd behaviour with product.purchase() not triggering a confirmation dialog after a subscription has expired and trying to purchase it again. Seeing this in iOS 16.2 and 15.7.2 (haven't tried any other versions) on actual devices, not in simulator.
I'm using a sandbox user on the sandbox environment (not using the local store kit config file testing option).
Using a newly created sandbox user, first subscription purchase goes through just fine, dialog box pops up, login with sandbox user, get confirmation of purchase and then Transaction.currentEntitlements has one item as expected. It auto renews for 12 times (each time Transaction.currentEntitlements contains the correct results) and then expires, as expected for sandbox. Transaction.currentEntitlements is then also empty, as expected. All good so far.
Now I want to test purchasing it again...Call product.purchase() again to renew/start a new subscription and nothing happens, no confirm purchase dialog box pops up at all. The purchase function simply exits BUT returns success (as in the following gets called) but in self.updatePurchasedProducts(), Transaction.currentEntitlements is empty.
case let .success(.verified(transaction)):
// Successful purchase
await transaction.finish()
await self.updatePurchasedProducts()
if I instead go to Settings->App Store->Sandbox User-> Manage Subscriptions and renew the subscription there, instead of in my app, then Transaction.currentEntitlements has a new entry and all is good again.
Alternatively, if I create yet another new sandbox user and logout of the old one I was using, I am once again able to purchase from within the app, so .purchase() once again works as normal.
Is there something I am missing about expired subscriptions and trying to purchase them again in the app? Is this a sandbox issue and in production I'll have no problem?
The sandbox user has purchasing enabled in Settings->App Store.
I've also tried calling AppStore.sync() (which is in my "Restore Purchase" button) before calling product.purchase() after the subscription stops renewing, expires and this issue comes up, doesn't resolve it.
Also have a less important question, the initial call to product.purchase(), the one that works as expected, has a bit of a delay before the confirmation dialog pops up, a few seconds, which will probably result in the user clicking the buy button again thinking it didn't work. Is a bit of a delay normal for sandbox? Will it be ok in production? When it fails, and I have to renew in Settings->AppStore->Sandbox user, there's also a bit of a delay after I return to my app, 5-15 or so seconds, before the transaction observer fires and currentEntitlements is checked again, is there a way to reduce this delay?
Thank you!
Colin
@MainActor
class IAPManager: NSObject, ObservableObject {
// removed other functions.....
func purchase(_ product: Product) async throws {
let result = try await product.purchase()
switch result {
case let .success(.verified(transaction)):
// Successful purchase
await transaction.finish()
await self.updatePurchasedProducts()
case let .success(.unverified(_, error)):
break
case .pending:
break
case .userCancelled:
break
@unknown default:
break
}
}
func updatePurchasedProducts() async {
for await result in Transaction.currentEntitlements {
guard case .verified(let transaction) = result else {
continue
}
if transaction.revocationDate == nil {
self.purchasedProductIDs.insert(transaction.productID)
} else {
self.purchasedProductIDs.remove(transaction.productID)
}
}
}
}
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
In-App Purchase
StoreKit
StoreKit Test
Subscriptions
When I test subscibe in sandbox,IOS says this transaction need to request parent’s approval。But this is a sandbox account,it don't have any family members
I'm encountering an issue with in-app purchases in the Sandbox testing environment for our app Answify. Our subscription products were approved on April 9th, 2025, but they are not available when testing in the Sandbox environment.
Problem Description
When using the Product.products(for:) method from StoreKit 2 to request our approved in-app purchase products, an empty array is returned. This happens both with our main app flow and with a direct test that specifically requests the products.
Environment Details
App: Answify (Bundle ID: com.answify.Answify.iphone)
Build: 71 (available in TestFlight)
iOS: 18.4 (iPhone)
Testing date: April 21, 2025
Sandbox accounts tested:
purchase2 [at] it-xpert.be
sandbox [at] it-xpert.be (recently created)
Steps to Reproduce
Login with a Sandbox test account
Launch the Answify app
Navigate to the subscription screen
The app attempts to load products via Product.products(for:), but receives an empty array
The app falls back to displaying dummy products with an error message
Attempted Solutions
I've verified the following:
Correct Sandbox Environment: The app correctly identifies it's running in the Sandbox environment (confirmed via both app logs and UI indicators).
Correct Sandbox Account: I've confirmed in iOS Settings that I'm using the Sandbox account (purchase2 [at] it-xpert.be). I've also tested with a different Sandbox account (sandbox [at] it-xpert.be) with the same results.
Approved Products: All products have been approved since April 9th, 2025, and show as "Ready to Submit" in App Store Connect.
Product IDs: I've triple-checked that the product IDs match exactly between the app and App Store Connect.
Manual Transaction Testing: I've attempted to manually test transactions through the iOS Settings > Developer menu with the product ID "com.answify.subscription.personal" and lot ID "answify_subscriptions". This test also fails with "The product or lot identifier provided is not valid" error.
Local StoreKit Testing: The products load correctly and purchases work when using a local StoreKit configuration file, confirming our implementation is correct.
Relevant Code
Here's the code we use to fetch products:
// In StoreManager.swift
func loadProducts() async {
print("DEBUG: Starting product loading process from App Store")
isLoading = true
error = nil
do {
// 1. Fetch pricing packages from backend
var pricingPackages: [PricingPackage] = []
do {
print("DEBUG: Fetching pricing packages from backend API")
pricingPackages = try await fetchPricingPackages()
print("DEBUG: Successfully received \(pricingPackages.count) pricing packages from backend")
} catch {
print("DEBUG: Error fetching pricing packages from backend: \(error)")
pricingPackages = createHardcodedPricingPackages()
print("DEBUG: Using \(pricingPackages.count) hardcoded pricing packages as fallback")
}
// 2. Load products from the App Store
let productIdentifiers = Set(pricingPackages.map { $0.inAppPurchaseID })
print("DEBUG: Requesting \(productIdentifiers.count) products from App Store with IDs: \(productIdentifiers)")
do {
// Attempt to load products
let storeProducts = try await Product.products(for: productIdentifiers)
print("DEBUG: Successfully loaded \(storeProducts.count) products from App Store")
// Rest of implementation...
} catch let storeKitError {
print("DEBUG: StoreKit error when loading products: \(storeKitError.localizedDescription)")
// Fallback to dummy products...
}
} catch {
// Error handling...
}
}
// Direct StoreKit test (also returns 0 products)
func testStoreKitDirectly() async {
let productIDs = Set([
"com.answify.subscription.personal",
"com.answify.subscription.personal.yearly",
"com.answify.subscription.startup",
"com.answify.subscription.startup.yearly",
"com.answify.subscription.business_monthly"
])
do {
let products = try await Product.products(for: productIDs)
print("DEBUG: Directly received \(products.count) products from StoreKit")
} catch {
print("DEBUG: Direct StoreKit test error: \(error.localizedDescription)")
}
}
Console logs
Here is the relevant console output:
DEBUG: Requesting 5 products from App Store with IDs: ["com.answify.subscription.startup.yearly", "com.answify.subscription.personal.yearly", "com.answify.subscription.startup", "com.answify.subscription.personal", "com.answify.subscription.business_monthly"]
DEBUG: Successfully loaded 0 products from App Store
DEBUG: No products found in the App Store. Switching to dummy products.
DEBUG: Creating dummy products since App Store products couldn't be loaded
DEBUG: Running direct StoreKit product retrieval test
DEBUG: Directly requesting 5 products from StoreKit
DEBUG: Directly received 0 products from StoreKit
Question
Is there any additional step required after product approval to make them available in the Sandbox environment? Could there be an issue with the App Store Sandbox environment itself?
Any guidance would be greatly appreciated. This issue is blocking our testing and release process.
Thank you!
We have uploaded our app on 17th Apr'25 on app store and status showed "Ready for distribution". However our in-app purchases are still showing "Waiting for Review". It has been 4 days since our app is live on app store but we are unable to make the in-app purchases.
Please let us know what steps are we supposed to do on this front
Hi all,
I’m testing Subscription in my Flutter app on a real iOS device (iPhone 16 Pro with iOS 18) via TestFlight. I’ve set everything up as required, but I still get this error:
flutter: Found products: []
If everything works perfectly when StoreKit configuration is used in Xcode, but not via TestFlight.
All my Subscriptions are approved with the same ID.
My developer account pending for more that 4 days.
When I login to http://developer.apple.com, it show the following message:
Purchase your membership.
To continue your enrollment, complete your purchase now.
Your purchase may take up to 48 hours to process.
I have already paid the membership fee and got the E-invoice from apple.
Could anyone help to solve this problem?
I would like to share some feedback regarding the current App Store pricing model, particularly around subscriptions.
Over time, there has been a noticeable shift from one-time purchases to subscription-based pricing for nearly all types of apps and games. While subscriptions make sense for content-driven services such as streaming (movies, music, books, etc.), they often feel forced or excessive when applied to standalone apps or games that previously used a one-time purchase model. Many users view this as an abuse of the subscription system, leading to frustration and distrust.
As a developer, I also understand the challenge of sustaining revenue, especially when major updates require significant time and resources. One-time purchases often don’t reflect the long-term value an app may provide or the cost of continued development.
That said, I believe a more balanced approach would benefit everyone. I’d like to suggest the implementation of a major upgrade pricing model on the App Store. For example, when a developer releases a major new version of an app (e.g., 2.0, 3.0, etc.), they could offer:
A standard price for new users (e.g., $2.99)
A discounted upgrade price for existing users (e.g., $0.99)
This would allow developers to be fairly compensated for continued innovation while also respecting customers who have already supported the app. Subscriptions could then be more appropriately reserved for content-based services.
I believe this model would create a healthier ecosystem for both users and developers, encouraging more sustainable and transparent pricing practices.
Feedback Assistant : FB17281833
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect
Tags:
Subscriptions
App Store
StoreKit
App Store Connect