Post not yet marked as solved
StoreKit don't work with iOS 17.4.
After updating to iOS 17.4 our users can't make any purchases in App. Its very critical bug that affected our App.
<SKPaymentQueue: 0x302bb4670>: Error in remote proxy while checking server queue: Error Domain=NSCocoaErrorDomain Code=4097 "connection to service named com.apple.storekitd" UserInfo={NSDebugDescription=connection to service named com.apple.storekitd}
[df94_SK2] Failed in XPC product request products(IDs: ["report"]): Error Domain=NSCocoaErrorDomain Code=4097 "connection to service named com.apple.storekitd" UserInfo={NSDebugDescription=connection to service named com.apple.storekitd}
Does anyone know what to do?
Post not yet marked as solved
Hello.
How can I get transaction information when a payment request is submitted to the app store server
Post not yet marked as solved
Hi,
I am following https://developer.apple.com/documentation/storekit/transaction/testing_refund_requests and trying to test refund requests.
I am able to trigger refund requests from my app (in sandbox) using https://developer.apple.com/documentation/swiftui/view/refundrequestsheet(for:ispresented:ondismiss:)
I do see that the notification URL receives a NotificationTypeV2.CONSUMPTION_REQUEST but it's not receiving NotificationTypeV2.REFUND
The product for which the refund is triggered is a consumable type
Is this expected behavior? How can I test REFUND without this?
Thanks
Post not yet marked as solved
ERROR: 💰 Product purchase for '***' failed with error: Error Domain=RevenueCat.ErrorCode Code=2 "There was a problem with the App Store." UserInfo={source_file=RevenueCat/SKError+Extensions.swift:64, NSUnderlyingError=0x600000c91890 {Error Domain=SKErrorDomain Code=0 "An unknown error occurred" UserInfo={NSLocalizedDescription=An unknown error occurred, NSUnderlyingError=0x600000c68570 {Error Domain=ASDServerErrorDomain Code=1003 "No Token Available When Expected." UserInfo={NSLocalizedFailureReason=No Token Available When Expected.}}}}, readable_error_code=STORE_PROBLEM, NSLocalizedDescription=There was a problem with the App Store., source_function=asPurchasesError}
And, I have also tested with SwiftyStoreKit and encountered the same issue.
Post not yet marked as solved
My company did an app for a customer 10 years ago. The app has in-app purchases (not subscriptions). It is an Objective-C code base. Over the years we've done minor updates to this app in order to keep it in compliance, but no major overhaul.
The app has been pretty reliable in the past, but recently my customer is getting a flood of complaints from users who say their in-app purchases disappear and can't be restored. It's happening too often to just be a case of bad internet connection or similar issue. The only thing that seems to be consistent is that it's never US-based users.
Whenever I test this app using sandbox accounts, I cannot reproduce the problems that are being reported. I'm always able to make purchases and restore them after reinstalling the app, or restore them to a different device. The content associated with the purchases always downloads correctly, even if I intentionally interrupt and restore internet access.
What can I do to figure this out? Should an IAP based app from 2014 be expected to work correctly today? Are there new legal issues with non-US app stores that we need to be aware of?
I realize there isn't a lot to go on here, but I don't have any more information.
Thanks,
Frank
Post not yet marked as solved
{NSLocalizedDescription=Reached max retry count, AMSURL=https://amp-api.sandbox.apple.com/v1/catalog/us/in-apps?extend=hostedContent&filter%5BappBundleId%5D=com.dazn.staging&filter%5BofferName%5D=BR.AP.HO.01.STAG,BR.MP.HO.01.STAG,BR.NFL.APPLE.SPP.HO.01.STAG&l=en-US&omit%5Bresource%5D=autos&platform=iphone&with=adHocOffers, AMSStatusCode=401, NSLocalizedFailureReason=Task reached max retry count (0 / 0);}
My app listens for transactions using:
for await result in Transaction.updates {
// check verification and process Transaction
}
The result coming from these updates has a jwsRepresentation field, which when decoded server-side reveals the price the user paid, discounted in the case of a custom offer code. How can I get this value without a server roundtrip? Transaction does not have price field, and the subscription product's price does not seem to include custom offer code pricing.
Hello,
I'm trying to add in-app purchases to a macOS app but failing to load the local test products. From the docs and various examples I've found online, it should be pretty straightforward with StoreKit 2.
So far, I've done the following:
added in-app purchase capability
created the local .storekit file
added consumable and non-consumable products
updated the scheme to use the test StoreKit configuration
verified the products are present and can be purchase by using Debug > StoreKit > Manage Transactions to make direct purchases
verified the product IDs are correct
To simplify things I tried creating a barebones app. I created a new .storekit file and added a single non-consumable product with ID product1. I used the default view and just a task to retrieve the products:
import SwiftUI
import StoreKit
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.task {
let products = try? await Product.products(for: ["product1"])
print(products)
}
.padding()
}
}
The print statement output is: Optional([])
I know I must be doing something wrong, but I'm completely missing it. I hope someone can help me.
Thanks
After upgrading to iOS 17.4, when using SKProductsRequest to request product information from Apple, an error is returned. The error message is "4097 Couldn’t communicate with a helper application." At present, users who have upgraded to iOS 17.4 are unable to make payments. How can we solve this problem? Thank you!
Post not yet marked as solved
Is it possible to have limited in-app quantity of an iap item? Let's say I have a premium gun which is limited to 100 quantity for the whole game. Is it possible to show the quantity remaining and hide once 100 quantity gets sold?
Thanks!
Post not yet marked as solved
Hi all, how do I get the originalTransactionId in an app after completed purchase. I use SubscriptionStoreView and onInAppPurchaseCompletion but I don't know how to extract the originalTransactionId. Any help would be appreciated.
From https://developer.apple.com/documentation/appstoreserverapi/originaltransactionid I read "To get the original transaction identifier from your app, use the originalID property of the Transaction object that represents the in-app purchase. " So I assume I can extract the originalTransactionId in the code following onInAppPurchaseCompletion
Regards
Thomas S
Post not yet marked as solved
Hello,
I'm encountering an issue where my released app fails to launch only on iOS 17.4. The version of the app released through TestFlight works fine without any issues.
Specifically, when the app installed from the App Store is launched on iOS 17.4, it immediately crashes. However, I've noticed the following:
If I turn off the network connection, such as putting the device in Airplane Mode, the app launches successfully.
Once the app is launched, I can re-enable the network connection, and the app continues to run without crashing.
My app uses StoreKit2 for handling transactions and connections with the App Store. It initiates a connection to the App Store via StoreKit2 at launch. The primary difference between the TestFlight version and the production version is the App Store endpoint they connect to. This leads me to suspect that there might be an issue with the connection to the App Store.
(Another possibility is that the app communicates with Firebase or Google Admob, so there could be an issue with these SDKs as well.)
This issue only occurs in the production version, making it difficult to investigate. Are there any suggestions on what I can do to further diagnose this issue?
You can download my app from here:
https://apps.apple.com/us/app/repeatable-player-cut-loop/id616310281
I can provide the TestFlight URL if needed.
Any help or guidance would be greatly appreciated.
Post not yet marked as solved
Hey all,
Tl;dr:
In debug-build using a .storekit file, all is good. When uploading a release build to testflight, purchasing follow the expected flow, but it does not seem the subscription status is reflected.
Full description
I've implemented auto-renewable subscriptions in my app. In debug, I've setup a scheme to use products.storekit. When I run this scheme on my device, I can subscrbe, cancel etc, and it all works as expected.
When I upload my release scheme to testflight, purchasing can be done, but changes do not seem to be reflected inside the app (i.e.e no features get unlocked).
Same thing when I run this scheme on my device. This scheme has None set for Storekit configuration.
When I set 'Storekit configuration' to the Products.storekit, file I can't make a purches at all: SubscriptionStoreView shows
Subscription unavailable. The subscription is unavailable in the current storefront'.
I've watched a number of WWDC sessions on the topic, read most (all?) of the documentation, and I just can't seem to find out what it is that needs to be done.
Unfortunately, debugging has been rather cumbersome and sometimes impossible lately, especially when trying to debug a release build.
Anyone can tell me what it is I am overlooking, or what piece of information or link I missed?
Here is the relevant code (which works OK in debug)
private func listenForTransactions() -> Task<Void, Error>
{
return Task.detached
{
for await anUpdate in Transaction.updates
{
do
{
let transaction = try self.checkVerified(anUpdate)
await self.checkSubscriptionStatus()
await transaction.finish()
}
}
}
}
And here's checkSubscriptionStatus():
@MainActor
private func checkSubscriptionStatus() async
{
var hasActiveSubscription = false
do
{
for aStatus in try await Product.SubscriptionInfo.status(for: "718A7488")
{
let state = aStatus.state
hasActiveSubscription = (state == .inGracePeriod) || (state == .subscribed)
}
}
catch
{
print(error)
}
self.hasActiveSubscription = hasActiveSubscription
}
Post not yet marked as solved
Hi all,
I've implemented in-app purchases to have auto-renewing subscriptions.
However, when I use Xcode's Transaction Manager to expire a subscription, there seems to be no callback Transaction.updates or Transaction.currentEntitlements
I can see an expiry through Transaction.all but I can't imagine the intention is to poll that while the app is running.
What am I missing here?
Post not yet marked as solved
I need to test my app's in-app purchases and I am having a very difficult time with it.
I created a "Sandbox" account in App Store connect. Doing so was very frustrating. It told me multiple times that my password was "too simple", without ever explaining what the password rules are. Then it emailed me something so I could "validate" the account. Luckily I used an actual email address that I can receive mail on. I was expecting I could use any fake address since this is a Sandbox account.
After that I started an iOS simulator and tried to log in. It immediately asked me to turn on two-factor authentication. I declined, and then it just said "User name or password is incorrect". I tried a couple more times, then I went back and actually turned on the two factor auth. But that didn't solve the problem. I still cannot log in.
Can someone explain what I'm doing wrong here?
Post not yet marked as solved
Hi All, I have this code and I would like to send the payload of the completed purchase to my server. How to do that? Regards Thomas S
`
SubscriptionStoreView(...)
.onInAppPurchaseCompletion { product, result in
if case .success(.success(let transaction)) = result {
print("Purchased successfully: \(transaction.signedDate)") // this looks good in Xcode
// Pass payload of transaction to my server
let url = URL(string: "... my server ...")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = ???? // how do I pass the payload of the transaction to the httpBody
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
let statusCode = (response as! HTTPURLResponse).statusCode
if statusCode == 200 {
print("SUCCESS")
} else {
print("FAILURE")
}
}
task.resume()
} else {
print("Something else happened")
}
}
`
Post not yet marked as solved
Hi All, I use the SubscriptionStoreView and it displays a cancellation button in the upper right corner. How do I set a value of a local variable and dismiss the SubscriptionStoreView when the user clicks the cancellation button? Right now it seems as if the cancellation button is disabled and nothing happens when I press the cancellation button.
Any help is appreciated.
Regards Thomas S
Post not yet marked as solved
Transaction.updates
When testing on TestFlight, Transaction.updates emits payments that occur on the same device (usually within 1min after payment is finished), contradicting the docs:
The asynchronous sequence that emits a transaction when the system creates or updates transactions that occur outside of the app or on other devices.
Transaction.unfinished
When testing on TestFlight, Transaction.unfinished contains finished payments from a different device (same App Store account). Docs:
A sequence that emits unfinished transactions for the user.
Both issues do not happen when testing with Xcode.
Xcode 15.2, iOS 17.3, 17.4
Post not yet marked as solved
Hi everyone,
I'm facing a weird behaviour when purchasing an auto-renewable subscription in the sandbox environment on a real device with purchase(options:) and also listening to Transaction.updates.
I get the "You're all set. Your purchase was successful [Environment Sandbox]" alert.
I receive an update through Transaction.updates. and also a transaction from Product.PurchaseResult.
Both transactions are successfully verified and have the same transactionId. Both have PURCHASE as transactionReason.
They only differ in:
deviceVerification
deviceVerificationNonce
originalPurchaseDate
signedDate
I was not expecting to receive an update through Transaction.updates as the purchase was done on the same device.
As the documentation says, Transaction.updates emits a transaction when the system creates or updates transactions that occur outside of the app or on other devices.
Am I losing something?
Thanks for your help!
Post not yet marked as solved
Hi,
We have Apple Search Ads for promoting our app.
We are able fetch attribution records of those ads using AAAttribution inside app and send to our server and it is working fine.
Now, we would like to receive Install-validation postbacks by setting NSAdvertisingAttributionReportEndpoint into our domain name and configured the server to receive HTTPS POST messages as per the instruction provided in the below link.
Steps done
Set NSAdvertisingAttributionReportEndpoint into our domain name
Our server configured the server to receive HTTPS POST messages
Made sure that updatePostbackConversionValue is called while app is launched.
https://developer.apple.com/documentation/bundleresources/information_property_list/nsadvertisingattributionreportendpoint
In our live app, we are keep getting attribution records using AAAttribution inside our app and sending them to our server. It is working fine now.
But we did not receive any Install-validation postback yet into the URL provided in NSAdvertisingAttributionReportEndpoint.
To troubleshoot this, i clicked Apple Search Ad of our app in App Store, i installed our app and opened it and in the console i can see the below error message.
Error updating install attribution pingback for app: <OUR_APP_ID>, error: Error Domain=ASDErrorDomain Code=1208 "SKAdNetwork: No pingbacks found while attempting to register/ update." UserInfo={NSLocalizedDescription=SKAdNetwork: No pingbacks found while attempting to register/update.}, result: 0
I have attached console log for your reference.
Is there any step i am missing to receive Install-validation postback in our server?
Is there any way to validate domain name provided in nsadvertisingattributionreportendpoint so that we can check if any server configuration issue?
Please advise on getting Install-validation postback in our server, Thank you.