StoreKit

RSS for tag

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

StoreKit Documentation

Posts under StoreKit tag

278 results found
Sort by:
Post not yet marked as solved
29 Views

StoreKit 2 • What is subscriptionGroupID in status(for groupID: String)?

Hello, I want to access the latest transaction for a Subscription Group. I use the following method static func status(for groupID: String) async throws -> [Product.SubscriptionInfo.Status] to access the statuses for the group, and from there, I can get a verified transaction from the status. But when I set the GroupID equal to the Subscription Group Reference Name I put in the .storekit configuration file in Xcode, I don't have any status (so wrong ID). Actually, I have to use a subscriptionGroupID like 3F19ED53 (found using a previous transaction: https://developer.apple.com/documentation/storekit/transaction/3749718-subscriptiongroupid). When I look into a Product, this ID is set for subscriptionFamilyId. So my question is how can I know the ID if it's not the one I provided in App Store Connect or the config file? Do I first have to access a Product from this group? Thanks.
Asked
by alpennec.
Last updated
.
Post not yet marked as solved
29 Views

Storekit2 with firebase help

Hi guys, I am building an app that plays audio. Some audio is free whereas some audio is "premium" with a ONE TIME FEE it will unlock ALL audio. I will be uploading the audio through firebase. Whats the easiest way of going about this? I have no idea where to start. Any help is greatly appreciated! :) Take care all :)
Asked
by HarryG98.
Last updated
.
Post not yet marked as solved
27 Views

StoreKit 2 • Purchase Result wrong when Ask to Buy is cancelled (no tap on Ask)

Hello, When 'Ask To Buy' is enabled, and the user cancels the request (left button on the provided screenshot below), the purchaseResult in iOS 15 is set to .pending when we call try await product.purchase(). It's wrong, it should be set to .userCancelled because the parent will never receive any approval request in this case. It breaks the logic in my app because tracking real pending requests is then not possible. I also think that a declined transaction should be made available to the app in the transactions observer: how can we remove a pending transaction that had been declined? We can't for the moment. Thanks, Axel
Asked
by alpennec.
Last updated
.
Post not yet marked as solved
33 Views

StoreKit 2 • updateListenerTask never called (Ask To Buy context for example)

Hello, I'm currently adding StoreKit 2 into my app. I've watched the WWDC21 session (Meet SK2) and downloaded the sample SKDemo app. When I want to test the Ask To Buy flow, it does not work: I see the sheet on the device, I see the alert and tap on the "Ask" button. In Xcode, I then approve the transaction but the func listenForTransactions() -> Task<Void, Error> is never called. I'm testing the app in Debug mode, on a real device and on a simulator (using the Products.storekit local configuration file). What's wrong? Thanks, Axel Version 13.2 beta 2 (13C5081f) iOS 15.2 (19C5044b) func listenForTransactions() -> Task<Void, Error> {         return Task.detached {             for await result in Transaction.updates {                 do {                     let transaction = try self.checkVerified(result)                     await self.updatePurchasedIdentifiers(transaction)                     await transaction.finish()                 } catch {                     print("Transaction failed verification")                 }             }         }     }
Asked
by alpennec.
Last updated
.
Post not yet marked as solved
121 Views

Mac App Store IAP Price Doesn't Match App Store Connect

Hi, I'm working on my first app, so I'm not sure if I'm doing this right... I've got an unreleased app in App Store Connect with an IAP set; however, when I retrieve the price to show in my app, I'm consistently seeing it shown as pricing from 2 tiers above what I've set. E.g. in App Store Connect, I've set the IAP to Tier 22 (GBP 19.49), but my app shows GBP 20.99 - which is Tier 24. I've tried changing tiers - but no joy. Should I expect the pricing to match on an unreleased app? Thanks!
Asked Last updated
.
Post not yet marked as solved
37 Views

Production verifyReceipt endpoint declined using Cloudflare

I am trying to do a POST request to the verifyReceipt production endpoint using Cloudflare Workers. I intentionally stripped out all the receipt data, so the expected output would be status 21002 (The data in the receipt-data property was malformed). const url = "https://buy.itunes.apple.com/verifyReceipt" addEventListener("fetch", event => { return event.respondWith(handleRequest()) }) async function handleRequest(request) { const init = { method: "POST" } const response = await fetch(url, init) const results = await response.text() return new Response(results, init) } Using the sandbox url (https://sandbox.itunes.apple.com/verifyReceipt), this is working fine! However, when switching it out for the production endpoint it suddenly results in status 21199 (internal data access errors). Even when doing the request within the Cloudflare Workers test environment, it works, but when deploying the worker, it does not. Also, executing the request from other servers works as desired - the issue is specifically related with requests coming from Cloudflare. Does Apple have any measures active to decline Cloudflare Workers requests on this production endpoint? Is there a way around it?
Asked
by Baroni.
Last updated
.
Post not yet marked as solved
36 Views

Selling product with free app subscription

We have a wearable device that utilizes an iPhone app. You have to have the app in order to use the wearable device. We want to sell the device with a free one year subscription or the customer an add an additional year to the subscription for an additional price. What is the best way to handle this? Our thoughts: Generate 2 offer codes: 1 Free Year, 1 Free Year + 1 Paid Year Sell device on our website as two different products: Device + 1 Free Year, Device + 1 Free Year + 1 Paid Year. Give user an offer code or link to get app from Apple App Store. When user redeems offer code, downloads app and login, we verify the user bought a device on our API Server. We also want users to be able to buy renewable subscriptions in the Apple app store: mothly, yearly.
Asked
by jimkiely.
Last updated
.
Post not yet marked as solved
1.3k Views

[Sandbox] Consumable products "already bought"

My app only offers consumable in-app purchase products. I can successfully purchase a product once but when I try to purchase it again, a popup "This In-App purchase has already been bought. It will be restored for free." appears and the first transaction is restored: the payment queue delegate is notified that a new transaction (with the same identifier as the successful transaction) is updated to the purchased state. I never get a purchased transaction with a new identifier and hence I consider that the purchase failed. Also, each time the app is put in foreground again or at startup, the payment queue delegate is notified that a transaction has been updated (as if it had never been finished). Even though the app properly finishes the transaction each time. Side notes: I guarantee that all purchased or failed transactions are finished (confirmed by the removedTransactions SKPaymentQueueDelegate method being called each time). I even tried to call finishTransaction from the main thread with no success. Right before the subsequent purchase attempts, the transactions queue is empty. I'm also pretty sure I was able to purchase several times the same product last week, with no change in code (same app version from Testflight). I observe this behaviour when building the app with Xcode or when distributed via Testflight. It has not been published yet so I cannot check how it behaves in the Production environment. Do you have any clue on what's going on? Could it be a side effect of using the Sandbox environment? Thanks for your help, Aurélien.
Asked
by patatrouf.
Last updated
.
Post not yet marked as solved
70 Views

[IAP] How to handle missing receipt after a payment

Hi guys, I have an app that provides consumable product (in-app currency). I wonder if there are any cases when the app does not receive the signed receipt after a payment (to send back to my server in order to verify that receipt with the App Store). If yes, how can I handle that case? Is it possilble for the app to request the missing receipt? Thanks in advance.
Asked
by ngvnqng.
Last updated
.
Post not yet marked as solved
74 Views

Apple StoreKit Certificate

Where can I download the Apple StoreKit 2 root certificate to install on my NodeJS server to verify StoreKit 2 transactions and make sure the certificate chain in the JWS header comes from Apple?
Asked
by iamlogiq.
Last updated
.
Post not yet marked as solved
64 Views

Are Introductory Offer Dates Inclusive?

Let's say I want to create an introductory offer starting from the 1st of November till the end of the year. (it should begin at 01-11-2021 00:00:00 and expire at 31-12-2021 23:59:59) Which of the options below is correct in that case? Option 1 Start date: 1 November End Date: 31 December Option 2 Start date: 1 November End Date: 1st of January
Asked Last updated
.
Post not yet marked as solved
319 Views

StoreKit 2 Purchase doesn't load in App Review

Hi, I'm using StoreKit 2 for Consumable purchases since it is the new in-app purchase is still in review (2 days) and App Review getting rejected because it can't load this product. Everything works fine in TestFligt. I checked Agreement and it's fine. It isn't loading because StoreKit 2 or App Review side? Because I don't know how to test it more than with TestFligt. Thanks 🙏
Asked
by WeddMate.
Last updated
.
Post not yet marked as solved
106 Views

WatchOS Auto-Renewing Subscriptions

I'm creating a standalone WatchOS app using StoreKit 2. The code I have for making the purchase and checking the subscription status works under iOS 15. On WatchOS 8, after confirming the purchase, the product.subscription.status array is empty. I'm testing using the Xcode sandbox and I can see the purchase transaction there. I've talked with an Apple engineer and they think it may be a bug in WatchOS, but I'm reaching out here to see if anyone else has encountered this issue. Here's a code snippet: guard let product = store.subscriptions.first else { print("No Subscriptions"); return } guard let sub = product.subscription else { print("Not Subscription",product.id); return } let statuses = try await sub.status After the purchase, statuses has a value on iOS 15, but it's empty on WatchOS 8. "store" is my object to deal with StoreKit. Here's some relevant code that populates the store.subscriptions array. class Store: ObservableObject {   @Published private(set) var subscriptions: [Product]   @MainActor   func requestProducts() async {     do { //... keys are my product identifiers       let storeProducts = try await Product.products(for: keys)       for product in storeProducts {         switch product.type { // [snip]         case .autoRenewable:           newSubscriptions.append(product)         } }       subscriptions = sortByPrice(newSubscriptions) } // [snip]   } } I have tested this with Xcode 13.1 and 13.2b2.
Asked
by EdA.
Last updated
.
Post marked as solved
632 Views

SKProductsRequest delegate is not called

Even if I start a request for SKProductsRequest, didReceiveResponse, didFailWithError, and requestDidFinish are not called. The first request successfully called didReceiveResponse and requestDidFinish. However, didReceiveResponse, didFailWithError, and requestDidFinish are not called in the second and subsequent requests. About 12 hours after the second request, when I started the request again, didReceiveResponse and requestDidFinish was called normally. However, when I started the request immediately afterwards, didReceiveResponse, didFailWithError, and requestDidFinish were no longer called again. I kept the SKProductsRequest as a strong reference and executed the start of the request. https://developer.apple.com/documentation/storekit/skproductsrequest Objective-c Code: //SKProductsRequest request @property (strong, nonatomic) SKProductsRequest *request; _request = [[SKProductsRequest alloc] initWithProductIdentifiers:[NSSet setWithArray:_productIdentifiers]]; _request.delegate = self; [_request start]; - (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { } - (void)requestDidFinish:(SKRequest *)request { } - (void)request:(SKRequest *)request didFailWithError:(NSError *)error { } - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { } The following log is displayed in the console log of Xcode. [BackgroundTask] Background Task 8 ("SKProductsRequest"), was created over 30 seconds ago. In applications running in the background, this creates a risk of termination. Remember to call UIApplication.endBackgroundTask(_:) for your task in a timely manner to avoid this. This phenomenon occurred in the following operating environment. Xcode 13.0 iPhone 11 Pro / iOS 15.0 Deploy target iOS 13.0 SAND-BOX        This phenomenon did not occur in the following operating environment. Xcode 12.5.1 iPhone 11 Pro / iOS 14.5 Deploy target iOS 12.3 SAND-BOX This method is called after all processing of the request has been completed. Typically, subclasses of SKRequest require the delegate to implement additional methods to receive the response. When this method is called, your delegate receives no further communication from the request and can release it. https://developer.apple.com/documentation/storekit/skrequestdelegate/1385532-requestdidfinish The documentation states that the request can be released after the delegate is called. What does that mean? Is this the phenomenon that the next request is not processed until the unreleased request expires?
Asked
by mario25.
Last updated
.
Post not yet marked as solved
106 Views

How do I resolve "The verify credentials call failed" when attempting to restore an in-app purchase on iOS 15?

I am using StoreKit for in-app purchases. I'm testing the restoration of a purchase, to no avail. I keep getting this error message after typing in the username & password for a sandbox tester: Error Domain=SKErrorDomain Code=0 "UNKNOWN_ERROR" UserInfo={NSLocalizedDescription=UNKNOWN_ERROR, NSUnderlyingError=0x7b0c000652b0 {Error Domain=ASDErrorDomain Code=500 "Unhandled exception" UserInfo={NSUnderlyingError=0x7b0c00079ef0 {Error Domain=AMSErrorDomain Code=100 "Authentication Failed" UserInfo={NSLocalizedFailureReason=The verify credentials call failed., NSLocalizedDescription=Authentication Failed, NSUnderlyingError=0x7b0c0007fbc0 {Error Domain=AMSErrorDomain Code=15 "An unknown error occurred. Please try again." UserInfo=0x7b0800027540 (not displayed)}}}, NSLocalizedFailureReason=An unknown error occurred, NSLocalizedDescription=Unhandled exception}}} What do I need to do to resolve this error?
Asked Last updated
.