StoreKit

RSS for tag

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

StoreKit Documentation

Post

Replies

Boosts

Views

Activity

Unfinished transactions not being emitted on start of app
I'm using the iOS simulator with a StoreKit configuration file. I can see that there have been transactions while the app has been closed, but my StoreKit 2 listener is never called with those updates to be able to finish them When I open my app from a cold start. I've added a listener on application(_:didFinishLaunching:launchOptions:) like this: func startObservingTransactions() { task = Task(priority: .background) { for await result in Transaction.updates { if case .verified(let transaction) = result { await transaction.finish() } } } } But the Transaction.updates loop never gets called (have added breakpoints to check). It's only ever called when a purchase is made, or subsequent transaction renewals when the app is open. Only then it will get the previously unfinished transactions. Steps to reproduce: Create an app with a StoreKit config file (with sped up transactions) to purchase an item Make a purchase then quit the app Wait for a bit for more transactions to be made while the app is closed. Open the app from a cold start and none of the transactions will be finished by the listener in your app. Cancel the subscription via the transaction manager. Close and open the app from a cold start. The first transaction will be finished by the listener but none of the others will be. In Apple's docs it says If your app has unfinished transactions, the listener receives them immediately after the app launches Why is this not the case?
14
2
3.2k
Dec ’22
App Store Server API: > 4 second latency
We're currrently migrating from the deprecated /verifyReceipt endpoint to the new App Store Server API. Context: We use Storekit 2 on the client. Even though it validates transactions client-side, our app also persists subscription data (Original Transaction ID + Product ID) to our DB, so it's necessary to validate the purchases server-side as well. When calling the new endpoints (for example, Get All Subscription Statuses or Get Transaction History ), I'm currently seeing 4+ second latency. This is the case when passing in only a Transaction ID and hitting the Production endpoint, even for Transaction IDs that don't exist in Production (eg, Sandbox transactions). Are there any plans to improve the performance of this API? As it currently stands, we're holding off on the migration -- 4 seconds is far too impactful on both our user experience and our backend system versus the existing 300-400ms latency of /verifyReceipt.
3
0
115
1w
No way to close the page for subscription Offer Code processing invoked by "SKPaymentQueue.default().presentCodeRedemptionSheet()".
Problem was observed on the published App because the IAP offer code processing is only done on the published App. I implemented the ".presentCodeRedemptionSheet()" command by tapping Offer Code button. Then the typed in offer code was processed by this page and the offer was successfully purchased from AppStore. After detecting the purchased status, executed "SKPaymentQueue.default().finishTransaction(transaction)". I thought that finishTransaction() would close the offer code processing page that is not written in document. However the page for offer code processing page was still displayed and was never closed. The only way to close the input page for offer code is to manually tapping "Cancel" button. Since there is no way to close the offer code processing page, I added ".popToRootViewController(animated: true)" in order to close all pages and views after detection of purchased status but failed to close the offer code processing page managed by Apple. I need to know how to programmatically close the offer code processing page invoked by ".presentCodeRedemptionSheet()". I got no response from FeedBackAssistant and Apple Developer Technical Support. Thank you.
4
0
382
Apr ’23
How to distinguish between subscription purchases made through the app and directly from the App Store
We are wondering if it is possible to distinguish between purchases made through our app and those made directly from the App Store in the subscription process. Does the API information such as Server notifications v2 and Get All Subscription Statuses contain information that can distinguish between these cases? If not, we are thinking of using the appAccountToken included in JWSTransaction to distinguish between them. We are aware that appAccountToken is set when an appAccountToken or applicationUsername is given to an app when purchasing a subscription. Therefore, we believe that the appAccountToken of JWSTransaction is not set when you purchase a subscription directly from the App Store. We think that by setting the appAccountToken for purchases made through our app, we can distinguish whether the subscription was purchased directly from the App Store or not, but is this an appropriate way to do so? Please let us know if there is a case where the appAccountToken is set even if the subscription was purchased directly from the App Store. https://developer.apple.com/documentation/appstoreserverapi/appaccounttoken
1
0
208
2w
using external link for payment than In-App purchase
We are a small startup and in process of launching our product. For now we have digital services (user can add and see data as they entered only be subscribed), but later we would have value added services - including hardware ( devices e.g. Glucometer). Current payment workflow we have uses Razorpay as payment gateway. We have two options: We can either make a web page for the payments to be collected via Razorpay. this will have less impact on the code and implementation. (like there's for Netflix and Spotify where they redirect to browser for payment than in-app purchase) We can add the apple payment gateway for the payments. Questions: What would be the charges in both the scenarios ? E.g. If we take 100rs payment from patient then how much would go to apple in scenario 1 and 2. Is there any support for small startups where apple provides some discount with respect to the payments collected ?
0
0
92
1w
Moved my Project from iMac using macOS 13.6 to MacBook Air M1 using macOS 14.5
Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost Getting this error with: SKPaymentQueue.default().restoreCompletedTransactions() Implemented: func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: any Error) { <#code#> } Error returned is the 1005 error I listed above. The laptop works fine, it is connected to the internet just fine. The problem is connecting to the AppStore Simulator when the project target is intended for the Mac. I have an iOS project for this product and I do NOT get this problem with the transaction observer when the project target is iOS (iPhone, iPad). This problem only occurs on the M1 Laptop and the target is MacOS.
2
0
261
Jun ’24
Are there cases where a response to an error returned from the AppStore Server API is considered a subscription cancellation by the user?
According to the following document, when the AppStore Server API is executed and the account does not exist, the response "errorCode: 4040001" is returned. If this response is returned, is it safe to assume that the account has been deleted and treat the subscription as cancelled? Also, please let us know if there are any other error codes other than this error code that can be used to determine that the subscription has been cancelled. https://developer.apple.com/documentation/appstoreserverapi/accountnotfounderror
1
0
195
2w
StoreKit issue
Hey everyone! I’m currently working on a new app called Kept – a simple and elegant journaling app designed to help you capture your thoughts and ideas effortlessly. However, I’ve hit a bit of a snag with the TestFlight distribution of the app. When I test the in-app purchases locally, everything works perfectly. But once the app is pushed to TestFlight, users only see "Loading products..." indefinitely and are unable to make purchases. Here are the details: The app works locally with sandbox accounts. Product identifiers and configurations have been double-checked. All in-app purchases are correctly set up and approved in App Store Connect. Using correct sandbox account settings on the device.
1
0
188
2w
When I will receive the App Store Server notification?
I'm migrating my app to Store Kit V1, to Store Kit V2, and, due some legacy circumstances I'm implemented in past using a synchronous method, calling verify receipt on my server to validate receipt and do the needed business logic, but due to the deadline I changed the entire app integration and some questions starting to appear in my mind. First of all, when I processing the purchase when basically I will receive the notification? When the Store Kit calls the transaction.finish or after the purchase was successful I always will receive this notification?
1
0
172
2w
App Store Review Request error Swift 6
I'm fairly new to Swift, so I'm unsure as to what's going wrong with my code and how to fix it. After switching to Swift 6, the view I have with requestReview throws: "Cannot form key path to main actor-isolated property 'requestReview'" As I understand it, this is potentially due to the changes made to @MainActor. However, I am unsure how to go about fixing this error.
3
2
223
2w
Sandbox users always are owning application
Hi! I'm trying to implement a two week free trial for my existing paid ipad app. Following the guidance from the wwdc2022/10007, I'm using AppTransaction.shared and checking the result. I'm getting a verified result, but the appTransaction.originalPurchaseDate is always the same date - 2013-08-01 07:00:00 +0000 / 397033200, even the particular sandbox account user never had a purchase. This makes testing the logical branch of "has this user never purchased this app before" if the app store is always telling us that it's been purchased. (I've been using new sandbox account, so there should be no history) Here's some code that includes hacking around always getting that original purchase date. We're in the final stretches, and wanting to test things that will be closer to actual store behavior (and I'm thinking that always returning a purchased date for an unpurchased app wouldn't be happening) Am I just holding things wrong? Sandbox bug/limitatiin I just have to live with? thanks! ++md class MJAppStore: NSObject { @objc static let shared = MJAppStore() @objc func verifyAppStoreStatus(_ completion: @escaping (MJAppStoreStatus, Error?) -> Void) { Task { do { let status = try await doVerificationThing() completion(status, nil) } catch { completion(.error, error) } } } func doVerificationThing() async throws -> MJAppStoreStatus { do { let result = try await AppTransaction.shared print("TRIAL: survived AppTransaction.shared") switch result { case .unverified(_, _): print("TRIAL: app transaction UNVERIFIED") return .free case .verified(_): let appTransaction = try result.payloadValue // hack around the app store sandbox accounts saying we're purchased even though // we're not really. 2013-08-01 07:00:00 +0000 print("TRIAL: app transaction VERIFIED \(appTransaction.originalPurchaseDate.timeIntervalSinceReferenceDate) -> \(appTransaction.originalPurchaseDate)") if appTransaction.originalPurchaseDate.timeIntervalSinceReferenceDate == 397033200 { return .free } else { return .purchased } } } catch { ...
1
0
182
4w
In-App purchase required for a support app?
Hi, I am trying to determine if an in-app purchase will be required within the app we are developing. We provide a web platform where the user can sign in and offer/search services correlated to entertainment world (showman, catering, DJ, live food lesson, etc.). The web app has 2 target: consumer users and business user. Consumer users can search services that tay want and chat business users owner of that services. Business users can create their ownpages in order to be visible to the consumer users in the community. Business users can also access too specified premium features for visibility. We are now designing a mobile app with only few features: Register login section Search business pages The users are the same and there is no differences in the mobile features (no hide premium functionalities). For these small features we have to implement the in-app purchase? The idea is to provide initially a small "companion" app to search business pages. Fo the next releases, where we want to provide more features, premium functionalities for business user we will integrate in-app and we already have plans to implement it. Thanks in advance!
0
0
144
2w
How to get signed transaction data from StoreKit 2
Is there any way to get the transaction in its original transaction in a secure format (such as a JWT) using the StoreKit 2 API? I can see the [jsonRepresentation] (https://developer.apple.com/documentation/storekit/transaction/3868410-jsonrepresentation) in the Transaction object, but that is already decoded. The transaction needs to be sent to the backend server for further processing, but there is no way to verify the integrity of the transaction details. For instance, there is no way to know if the transaction details the backend server receives actually belong to that specific user. The backend server can query the App Store API for a specific transaction ID, and then compare the details, but that still does not prove that the transaction the client sent actually belongs to that client. What I'm after is any way to send a transaction to the backend server that has been signed by Apple, which can then be validated. There a few use-cases for this, but the most pressing one is that of recovering purchases and linking new devices to an existing app account. For example: User A installs the client app on device X, which creates an account on the backend server. Assume there is no login-mechanism in place, we just need to rely on their in-app purchase history to identify a user account on new devices (or a re-installation of the app on an existing device). User A purchases a non-consumable or subscription in this app. Now that user has a transaction history that can be retrieved from the App Store API. User A now installs the app on device Y. The backend server creates a new account for this user (since it does not know who that user is, at least not yet). The user triggers a "recover purchases" command in the app, so the app queries the StoreKit 2 API for existing transactions. Store Kit responds with the previous transaction, which the app then sends across to the backend server (currently using jsonRepresentation). The backend server does not have a way to validate that the provided transaction data actually belongs to user A, so simply trusts it, and queries the App Store API with the provided transactionID. The server receives the transaction from the App Store API, and can validate that it in fact is a valid transaction, but still, there is no way to be certain that it belongs to user A. The backend server then merges the newly created account on device Y with the existing account on device X, so device Y now access that same initial account. I feel that there is a problem here. Let's say a malicious user B somehow has access to valid client transaction data from user A. User B installs the app on device Z. User B transmits a a valid jsonRepresentation of a transaction that belongs to user A to the backend server to link their device to the existing account. The server queries the App Store API with the transaction ID, and validates it, and given that this is successful, it simply links device Z to the existing account of user A. Now user B has access to the account of user A. The chances of this happening could be reduced (but not completely avoided) if there was a way to send a signed transaction from a device to the server. That way the backend server could verify the source of the transaction coming from the device, and if it is successful, continue on with any further processing. If there is something in the existing jsonRepresentationof the transaction from the client that I could use for verification, then please point me in the right direction. Yes, all of this may be avoided if the application has login accounts, but that isn't the issue here. Our app does have the ability to log in via 3rd party providers, but that is entirely optional, so the only way we can restore accounts on new devices is to check the App Store transaction history. Any help or suggestions regarding this would be appreciated.
2
0
160
2w
StoreKit Free Trial Period
I'm offering a free trial period for each of four auto-renewable subscriptions. Does anyone know the best way to detect whether a customer is still in the trial period, and to calculate the remaining trial days? I'm using Storekit 2. I've seen vague answers about using the Transaction purchaseDate and expiry date, but the documentation is incredibly vage as to what those values actually represent when it comes to a free trial period. What does purchase Date actually mean when you're in a free trial? Any help greatly appreciated.
1
0
284
2w
In App Purchases (Subscription Issue)
Hello, We are facing an issue with our customers on in-app purchasing. One of our customers tried to get a yearly subscription on 23rd May 2024 but could not succeed due to a billing error. But on 19th June 2024, his subscription was purchased automatically for 1 year, and the package expiry date shows 19th June 2025. So why did Apple charge to customer after 1 month without any intimation? Can anybody help here? Thanks
1
0
210
2w
Subscriptions for teams (in-app purchase)
Is it possible - in appstore - to create a subscriptions model similar to what microsoft teams and google workspace has for team memberships? We want to have a subscription price per user per month (or year). Administrator should be able to add additional users (and add a subscription for the new users) - It doesn't seem to be possible - only option is to have prefix subscriptions with 5 users, 10user, 15 users etc. (we've also looked into consumables - but the lack the option to be reoccurring payments) Thanks in advance?
0
0
150
2w
Notification Received on Consumable Purchase
Hello, I am encountering an issue where I receive an App Store Server Notification V2 upon the purchase of a consumable item. I have configured the App Store Server Notification V2 endpoint to handle notifications related to subscription products. However, I did not expect to receive notifications for consumable purchases. The notification includes the following signedPayload decoded into the ResponseBodyV2DecodedPayload object with the following values: notificationUUID: 3cd6410b-0c89-4247-aba5-20710e79895e notificationType: null subtype: null The transaction information decoded from the ResponseBodyV2DecodedPayload object is as follows: transactionId: 2000000633622618 webOrderLineItemId: null productId: heart_2 To debug, I called the Get Notification History API of the App Store Server API, and the mentioned notification for the consumable product purchase is not included in the history. Only notifications related to subscription product purchases are retrieved. According to the notification type documentation, there is no explanation for cases where both notificationType and subtype are null, nor is there any mention of receiving notifications for consumable purchases. Therefore, I am uncertain how to interpret and handle this notification. Could you please provide an explanation or guidance on this issue? Thank you. References: https://developer.apple.com/forums/thread/737592 https://developer.apple.com/documentation/appstoreservernotifications/notificationtype
2
0
208
2w
Auto-Renewable Subscription proration
Hello, I studied this and this documents and I find certain contradiction with this discussion. Could you help me out, please? I set up my subscriptions this way: , where Pro (annual or monthly) offers most of the features and Mobile Pro (annual or montly) least of the features. Do I get it right, that: Upgrading: to annual: What happens here? to monthly: [link] The customer’s prorated payment from lower level subscription is refunded to the original payment method. They’re charged for the higher level subscription, which goes into effect immediately. Downgrading: both annual and monthly: [link] They’re charged for the lower level subscription on their next renewal date. They continue using their current subscription until then. Crossgrading: to annual: What happens here? to monthly: [link] ...the crossgrade goes into effect on the customer’s next renewal date. They continue using their current subscription until then. Thanks.
1
0
188
3w
StoreKit Transaction Price values
Apple added price field on StoreKit's Transaction with Xcode 15.1 and I adopted immediately. What I saw was that when the app was run in debug or TestFlight, the values for price were the same as they were displayed to the user e.g. $29.99 would be returned as 29.99 but in production I got values multiplied by 1000. They do multiply values by 1000 for App Store Server Notifications and APIs though but it is not documented as such for StoreKit's Transaction price field. I am afraid to make this change again and deploy it to production. Has anybody experienced anything like this?
2
0
229
3w