Meet StoreKit 2

RSS for tag

Discuss the WWDC21 session Meet StoreKit 2.

View Session

Posts under wwdc21-10114 tag

48 Posts
Sort by:
Post not yet marked as solved
1 Replies
269 Views
Hello, I am implementing StoreKit2. My app uses Transaction.currentEntitlements to load the user's purchased subscriptions after the app is launched, how the transactions are loaded? (from the AppStore/Internet or from the local receipt) currentEntitlements doesn't throw any exception, and I'm not sure how to handle the offline case.
Posted Last updated
.
Post not yet marked as solved
7 Replies
2.2k Views
Hi, I have been testing StoreKit 2. I'm trying to query for available subscription products by using the following query code as per the document. I have configured the in-app purchases with subscriptions in appstoreconnect. The request query keeps throwing an error. Would appreciate some help. Query Code let productIdentifiers: Set = ["monthly_subscription", "yearly_subscription", "family_monthly_subscription", "family_yearly_subscription"]         async {             do {                 let _subscribableProducts = try await Product.request(with: productIdentifiers)                 self.subscribableProducts = _subscribableProducts             }             catch {                 print("Something went wronge \(error)")             }         } Error thrown systemError(Error Domain=ASDErrorDomain Code=507 "Error decoding response" UserInfo={NSLocalizedDescription=Error decoding response, NSLocalizedFailureReason=Could not decode media products response})
Posted Last updated
.
Post not yet marked as solved
0 Replies
348 Views
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
Posted
by alpennec.
Last updated
.
Post not yet marked as solved
1 Replies
161 Views
Hello, I'm using in my app storekit2 solution from wwdc example: https://developer.apple.com/documentation/storekit/in-app_purchase/implementing_a_store_in_your_app_using_the_storekit_api Anyway, I got rejection from Apple with information that "app includes a feature to restore previously purchased in-app purchase products by entering the user's Apple ID and password. However, subscription in-app purchases cannot be restored in this manner." I don't understand this issue. I don't force user to login. What is going on? I don't understand this issue. Can somebody help me understand this? Thanks.
Posted
by pidipius.
Last updated
.
Post not yet marked as solved
4 Replies
1.1k Views
It seems that subscription status gives different results with XCode testing and Sandbox testing. I am using StoreKit2 to implement an IAP of an autorenewable subscription. I want to determine whether the subscription has been cancelled, so that the UI reflects that the subscription will stop after the expiry date and not be renewed. the 'willAutoRenew' property of the subscription status renewalInfo seems to do exactly what is required, and works fine in XCode testing. My setup is very similar to the StoreKit demo associated with the WWDC21 session available here: https://developer.apple.com/documentation/storekit/in-app_purchase/implementing_a_store_in_your_app_using_the_storekit_api/ To demonstrate its use, add: print(renewalInfo.willAutoRenew) after line 79 of the SubscriptionsView in the demo project. When you run the app, and purchase a Standard Navigation assistance subscription, the console shows 'true'. If you then cancel the subscription in XCode (Debug:StoreKit:Manage Transactions), the console will show 'false' as expected So far so good. My problem is that when I move to Sandbox testing, and cancel the subscription in another way (eg using the .manageSubscriptionsSheet view modifier, or in Settings:App Store:Sandbox Account), the willAutoRenew property remains true, even though the subscription is in fact cancelled (ie it disappears after the expiry date) Does anyone know a workaround to determine cancellation status?
Posted
by Baylward.
Last updated
.
Post not yet marked as solved
0 Replies
137 Views
Use StoreKit 2 my client IAP code like this: func purchase(_ product: Product) async throws -> Transaction? {         let orderId = UUID.init()         let result = try await product.purchase(options: [.appAccountToken(orderId)])         switch result {         case .success(let verification) :             let transaction = try checkVerified(verification) //Here can I tell my server deliver content to user? //I do not want valid transaction on device(just like valid receipt via S2S use Storekit1)             return transaction         case .userCancelled, .pending:             return nil         default:             return nil         }     } If verificationResult return ..verified() case , can I tell my server deliver content to my customer ? Or should I send originalID for this transaction to my server, my server has to fetch transaction info by history Api(decode JWS info) to decide whether to deliver content to my custom? Thank you very much
Posted
by JerryLiu.
Last updated
.
Post not yet marked as solved
1 Replies
396 Views
My app uses the new API for in-app purchase rather than the original API as listed here: https://developer.apple.com/documentation/storekit/choosing_a_storekit_api_for_in-app_purchase But in App Store connect I'm getting this error/warning: These in-app purchases can’t be promoted on the App Store because your latest approved binary doesn’t include the SKPaymentTransactionObserver method. SKPaymentTransactionObserver is a part of the old API and I believe I shouldn't need to implement it anymore. Anyone know what I should do here?
Posted Last updated
.
Post not yet marked as solved
1 Replies
430 Views
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.
Posted
by alpennec.
Last updated
.
Post not yet marked as solved
1 Replies
196 Views
Since StoreKit2 Transaction.currentEntitlements will able to return us user current owned purchased, during app startup. If that is the case, is it still necessary for developer to provide a restore button? If we still need to provide a restore button, what should the restore button do and what API should it call? Thanks
Posted
by yccheok.
Last updated
.
Post not yet marked as solved
1 Replies
218 Views
Hi, I have a paid app available through the Mac App Store, and when the user opens the app, I want to verify that the transaction of the payment is valid. I would have assumed that in StoreKit2, the 'Transaction.all' would work, but when I tested this, it shows 0 transactions for all users. This is what I'm testing: for await result in Transaction.all { guard case .verified(let transaction) = result else { continue } print("verified product = \(transaction.productID)") // send to analytics } But nothing gets observed in the analytics. Does the StoreKit2 framework have an easy way to determine transactions that are made for paid-up-front apps?
Posted
by zulfishah.
Last updated
.
Post not yet marked as solved
0 Replies
400 Views
Hi, I have a paid app in the Mac App Store, and I want to verify that the user purchased the app legitimately. Does the StoreKit2 framework have an easy way to determine this? From the documentation I've seen, I believe the 'Transaction.currentEntitlements' call will only return transactions for IAP and subscriptions. I would assume that 'Transaction.all' would work, but when I run the app (with Xcode debugger attached) I get no results. What's the best way to test this out for an app that's going to be paid-up-front?
Posted
by zulfishah.
Last updated
.
Post not yet marked as solved
2 Replies
304 Views
Can someone please confirm me how to use App Account Token purchase option? Do we have to save the UUID with the users data or do we not have to do anything? i am really confused in this matter. Any explanation would be extremely appreciated. Thanks 😊
Posted
by MFAB.
Last updated
.
Post not yet marked as solved
1 Replies
373 Views
Hello everyone, I'm trying to use Storekit 2 for my application. But I have an issue when checking the expired date. I cancelled the subscription in the setting (Sandbox). After few minutes, the subscription was expired (stop to renew). It's OK. But after I open my app, the status of the subscription still "Subscribed" although the expiredDate was expired. Why the status wouldn't be "Expired"? func updateSubscriptionStatus() async {     do {       guard let product = subscriptions.first,          let statuses = try await product.subscription?.status else {         return       }       for status in statuses {         switch status.state {         case .subscribed:           print("Always enter this case with expired date.")         case .expired:           print("Never enter this case.")         case .revoked:           break         case .inGracePeriod:           break         case .inBillingRetryPeriod:           break         default:           break         }       }     } catch {            }   }
Posted
by carsonvo.
Last updated
.
Post not yet marked as solved
1 Replies
523 Views
Hi, I have a look to wait for all non purchase Transaction             for await result in Transaction.updates { … } But this block works when I trigger a restore purchases, but it is never called when I approve a pending purchase. Is there any reasoning why this could be or a bug. (As an app store user and father I had a similar problem where my daughter had to tap purchase again and then it worked. All the best Christoph
Posted Last updated
.
Post not yet marked as solved
2 Replies
879 Views
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")                 }             }         }     }
Posted
by alpennec.
Last updated
.
Post not yet marked as solved
4 Replies
968 Views
When dealing with auto-renewable subscriptions, there are multiple ways to access the latest transaction. We can access it when a purchase is made, or we can request the latest transaction for a given productID at a later time. To do so, we can use Transaction.latest(for:), access the transaction history using Transaction.all, get the currentEntitlements, or use the array of Product.SubscriptionInfo.Statusthan contains the latest transaction for a subscription group. It's also necessary to listen to transactions when the app is running using the AsyncSequenceTransaction.updates`. In my app (and also in the SKDemo project from Apple), when I want to access the latest transaction as soon as the app is launched, it's missing the transactions that renewed or happened while the app was not running. I tried using the different methods mentioned above but they never give me the latest transaction, always the latest transaction while the app was running before I killed it. I have to wait for a new renewal event to receive the latest transaction in the Transaction.updates listener, which is not good. For example, when I set the Subscription Renewal Rate to Monthly Renewal Every 30 seconds, and I quit the app when the latest transactionId is 100, I wait for 5 minutes, I expect to see the transactionId 110 but I see 100. In the real life, it means that if the app is not running when a monthly or annual subscription renews, I have to wait weeks or months to receive the missing transaction. I thought that the Transaction.updates listener would be called at launch with all the transactions that occurred while the app was not running. Is that a bug in Xcode or have I misunderstood something? How can I access the real latest transaction that happened when the app was not running at launch? I need to access that to know what the user has access to. I think the transaction management panel from Xcode displays all the transactions, even the one when the app was not running. PS: I'm using Xcode 13.2.1 and iOS 15.0 (simulator). Transaction.updates is not working on iOS 15.2 (my device, or simulator) from what I've seen so far.
Posted
by alpennec.
Last updated
.
Post not yet marked as solved
1 Replies
426 Views
if let status = try await product.subscription?.status { for state in status { if (state.state == .subscribed) { isPro = true break } } } When I subscribe with the api product.purchase in my app, every thing work right. The state is updated to .subscribed right after the purchase finished. However, when I manage the subscription in App Store sandbox with a test account. The subscription state does not updated until I manually ask for another purchase in my app. Then a window popup telling me that I have already purchased this product. And then the state of the subscription also updated to .subscribed. I have also made a update listener to listener all transaction update, just like how SKDemo do. But seems it doesn't receive any update. Last, could any one tell me that if the update listener also responsible for listening the expiration of a subscription?
Posted
by long123.
Last updated
.