Is there an App Store Server API available that allows cancellation of specific subscriptions by specifying transaction_id or similar identifiers?
Background of these questions:
We occasionally suspend user accounts due to violations of our service terms and conditions. In such cases, we would like to forcibly cancel their subscriptions if possible. However, we could not find relevant information in the documentation, which is why we are reaching out with these questions.
Please let us know.
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
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?
Where the problem occurs:
In-app purchase
Non-ApplePay
Non-local authentication login
Environment where the problem occurs:
Sandbox environment (Development environment, TestFlight environment)
Problem handling process:
Open page A in the app and purchase product B (auto-renewable subscription) on that page.
User authentication is required to purchase product B.
During the authentication process, the user needs to enter the Apple account and Apple account password.
After completing the authentication, complete the purchase of product B.
Problem in step 3:
Why is FaceID or TouchID not used for authentication?
Note: Face ID and Password -> iTunes Store and App Store -> Status is Enabled
Hello, I’m trying to change my business model within the app, and following Apple’s documentation guidelines HERE I created this task in the main view of the app. It seems to work perfectly in the simulator, on physical devices, and on TestFlight. However, after releasing it to production and uploading the new version to the App Store, it doesn’t work, and all users, whether new or existing, are asked to subscribe. In the console, it appears to retrieve the transactions correctly, but in production, I’m not sure how to view the console or see what it’s retrieving.
Here the sandbox receipt I obtained
AppTransaction.shared obtained: {
"applicationVersion" : "1",
"bundleId" : "com.anestesiaIB.Drugs-Infusion-Calc",
"deviceVerification" : "6M0Nnw14nSEOBVTPE\/\/EfnWSwLm7LFSlrpFEwxgH74SBHp5dSzBEm896Uvo42mwr",
"deviceVerificationNonce" : "8a8238c0-0aee-41e6-bfb0-1cfc52b70fb6",
"originalApplicationVersion" : "1.0",
"originalPurchaseDate" : 1375340400000,
"receiptCreationDate" : 1737577840917,
"receiptType" : "Sandbox",
"requestDate" : 1737577840917
}
This are the processing log while verified the receipt
New business model change: 1.7
Original versionéis components: ["1", "0"]
Major version: 1, Minor version: 0
This user is premium. Original version: 1.0
This is my task...
.task {
do {
let shared = try await AppTransaction.shared
if case .verified(let appTransaction) = shared {
let newBusinessModelVersion = (1, 7) // Representado como (major, minor)
let versionComponents = appTransaction.originalAppVersion.split(separator: ".")
if let majorVersion = versionComponents.first.flatMap({ Int($0) }),
let minorVersion = versionComponents.dropFirst().first.flatMap({ Int($0) }) {
if (majorVersion, minorVersion) < newBusinessModelVersion {
self.premiumStatus.isPremium = true
isPremium = true
} else {
let customerInfo = try await Purchases.shared.customerInfo()
self.premiumStatus.isPremium = customerInfo.entitlements["premium"]?.isActive == true
isPremium = self.premiumStatus.isPremium
}
} else {
print("Error: obteining version components")
}
} else {
print("Not verified")
}
} catch {
print("Error processing transaction: \(error.localizedDescription)")
}
}
I am handling the buy subscription with this function
const handleBuySubscription = async (productId) => {
try {
await requestSubscription({
sku: productId,
});
setLoading(false);
} catch (error) {
setLoading(false);
if (error instanceof PurchaseError) {
errorLog({ message: [${error.code}]: ${error.message}, error });
} else {
errorLog({ message: "handleBuySubscription", error });
}
}
};
but the
requestSubscription({
sku: productId,
})
does not return anything, and it is stuck at await
https://developer.apple.com/documentation/appstoreserverapi/get-v2-history-_transactionid
I would like to inquire about the detailed triggers for updating receipts in this API specification.
Recently, I was using this API with sort=DESCENDING&revoked=false to retrieve the expiration date of the most recent receipt and determine the subscription status. However, for some reason, an old receipt with an earlier expiration date appeared as the first receipt, and I would like to know the reason for this.
Can you provide information on what specific events or actions trigger the updating of receipts in this API?
Also, regarding https://developer.apple.com/documentation/appstoreserverapi/status, will statuses 3 and 4 not be returned in the response unless the billing grace period is enabled in the App Store?
I enter the payment wall, there it takes more or less 3 to 4 minutes to show the plans, when I select the monthly plan the loader is shown and from there the pop up to make the purchase in sandbox does not appear, I have waited until a maximum of 50 minutes and it is not shown, I go back and close the app I do the same steps and I am still there, without showing the pop up.
Doing this same process in xcode, everything happens immediately without any interruption.
When simulating a Storekit error like an invalid device verification or others of that type, should we finish a failed transaction? When I test with a Storekit configuration file, all failed transactions persist after every restart. The Apple-provided sample code for Storekit 2 has transactions finished only when they are successful.
Hi,
Using StoreKit 2 with App Store Server notifications like so:
User selects a purchase
App calls Product.purchase()
If successful, App Store notifies our backend with the transaction details, importantly with a UUID for the transaction ID.
This works fine, but when I try to test contingent pricing via the handy StoreKit config Transaction Manager in Xcode by creating a PurchaseIntent if I then complete the purchase in the app the Transaction ID is sequential, (0 for the first, 1 for the second etc), which doesn't work for us as the backend might already have that ID stored so the purchase never completes.
If I disable the config file it works fine, but then I can't use the Transaction Manager debug tool. Is there a way to override the ID of a custom transaction that's created via the StoreKit configuration?
Thanks
hI, I’m looking for some clarity on the rules around in app purchasing, so I play a game with in app purchases that you have random odds of getting items out of loot boxes, they split the loot into sections, so featured, mega rare, rare and common. for each of these sections they give a % chance that they show of what chance you have to get an item out of that section, I.e featured is 1.24% and common is 74% ect.
my question is should they then have to display the odds of what each item has in those sections as well or is it good enough just to have the sections with % chance? So each section could have 10 items in, should those items have a % next to as well?
any advice you can give with this would be appreciated, if needs be I can send picture examples of what I’m explaining
I'm developing StoreKitV2 and my app provides in-app management of subscription. so I use AppStore.showManageSubscriptions method.
@MainActor
static func showManageSubscriptions(in scene: UIWindowScene, subscriptionGroupID: String) async throws
the document(https://developer.apple.com/documentation/storekit/appstore/showmanagesubscriptions(in:subscriptiongroupid:)) says
"Presents the App Store sheet for managing subscriptions for a subscription group." but actually It shows the list of subscription groups.
I wanna show the list of subscription options(products) of certain subscription group directly.
how can I??
In all the illustrations of win-back offers, I see an example of "Get 3 months off, then $X/month", as seen below.
First, I'm not exactly clear how each configuration translates into an actual offer in practice:
If I want to offer 3 months off on an annual subscription, ie. only if the user pays for the annual offer (basically a 25% discount), is that possible?
If I set a "Free" type, of 3 months, I guess that would allow the user to cancel before paying for the annual, correct?
If I set a "Pay up front" type, with a 25% discount, how would that show up to the user on the App Store?
Secondly, is eligibility to an offer determined by the user elapsing on the same subscription or any subscription in the same subscription group?
Thank you
Question on token testing in development:
Hello,
I'm developing a React Native application using StoreKit External Purchase. I'm having difficulties testing the transaction token retrieval in the development environment.
Specific questions:
Is it possible to test the transaction token retrieval in development/sandbox environment?
Is there a special testing mode for developers that would allow simulating token reception without going through the App Store?
Are there specific debugging tools to verify proper token reception?
Question on native implementation:
Regarding the native implementation of StoreKit External Purchase:
Is there detailed documentation on creating native modules for React Native that implement StoreKit External Purchase?
Can you confirm if the following approach is correct for native implementation:
Using NSClassFromString(@"ExternalPurchase")
Calling presentNoticeSheetWithURL:completion:
Retrieving the token in the completion block
Are there any code examples for complete native implementation?
Question on implementation validation:
For validating StoreKit External Purchase implementation:
How can we verify that our implementation is correct before App Store submission?
Are there validation tools or automated tests to check compliance?
What are common errors to avoid during implementation?
Question on best practices:
Regarding implementation best practices:
What's the best way to handle potential errors during token retrieval?
How to handle cases where the user cancels the transaction?
What are the recommended security checks for server-side token validation?
Question on documentation:
I'm looking for additional resources on StoreKit External Purchase:
Is there specific documentation for integration with frameworks like React Native?
Are there complete code examples for native implementation?
Where can I find information about testing and debugging best practices?
Additional technical question:
Technical implementation details:
What's the correct way to handle the ExternalPurchase class initialization in React Native native modules?
Are there specific requirements for the URL passed to presentNoticeSheetWithURL?
How should we handle the token in the completion block to ensure it's properly passed back to React Native?
Question on testing workflow:
Testing workflow questions:
What's the recommended testing workflow for External Purchase implementation?
How can we verify the token format and validity before production deployment?
Are there any tools or methods to simulate the complete purchase flow in development?
I cannot test IAP using sandbox account that I logged on from settings, it keeps show my regular Apple ID when I try to test IAP from TestFlight
This issue frustrate me and bunch of my colleagues, we cannot manage our subscription when sandbox account is default choosing Apple ID
I've seen people complaining about this issue a lot
Any help on resolving this issue would be really appreaciated
I have consumable IAPs in my app. Currently there is no way for me to test refunds for them as Xcode testing doesn't allow refunds option for my Purchases. According to this official documentation on Transaction.all , i should be getting my refunded consumables in Transaction's all property.
But there is no way for me to know what kind of data is in the refunded transaction object. Will there be a 'revocation date' like in the case of non-consumables?
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
For testing purposes, I log out of media and purchases to use sandbox ID's to test in app purchases. Once I log out of media and purchases in device settings, in app purchases is still using my real apple ID, I'm not being prompted anymore to log into a sandbox ID for purchases.
Topic:
App & System Services
SubTopic:
StoreKit
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
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
Hello, is it allowed to include the action=write-review URL parameter in customer support emails to direct users to the App Store review page?
Example: https://apps.apple.com/app/id[APP_ID]?action=write-review
I want to make it easy for customers to leave feedback after positive support interactions, but only if it's compliant.