I'm using code similar to the following to conditionally show the SubscriptionStoreView and the .storeButton(.visible, for: .restorePurchases) modifier is used to allow the user to restore an existing subscription.
How can I listen for events that would allow me to close this view once the subscription is restored?
The .onInAppPurchaseCompletion closure does not handle this and it also appears that listening for results in Transaction.currentEntitlements also doesn't handle the fact that a subscription is restored.
Any guidance on how to determine if the subscription has been restored would be greatly appreciated.
Finally, how can this be tested effectively in both TestFlight and in Xcode with the simulator.
if subscriptionManager.subscription == .none {
SubscriptionStoreView(groupID: "1234567") {
SubscriptionMarketingView(transparency: false)
.containerBackground(for: .subscriptionStoreFullHeight) {
GradientBackground()
}
}
.backgroundStyle(.clear)
.storeButton(.visible, for: .restorePurchases)
.storeButton(.visible, for: .redeemCode)
.onInAppPurchaseCompletion { product, result in
Task {
await subscriptionManager.entitlements()
}
}
}
StoreKit
RSS for tagSupport in-app purchases and interactions with the App Store using StoreKit.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Hi everyone,
I’m seeing a strange behavior with StoreKit 2 and I’d like to know if anyone else experienced this.
My subscription group “ROTA Premium” (Monthly + Annual) is currently Waiting for Review in App Store Connect.
What works
In Xcode’s StoreKit sandbox, everything loads correctly:
Products appear
Trial starts
Purchases work
What doesn’t work
In TestFlight and App Review, StoreKit 2 returns zero products, so my paywall shows:
“No subscription options found.”
There are:
No geo restrictions
No backend
No VPN/IP filtering
Paid Apps Agreement is accepted
App Review said the device was online, but couldn’t give technical help.
My question
Has anyone seen StoreKit 2 fail to load subscription products when the subscription group is still in Waiting for Review?
Do subscription groups need to be reviewed together with the app version for StoreKit 2 to return them in TestFlight/App Review?
Any advice would be appreciated!
Thanks.
Greetings!
I was reviewing the documentation for the Apple Store Server Notification v1 APIs and saw the deprecation notice. We are currently unable to migrate to v2 in the near future. With that in mind, I want to know if there were any plans to shut off v1, and if so, was there any timeline we could expect? Thank you in advance.
Reference: https://developer.apple.com/documentation/appstoreservernotifications/app-store-server-notifications-version-1
Trying to test IAP in sandbox. I created the test group and tester accounts. Accepted the invite downloaded the app. Signed into to sandbox in settings with the tester account. In app the purchases are failing and throwing my catch error message product couldn't be found. I decided to test it from settings/ sandbox/ manage/ initiate purchase/ but I've been getting "can't complete transaction. Something went wrong, ant this transaction couldn't be completed. Try again later" since last week. I reached out to dev support over the phone then email and they couldn't or wouldn't provide assistance. I asked my senior at work she took a look at it and confirmed I created the IAP correctly and that my sandbox account could make test purchases in apps she make but couldn't get mine to work. The storekit test work fine in xcode I just don't know what to do now.
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.
Hi everyone,
I’m implementing subscriptions using StoreKit v2, and I’ve noticed a behavior change starting with iOS 26.1.
I’d like to ask if anyone else has experienced the same issue.
■ Issue
Immediately after purchasing a new subscription,
the value of auto_renew_status (or autoRenewStatus) returned in the receipt is 0 (auto-renew OFF).
This issue occurs on iOS 26.1.
On iOS 26.0 and earlier, the same parameter returned 1 (auto-renew ON) right after purchase.
Sometimes, after executing a “restore” operation, the value changes to 1 later.
Since we’ve been using this parameter to determine whether a user’s subscription is active or not,
the current behavior is causing some difficulties on our end.
■ Questions
Has anyone else observed this issue (where autoRenewStatus is 0 immediately after purchase on iOS 26.1 or later)?
How are you handling or working around this behavior in your implementation?
If autoRenewStatus is unreliable, we’re considering determining the subscription state based on receipt fields instead.
Would this approach be reasonable?
"status" is 1 (indicates active subscription)
"expire_time" is in the future
"deleted_at" is null
If anyone has encountered the same behavior or knows of any Apple-recommended implementation approach,
I’d really appreciate your insights.
Thank you! 🙏
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.
In a recent update to developer news, Apple posted more details about compliance tools for the new laws coming into effect in Texas on Jan 1.
https://developer.apple.com/news/?id=2ezb6jhj
It is not explicitly stated in the news update or documentation but when the new RESCIND_CONSENT notification is sent to the developer, what happens on the child account devices? Does the app just disappear. Does the developer need to take any action in the App itself?
https://developer.apple.com/documentation/appstoreservernotifications/notificationtype
Thanks,
Eric
Topic:
App & System Services
SubTopic:
StoreKit
users download app with Streamlined Purchasing ,but the logic of checking subscription doesn't work. there the code:
func checkSubscriptionStatus() async {
for await entitlement in Transaction.currentEntitlements {
guard case .verified(let transaction) = entitlement else { continue }
if transaction.productID == monthlyProductID || transaction.productID == yearlyProductID {
if transaction.revocationDate == nil && !transaction.isUpgraded {
let activeSubscribed = transaction.expirationDate ?? .distantFuture > .now
if activeSubscribed {
hasActiveSubscription = activeSubscribed
// other operation
}
}
}
}
}
I have setup offer codes and subscriptions for users to purchase, when a user signs up using an offer code outside of the app the offer code does not save into my database where the subscriptions are saved
the transaction is successful and validated by store kit but I cant see that that user used an offer code - an example
https://apps.apple.com/redeem/?ctx=offercodes&id=6744338284&code=ASKDOM
I then setup an edge function in supabase to retrieve the data that store kit sends back and im not sure where to find the offer code as it still doesnt save
is there an internal apple reference that they use as apposed to the users offer code i.e offer code askdomSA = P3050 for example
how can Identify if an offer code was used
thank you
A customer of mine signed up for a free trial. I got a apple server notification with notification type DID_RENEW. What does that mean? Does that mean that they will be charged the subscription price now?
Hi everyone.
I'm trying to use https://developer.apple.com/documentation/appstoreserverapi/get-transaction-info to retrieve order information. How can I get the refund status of an order through this API? Also, Apple's webhook notification for refunds includes fields like revocationReason and revocationType. Can these be retrieved through the API? I've noticed that some refund orders have these fields when retrieved using get-transaction-info api, but others don't. I don't know the reason for these differences. Could you please explain?
Thank you very much.
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
App Store Server Notifications
App Store Server API
Inquire the types of notifications that can occur in a SANDBOX environment
Hello, WWDC 2024 is trying to conduct a test to receive notifications related to ONE_TIME_CHARGE, CONNSUMPTION_REQUEST, CONMSUMPTION_INFO, REFUND, and REFUND_DECLINED as described in the example of purchasing consumables, but as a result of the continuous search, I found that it is difficult to occur except for
ONE_TIME_CHARGE.
So, in order to verify only the business logic as shown below, we are testing only the business logic without actually calling the API after purchasing the test and saving the signaled Payload that we received in response to ONE_TIME_CHARGE. Can we actually request a refund for the test purchase and receive the corresponding notification and actually send the response?
public void handleSignedNotification(String signedNotification) throws Exception {
ResponseBodyV2DecodedPayload payload = signedDataVerifier.verifyAndDecodeNotification(signedNotification);
NotificationTypeV2 type = payload.getNotificationType();
//For Apple Server Notification, only ONE_TIME_CHARGE notifications are enabled in the test environment, so for testing, change them as below to test whether they are running business logic
type = NotificationTypeV2.REFUND;
log.info("Apple NotificationType : {}", type);
switch (type) {
case CONSUMPTION_REQUEST:
handleConsumptionRequest(payload);
break;
case REFUND:
handleRefund(payload);
break;
case REFUND_DECLINED:
handleRefundDeclined(payload);
break;
// For other necessary notifications, just take a log
default:
log.info("Unhandled notification: {}", type);
}
}
Regarding the call of 'CONSUMPTION_INFO', which is the response of 'CONSUMPTION_REQUEST'
Is there a value that WWDC 2024 must include when sending CONMSUMPTION_INFO, which is the response to CONNSUMPTION_REQUEST described in the refund example? I'm going to call the API with only sample provision and consumption like the sample code you introduced in the video.
I was told to submit my refund preference within 12 hours, but can I submit it as UNDECLARED at first and use the method to express my intention? When I receive the notification, I will save it in the DB and save it in the administrator page of the service so that the administrator can choose.
2-1. Some of the materials I looked for are told that Apple can proceed with the refund even 12 hours ago, and to express your opinion as soon as I receive the notification, but I wonder if this is correct.
If you get a notification as below, you should write whether you used it or not by referring to the consumption information. I think the customer said to check whether the data was provided when applying for a refund. Should I take it out of decodedTransaction, check the value, and just call it NO_PREFERENCE? I'd appreciate it if you could give me some advice.
Below is a part of the code I implemented.
private void handleConsumptionRequest(ResponseBodyV2DecodedPayload notification) throws Exception {
// 1. transaction ID get
String signedTransactionInfo = notification.getData().getSignedTransactionInfo();
JWSTransactionDecodedPayload decodedTransaction = signedDataVerifier.verifyAndDecodeTransaction(signedTransactionInfo);
String transactionId = decodedTransaction.getTransactionId();
// 2. Extract the relevant transaction (The following example is an in-app payment and will be accumulated in two types of DBs, stored in one of the two)
Sample sample = sampleService.findByAppleTransactionId(transactionId);
Example example = exampleService.findByAppleTransactionId(transactionId);
Boolean canRefund = false;
// 3. Check consumption information
if (sample != null) {
canRefund = checkSampleStatusForApplePurchaseRefund(sample);
} else if (example != null) {
canRefund = checkExampleStatusForApplePurchaseRefund(example);
}
// 4. Create Refund Preferences
RefundPreference refundPreference = determineRefundPreference(canRefund);
// 5. Creating a ConsumptionRequest Object
ConsumptionRequest request = new ConsumptionRequest()
.refundPreference(refundPreference)
.sampleContentProvided(true);
log.info("forTest~ canRefund: {}", canRefund);
log.info("forTest~ sample: {}", sample.toString());
log.info("forTest~ example: {}", example.toString());
log.info("forTest~ refundPreference: {}", refundPreference);
log.info("forTest~ request: {}", request);
// 6. Transfer to App Store (annotated with dummy requests that only confirm current business requests are going right)
// appStoreServerAPIClient.sendConsumptionData(transactionId, request);
}
Topic:
App & System Services
SubTopic:
StoreKit
Tags:
In-App Purchase
App Store Server Notifications
App Store Server Library
Previously I could get the sub package information after each payment via webhook but today I didn't get it. What happened?
My webhook url: https://r-connect-api-dev.mystg-env.com/webhook/appstore/notification/v2
Topic:
App & System Services
SubTopic:
StoreKit
Hi,
I am trying to obtain the subscription expiry date or purchase date from server using Storekit2 for my project.
I have an account which is already having an active subscription but it still says no purchase found.
Thanks
Hi,
I have a setup using App Store Server notifications, which has worked fine for a while now. However, I've never been able to successfully verify a purchase via Xcode, only via TestFlight.
The reason for this is that the StoreKit transactions have numerical IDs (e.g. starting from 0, incrementing one-by-one), instead of UUIDs like in TestFlight/production.
This means that often the backend will detect an existing transaction with the same ID and not complete the purchase.
What are we meant to do here? If I send a custom ID to make it unique the backend won't accept this - I can ask them to change this for our dev environment but it's not ideal.
What I'm after is a way to use UUIDs for transaction IDs when running via Xcode.
Thanks
Topic:
App & System Services
SubTopic:
StoreKit
User Initiated a Single Consumable Purchase but Was Charged Twice
A user initiated a single in-app purchase for a consumable item, but they were charged twice. Both transactions have the same purchase token.
Additional details: After the user successfully completed the in-app purchase, the completeTransactions callback was triggered again. This was called at app launch using SwiftyStoreKit.completeTransactions to finish any pending transactions.
Could this be causing the duplicate charge? Any insights would be appreciated.
In the app we're distributing, we've identified a user where the Get All Subscription Statuses API returns two original transaction IDs in the data response. This user has gone through cancellations and re-subscriptions since their initial purchase.
Meanwhile, despite maintaining a continuous subscription, a notification suddenly arrives on the renewal date with original_transaction_id2.
+---------------------------+---------------------------+---------------------+
| original_transaction_id | notification_type | subtype |
+---------------------------+---------------------------+---------------------+
| original_transaction_id1 | SUBSCRIBED | INITIAL_BUY |
~ Repeated cancellations and re-subscriptions ~
| original_transaction_id1 | SUBSCRIBED | RESUBSCRIBE |
| original_transaction_id2 | SUBSCRIBED | INITIAL_BUY |
+---------------------------+---------------------------+---------------------+
Although it can be inferred from the interface definition of the API itself that multiple original transaction IDs may be returned, what causes multiple original transaction IDs to be returned?
Furthermore, is it possible to reproduce the case where multiple original transaction IDs are returned in the sandbox environment provided by Apple?
As for this app, it:
Uses subscriptions through in-app purchases.
Does not offer upgrades, downgrades, or crossgrades, having only one product.
Has never undergone price increases or decreases.
Is distributed exclusively in Japan.
Topic:
App & System Services
SubTopic:
StoreKit
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
Is the following subscription cancellation flow possible for an iOS in-app subscription?
(Note: This is during the feature planning stage, not actual app deployment.)
Planned user flow:
User taps the “Cancel Subscription” button
Display a “Wait a moment!” screen showing how much the user has enjoyed BFLIX content (to encourage retention)
User taps “Proceed to Cancel”
Collect cancellation reason from the user
Redirect the user to the Apple subscription management page to complete cancellation
Can this flow be implemented under Apple’s current in-app purchase and App Store Review guidelines?
Topic:
App & System Services
SubTopic:
StoreKit