StoreKit

RSS for tag

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

StoreKit Documentation

Post

Replies

Boosts

Views

Activity

In-App Purchases / Restores Currently Fail in Sandbox Environment
Attempts to purchase an SKProduct or restore all completed transactions via the usual method calls in StoreKit leads to failure in the beta environment with the following error: Error Domain=SKErrorDomain Code=0 "An unknown error occurred" UserInfo={NSLocalizedDescription=An unknown error occurred, NSUnderlyingError=0x300b10210 {Error Domain=ASDErrorDomain Code=500 "(null)" UserInfo={NSUnderlyingError=0x300b10090 {Error Domain=AMSErrorDomain Code=301 "Invalid Status Code" UserInfo={NSLocalizedDescription=Invalid Status Code, AMSURL=https://sandbox.itunes.apple.com/WebObjects/MZBuy.woa/wa/inAppBuy?REDACTED, AMSStatusCode=500, NSLocalizedFailureReason=The response has an invalid status code}}}}} We've tried with existing sandbox user accounts, and created fresh ones which also fail in a similar way. Our beta testers report the same thing. Nothing has changed in our IAP code, and this started happening about 24-48 hours ago. It seems to be a server-side error - please can someone verify on Apple's side?
1
0
52
18h
Does SubscriptionStoreView .storeButton(for:.policies) work?
I've added .storeButton(.visible, for:.policies) to my SubscriptionStoreView, and the buttons do appear, but when I tap on them I get a sheet that just says "Terms of Service Unavailable / Somethng went wrong. Try Again.". (similar for Privacy Policy). Is this expected in development? Will these start working correctly in production? (and, more importantly, in App Review?) The docs say that these use the values (i.e. URLs) set in App Store Connect, but that I can override those. This is a new app. Is that wrong, do I need to set the URLs explicitly? Edited to add: the console reports: Failed to fetch terms of service and privacy policy: Error Domain=NSURLErrorDomain Code=-1011 "(null)"
0
0
49
1d
In App Purchases (Subscriptions)
We recently reduced the subscription price for new customers in the USA from $9.99 to $4.99. However, existing customers are also seeing the new price of $4.99, but when they attempt to purchase the subscription, they are charged the original price of $9.99. Actual Behavior: Existing Customers: See the price as $9.99 and are charged $9.99. New Customers: See the price as $4.99 and are charged $4.99. Can anyone assist with resolving this issue? Thank you!
1
0
55
2d
403 Forbidden when validating subscriptions
Hi all. Our application uses server-side validation of user subscriptions. After purchasing a subscription, the server keeps track of the subscription renewal statuses. But for the second week already, when requesting information on subscriptions, the server receives 403 Forbidden error. At first we decided that our ip was blocked somewhere and tried to change the ip to a new one. But changing the ip address did not give any results. We keep getting 403 Forbidden error on all requests to check subscriptions from our server. The request goes to the following address /verifyReceipt This method is deprecated and it is necessary to change the method of verification to a new one, but it can't be done quickly. At the moment, there is no information when verifyReceipt will be disabled. And we need to verify subscriptions. Maybe someone has encountered a similar problem? Thanks for the help!
1
0
56
3d
External Purchase Disclosure Sheet cannot be dismissed
Hello! If one of our users has previously installed a version of the app that doesn't have the External Purchase entitlement, they'll be presented with this automated disclosure sheet on app launch. This automated sheet cannot be dismissed, if you press "LearnMore", the app closes, if you try to swipe it away, the app closes. This completely blocks the user from using the app since they can't get past this disclosure sheet. I'm not allowed to link video recordings here, let me know if there's any way for me to share a recording with steps to reproduce. Thank you!
1
0
62
4d
Cancel Subscriptions on Behalf of Customer like Netflix (App Store Server API)
I recently had a request from a Product Owner to implement capability like Netflix has to enable users to switch their payment method from App Store Subscription to Credit Card on our website, as per capability that Netflix has in their account management portal. We tested it today with a colleague who was paying for Netflix through iOS in-app subscription: In the Netflix account management pages it showed that he was currently paying via In App Subscription He updated his payment method to Credit Card in their website's account management portal. Almost immediately after adding his Credit Card in his iOS Subscription Management settings (we could see the the subscription had been set to no longer renew, with an expiry date) How is this done - I can't see any API in App Store Server API documentation that gives us a way of cancelling / preventing renewal of subscriptions on behalf of a user... But Netflix can clearly do it somehow...
0
0
117
4d
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 { ...
0
0
88
5d
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.
1
0
188
2w
Cannot Receive `EXPIRED` Notifications from App Store Server Notifications V2
Hello, I am currently implementing server-side handling for in-app subscription payments and using App Store Server Notifications V2 to receive notifications with a TestFlight account. However, I am not receiving EXPIRED notifications, although I am successfully receiving other notifications such as SUBSCRIBED, DID_RENEW, and DID_CHANGE_RENEWAL_PREF. Here are some details of my observations: Until a certain point, I was receiving EXPIRED notifications without any issues, but they stopped coming in after that point. Each subscription renews every 3 minutes in TestFlight account, and I receive DID_RENEW notifications 7 to 12 times. According to the official documentation, the subscriptions should renew up to 12 times, but I am not receiving exactly 12 DID_RENEW notifications. This inconsistency might be related to the issue. Other notifications (SUBSCRIBED, DID_RENEW, DID_CHANGE_RENEWAL_PREF) are received without any issues. Could anyone provide insight into why this might be happening and suggest any alternative methods to handle subscription expirations in case the EXPIRED notifications are not reliable? Thank you for your assistance. Relevant Official Documentation App Store Server Notifications V2 App Store Server Notifications V2_notificationType Testing in-app purchases with sandbox Current Server Implementation Below is the Kotlin Spring Boot server code currently implemented for handling App Store Server Notifications V2: @RestController class ProductIosController( private val productIosService: ProductIosService, private val appStoreNotificationService: AppStoreNotificationService, ) : BaseController { @PostMapping("/api/v1/ios-products/app-store-notifications-v2") fun handleNotification(@RequestBody @Valid notification: AppStoreNotificationRequest): CustomResponse { appStoreNotificationService.processNotification(notification) return CustomResponse.ok() } } @Service class AppStoreNotificationService( @Qualifier("appStoreClient") private val appStoreServerAPIClient: AppStoreServerAPIClient, @Qualifier("signedVerifier") private val signedDataVerifier: SignedDataVerifier, ) { @Transactional fun processNotification(notification: AppStoreNotificationRequest) { logger.info("signedPayload: ${notification.signedPayload}") val decodedPayload = verifyAndDecodeSignedPayload(notification.signedPayload) val notificationType = decodedPayload.notificationType val signedTransactionInfo = decodedPayload.data.signedTransactionInfo val transaction = signedDataVerifier.verifyAndDecodeTransaction(signedTransactionInfo) val (user, product) = fetchUserAndProduct(transaction) when (notificationType) { SUBSCRIBED -> processSubscriptionPurchase(user, product, decodedPayload, transaction) DID_CHANGE_RENEWAL_PREF -> processSubscriptionGradeChange(user, product, decodedPayload, transaction) DID_CHANGE_RENEWAL_STATUS -> processRenewalStatusChange(transaction) OFFER_REDEEMED -> processOfferRedeemed(transaction) DID_RENEW -> processSubscriptionRenewal(user, product, decodedPayload, transaction) EXPIRED -> processSubscriptionExpiration(user, product) DID_FAIL_TO_RENEW -> processFailedRenewal(transaction) GRACE_PERIOD_EXPIRED -> processSubscriptionGracePeriodExpiration(transaction) PRICE_INCREASE -> processPriceIncrease(transaction) REFUND -> processSubscriptionRefund(transaction) REFUND_DECLINED -> processRefundDeclined(transaction) CONSUMPTION_REQUEST -> processConsumptionRequest(transaction) RENEWAL_EXTENDED -> processRenewalExtension(transaction) REVOKE -> processSubscriptionRevocation(transaction) TEST -> processTestNotification(transaction) RENEWAL_EXTENSION -> processRenewalExtension(transaction) REFUND_REVERSED -> processRefundReversed(transaction) EXTERNAL_PURCHASE_TOKEN -> processExternalPurchaseToken(transaction) else -> logger.warn("Unsupported notification type: ${notificationType.value}") } }
1
0
217
2w
In-App Purchase option missing in App Store version only
I just released an app to the App Store, and one of the in-app purchase options is missing. If I reinstall the TestFlight version, the option is available. If I then reinstall the App Store version, it's missing. All the other options are available and working just fine. This is how I surface them, and I've checked that all the product ids match (if they didn't they wouldn't show up in the TestFlight build). StoreView(ids: myProductIds) .productViewStyle(.compact) .storeButton(.visible, for: .restorePurchases) Any idea why one of the options wouldn't show up?
1
1
182
2w
Restrict In-app purchase offering based on location
I'm developing an application where user can access contents based on In-app purchase subscription.As per the app requirement I want to restrict user from accessing the content when they try to access from a different country. Example: Being a user I brought subscription while I was in India by paying lets say 10$ instead of actual 20$ (50% discount for India users). Lets say I am travelling to other country and in order to use the content user now has to pay the remaining 10$. As per apple's policy is this allowed? , if yes, then how to achieve this.
3
0
189
2w
Apply increased price to existing subscribers
Hi, We previously scheduled a price change (which did NOT affect existing subscribers) however months later, we have now made a decision to apply the increase to all subscribers. As the price has not increased, I only see the option to preserve and isn't obvious if this has any effect on those grandfathered in the lower price. Can anyone confirm or must I increase the price again?
1
0
160
2w
App Store Server Notifications V2 always retries five times
Hi, Our app that implemented in-app payment has been reviewed and passed and is currently in operation. However, there is a problem with the App Store server notification V2. According to the url https://developer.apple.com/documentation/appstoreservernotifications/responding_to_app_store_server_notifications, it is written as follows. "When you set up the endpoints on your server to receive notifications, configure your server to send a response. Use HTTP status codes to indicate whether the App Store server notification post succeeded: Send HTTP 200, or any HTTP code between 200 and 206, if the post was successful. Send HTTP 50x or 40x to have the App Store retry the notification, if the post didn't succeed. The system considers all other HTTP codes an unsuccessful post. Your server isn’t required to return a data value. If the App Store server doesn’t receive a success response from your server after the initial notification attempt, it retries as follows: For version 2 notifications, it retries five times, at 1, 12, 24, 48, and 72 hours after the previous attempt." We are sending an HTTP status code to the Apple server by 200 or 40x or 50x when we receive an Apple notification from the server as per the document. Nevertheless, Apple Server continues to send us 5 times App Store server notifications for each transaction. I would appreciate it if you could share how we can do it. Also, we can provide the implementation code of our server through code-level support. Thank you for your support.
3
0
225
2w
401 error when validating IAP receipt using App Store Server API before App first release
Hi, I'm using the App Store Server API for in-app purchase receipt validation. However I received 401 error status code. My app is ready for submit in App Store Connect, but not yet published the first version. The receipt is generated using StoreKit test configuration and follow the Sandbox testing instruction. It is generated on a real device using Sandbox Apple account registered in the App Sandbox tester section. If I go back to use the deprecated verifyReceipt API sandbox endpoint, I get {'status': 21002} error instead. Is it expected for an App that has not yet published in App Store? If not, is there any way to test the in-app purchase server-side validation before the App is release?
1
0
198
3w
Why is Apple refunding (6 IAP consumables) to customer even though they have exhaused their purchase?
"Jaxl Phone" a calling application. Users buy recharges to make cellular calls from the application. In this particular case, user has already utilised their recharge by making cellular calls from within the application. They have made about 4-hours of cellular calls from the app. Now, suddenly, customer started asking for REFUND from Apple. They never reached out to us. In fact, they also asked for REFUNDs for older IAP's and to our surprise, Apple has refunded all 6-IAP that the user has asked refund for. We have written twice to Apple Developer Support about it We have also hit consumption request API and used DECLINE as refund preference. But still Apple has gone ahead and issued a refund. How can we stop this scam and bleeding?
6
0
296
3w
Store kit screen automatically dismissed when using UPI payment method
I implemented a store kit in my application, which was working fine until the last three months. Recently, we have encountered an issue where the store kit screen automatically dismisses when attempting to purchase an in-app product using the UPI payment method. This issue specifically occurs with consumable products. Our non-renewable products are working fine with the same code base.
3
0
274
3w
Backyard-Birds Sample Code issue
In Apple official example code "Backyard Birds", is this code wrong? For I've tested this code many times but this part has never been executed! .onInAppPurchaseCompletion { _, purchaseResult in guard case .success(let verificationResult) = purchaseResult, case .success(_) = verificationResult else { return } showingSubscriptionStore = false } This modifier decorate code as below .sheet(isPresented: $showingSubscriptionStore) { SubscriptionStoreView(groupID: groupID) } Is it because the modifier onInAppPurchaseCompletion only works with ProductView ?
2
0
203
3w