App Store Receipts

RSS for tag

Validate app and in-app purchase receipts with the App Store using App Store Receipts.

App Store Receipts Documentation

Posts under App Store Receipts tag

79 Posts
Sort by:
Post not yet marked as solved
4 Replies
1.8k Views
Hello, I have an existing app which is beeing sold in the app store since 2010. Now I want to convert this app into a free app with optional in-app purchases. A part of the functionality which paid users currently have should then be accessible only by IAP. Therefore, I must identify my existing customers, to not make them pay again for functionality they have paid already. Googling around reveals that this is not easy to do, if it was possible at all. However, I found this post: https://stackoverflow.com/questions/3735635/convert-existing-ios-paid-app-to-freemium-model-with-in-app-purchase Quote: "There is now an Apple-approved way to do this on both iOS and macOS. The originally downloaded version of the app can be obtained from the receipt using the info key Original Purchased Version. You can then decide whether to unlock features if that version predates the switch to IAP." Now I have played around with this a bit, or more precisely: NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL]; NSData *receipt = [NSData dataWithContentsOfURL:receiptURL]; However, in my tests, receipt will always be nil. The URL also points to some local location with sandbox in the name. Am I doing something wrong in general, or is this just not supposed to work how I thought it would? Note that I have installed my app from the app store on my device, then launched the above code on my device (so I'm NOT testing this in the simulator). I also read about SKReceiptRefreshRequest, however I cant figure out how to use it. So the question is, how would I figure out if a user has already purchased the orignal paid version? My app does not have a server-component, and by checking some NSUserDefaults key would result in charging users which reinstall the app on a new device. So what should I do?
Posted
by
Post not yet marked as solved
1 Replies
865 Views
We are facing iOS appstore receipt validation connection timeout issue. I request the forum if anyone has resolved this issue in the recent past please do share your inputs. Thank you.
Posted
by
Post marked as solved
34 Replies
15k Views
We have an issue with validating in-app purchases which just seemed to start occurring today. When you send a sandbox receipt to the production endpoint (https://buy.itunes.apple.com/verifyReceipt), it returns the status code 21007 with the message. This receipt is from the test environment, but it was sent to the production environment for verification. This is documented here: https://developer.apple.com/documentation/appstorereceipts/status It is then advised to attempt this receipt on the sandbox endpoint (https://sandbox.itunes.apple.com/verifyReceipt) due to the status code returned. We have used this successfully for about a year now. We check the status code and if it is 21007, we then try the sandbox endpoint. As of today, we started seeing that the sandbox endpoint is returning a 21007 status code which does not make sense and threw our API into a recursive loop since it kept seeing that status and kept trying the sandbox endpoint. This status code is clearly wrong as it was not 'sent to the production environment' in these cases and this status code has never been returned in the past from the sandbox endpoint. Is this a bug introduced by Apple as of today or has something changed that I have not seen the documentation for?
Posted
by
Post marked as solved
9 Replies
5k Views
Because the receipt file doesn't exist at the following path, my application exits with error code 173. /Applications/Notched Up.app/Contents/_MASReceipt/receipt However unlike in the past where it then re-launches and works, I'm now getting the error message that this application is damaged and must be re-downloaded from the App Store. In the console I see the following messages. error 12:35:02.553477+0800 Notched Up (com.apple.libsqlite3) cannot open file at line 45340 of [d24547a13b] error 12:35:02.553498+0800 Notched Up (com.apple.libsqlite3) os_unix.c:45340: (2) open(/var/db/DetachedSignatures) - No such file or directory default 12:35:04.481080+0800 storeuid (com.apple.commerce) Fetching missing receipt for sandbox app /Applications/Notched Up.app default 12:35:04.707374+0800 storelegacy (com.apple.commerce) StoreLegacy: Failed to perform in-line receipt renewal for application at path /Applications/Notched Up.app : 'Error Domain=com.apple.commerce.client Code=500 "(null)"' My gut is telling me that something internal related to the App Store isn't working correctly as this code was functional a couple of weeks ago and while the first two lines show sql, this app doesn't use sqlite. App is signed with "Apple Distribution". Have tested app with "Apple Development". Have removed entitlements that need a profile and the provisioning profile. The App Store application shows the correct "Sandbox" tester account (in the preferences). I've logged the test account out and back in. I've verified that tester account is the same store locale as my main account. I've rebooted this i9 16" MBP running macOS 12.0.1, even thought it rebooted itself last night, because ???? Any advice, can you spot something I've done wrong?
Posted
by
Post not yet marked as solved
4 Replies
1.7k Views
I would like to programmatically keep track of offer codes that have been used. I just configured a Test Offer Code (Reference name), which contains 500 codes (Offer Codes) to buy a 1-month subscription for 0,49€. I was able to redeem the code and everything works, but I was expecting to receive the used code. Instead I received the Reference name in the payload from the App Store Server Notification in the field offer_code_ref_name="Test Offer Code". (expected was sth like offer_code_ref_name="JFFDS61SBJDBJ5BXJS4BX") I would be able to identify the Reference name by the code, if it was provided, because I have the following table in my app's backend: reference_name | code | url | expires_at | used | reserved Test Offer Code | xadz | zzz | 31-07-2022 | t | f Test Offer Code | asdf | *** | 31-07-2022 | f | f The used code doesn't seem to be included in the latest receipt. How can I obtain it? Can I somehow call App Store Connect API? Thanks
Posted
by
Post not yet marked as solved
2 Replies
3.2k Views
Hi, Currently we are using store kit api and we get the receipt which then backend validate from apple using /verifyReceipt. Now we are planning to move to store kit v2 api. But in this case, we are getting signedPayload instead of receipt. Now this signedPayload cannot be used in the /verifyReceipt. So what is the other way to validate the signedToken from apple and get the data that we get from the /verifyReceipt response. Thanks for the help!
Posted
by
Post not yet marked as solved
1 Replies
1.6k Views
I am using local receipt validation and the SKReceiptRefreshRequest API to restore purchases. When my iOS 16.1 users tap "restore purchase", the call fails. Notably, it does not ask the users to log into their iTunes account (it normally does) and my app logs the following error: <SKReceiptRefreshRequest: 0x281b0ad20>: Finished refreshing receipt with error: Error Domain=ASDErrorDomain Code=603 "Request throttled" UserInfo={NSLocalizedFailureReason=Unified receipt is valid and current, NSLocalizedDescription=Request throttled, AMSServerErrorCode=0} These errors started showing up after the release of 16.1 and appear to be limited to that specific version of iOS. The relevant code has not changed in years and I have iOS 15 and iOS 16.0 users who are currently able to restore purchases without issue. Also, I am not able to reproduce the issue in the sandbox but I am able to do so in production. I'm a bit at a loss. Why would my request be "throttled" and, further, why only on iOS 16.1 and only in production? Any thoughts on what could be happening here? Any help is much appreciated. Thank you!
Posted
by
Post not yet marked as solved
4 Replies
1.1k Views
Hi, Apple just rejected my app because IAP is not working. It was working yesterday of course but today I am receiving this error: ["msg": "Purchase failed. Error Domain=SKErrorDomain Code=0 \"An unknown error occurred\" UserInfo={NSLocalizedDescription=An unknown error occurred, NSUnderlyingError=0x2810320a0 {Error Domain=ASDServerErrorDomain Code=3004 \"We are temporarily unable to process your request.\" UserInfo={NSLocalizedDescription=We are temporarily unable to process your request.}}}", "error": Error Domain=SKErrorDomain Code=0 "An unknown error occurred" UserInfo={NSLocalizedDescription=An unknown error occurred, NSUnderlyingError=0x2810320a0 {Error Domain=ASDServerErrorDomain Code=3004 "We are temporarily unable to process your request." UserInfo={NSLocalizedDescription=We are temporarily unable to process your request.}}}] I know that yesterday App Store - Receipt Verification - was in outage. I am wondering if this is same problem? Does it work for you?
Posted
by
Post not yet marked as solved
1 Replies
843 Views
I have been stuck on this issue for a long time. I'm a newer in Swift and I couldn't find a way to solve this problem. I got the receipt data from my App, the code is, if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL, FileManager.default.fileExists(atPath: appStoreReceiptURL.path) { do { let receiptData = try Foundation.Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped) print(receiptData) // Read ReceiptData print("receipt: \(receiptData.base64EncodedString(options: []))") } catch { print("Couldn't read receipt data with error: " + error.localizedDescription) } } which is copied from sample code from Apple Developer Document. And this is one of the receipt data got from sandbox environment, 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 But when I use it to verify in sandbox environment, I always got 21002 error. Then I found some receipt data from stackoverflow https://stackoverflow.com/questions/33843281/apple-receipt-data-sample/53286406#53286406 . I use them to test my python code, it works. Here is the python code, receipt = "xxxxxx" url = 'https://sandbox.itunes.apple.com/verifyReceipt' headers = {"Content-type": "application/json"} data = json.dumps({"receipt-data": receipt}) res = requests.post(url=url, data=data, headers=headers, verify=False).text print(res) So, it seems that it's the receipt data I got from Apple wrong. I don't know why the receipt data is wrong. Is there anyway to find out the problem? I'm using XCode (Version 14.1 beta 2 (14B5024i)) and a iphone SE to make a test. It purchased and verified according to StoreKit 2.
Posted
by
Post not yet marked as solved
0 Replies
527 Views
I would like to determine which app version the user first downloaded. For that, I'm using StoreKit and the originalAppVersion property of AppTransaction: let verificationResult = try await AppTransaction.shared switch verificationResult { case .verified(let appTransaction): return "\(appTransaction.originalAppVersion) (\(appTransaction.environment.rawValue))" case .unverified(let appTransaction, let verificationError): // The app transaction didn't pass StoreKit's verification. The code runs fine, but always returns "1.0" for the app version and "Sandbox" for the environment. I tried debug/release builds and even pushed a build to TestFlight. Is the only way to test this to push a new App Store version that should go live?
Posted
by
Post not yet marked as solved
3 Replies
657 Views
Dear All, My iOS app used to work OK on macOS, but since a macOS update in-app purchases have stopped working. It seems that the storekitagent process is no longer able to save the receipt to the filesystem. Here is what I see in the system log after I do a "refresh receipt": default 22:03:47.822657+0100 storekitagent [58C16E76_SK1] Writing receipt (83905 bytes) to file:///Users/phil/Library/Containers/0407ACA7-9EE2-4E32-AA3E-101A1B38EE70/Data/StoreKit/sandboxReceipt error 22:03:47.823539+0100 kernel Sandbox: storekitagent(1382) deny(1) file-write-unlink /Users/phil/Library/Containers/0407ACA7-9EE2-4E32-AA3E-101A1B38EE70/Data/StoreKit/sandboxReceipt error 22:03:47.824306+0100 storekitagent [58C16E76_SK1] Error writing receipt (83905 bytes) to file:///Users/phil/Library/Containers/0407ACA7-9EE2-4E32-AA3E-101A1B38EE70/Data/StoreKit/sandboxReceipt: Error Domain=NSCocoaErrorDomain Code=513 "You don’t have permission to save the file “sandboxReceipt” in the folder “StoreKit”." UserInfo={NSFilePath=/Users/phil/Library/Containers/0407ACA7-9EE2-4E32-AA3E-101A1B38EE70/Data/StoreKit/sandboxReceipt, NSUnderlyingError=0x145c19f80 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}} Note that is a sandboxReceipt on my development system, but I have a report from a user who seems to be suffering the same problem with the app store version of the app. Is anyone else seeing this? Is there a "quick hack" I can do to grant the storekitagent process permission to write to that folder?
Posted
by
Post not yet marked as solved
1 Replies
591 Views
The app sells non-consumable in-app purchases. I also checked to enable family sharing. However, there are frequent cases where users share purchases using the family sharing function and fail when attempting to purchase or restore from a device of the shared account. Or, if a user who received the sharing makes a purchase, it will not be processed as shared payment information, but will be paid with the payment registered with the Apple ID of the current device. I used StoreKit2 and use Transaction.currentEntitlements to get payment info after purchase or restore. However, non-consumable in-app purchase information that has been shared with the family does not arrive normally. When I looked at the Storekit2 documentation, I know that there is nothing special handled or added in the API or code related to family sharing. If I'm wrong on this part or if you know a good solution to this non-consumable payment - family sharing, please advise.
Posted
by
Post not yet marked as solved
1 Replies
498 Views
Hello all, we have in-app purchases in our application. Our server is used to verify all transactions. We get transaction_id from verifyReceipts API along with other data. In the report that we get from Apple, there is no transaction_id or any common field that can uniquely identify a payment. Can we add transaction_id into reports somehow?
Post not yet marked as solved
4 Replies
872 Views
Since "2023-06-14T15:00:00Z" UTC, Too many ETIMEDOUT (https://buy.itunes.apple.com/verifyReceipt) errors have occurred. Is there any issue on buy.itunes.apple.com server? IAP server status seems okay. https://developer.apple.com/system-status/
Posted
by
Post not yet marked as solved
0 Replies
809 Views
Hello! If you see this post on stackoverflow, it's because I posted in both places. I have an app that I'm doing receipt validation via the validateReceipt endpoint (for iOS15) and the new StoreKit2 AppTransaction for iOS16. All is well until... A user reported that the app keeps telling him that there is no app receipt to validate and wants him to sign in and get a new receipt. Trouble is, his iPad is under device management from Mosyle and he doesn't have the account ID or password to sign in with. Well duh, of course not, that's handled by IT. My understanding is that the receipt is tied to the user account and the device that the app is on, so if the app is being distributed from a server then the receipt won't match the device, or possibly isn't even part of the distribution. I'm unclear on this, as all I'm getting is an alert about the receipt. I'm adding more code to detect and report on what might be happening inside the app, but in the meanwhile I have to figure out what to do to get rid of the warning prompt. My questions, after having read volumes of unhelpful information about MDM's, are simple. Is there a way to detect inside the app if the app was installed via an MDM? Can I tell from inside the app if the device is registered in an MDM? And how can I tell that the app is authorized to run on the device if the receipt validation methods aren't, well, valid? I have tried multiple combinations of search terms yet nowhere can I find out how to detect a valid MDM configuration and thus not look at the receipt. It seems the answer is either that developers aren't checking their receipt or that the solution is so blazingly simple that I'm just not seeing it.
Posted
by
Post not yet marked as solved
0 Replies
648 Views
After completing a purchase using the StoreKit 2 APIs and receiving a successful and verified Product.PurchaseResult, the local receipt is still empty. Ideally I would not need this anymore, but our server-side implementation currently requires the encoded receipt data so for my current use-case I need to access it still. My purchase flow looks like so: let purchaseResult = try await product.purchase(options: purchaseOptions) switch purchaseResult { case .success(let verification): let transaction = try checkVerified(verification) ... guard let receiptPath = Bundle.main.appStoreReceiptURL?.path else { throw Error.missingReceipt } let receiptData = NSData(contentsOfFile: receiptPath) // Receipt data is nil here let receiptString = receiptData?.base64EncodedString(options: .endLineWithLineFeed) ?? "" ... // Handle server logic ... await transaction.finish() case ... ... } My understanding was receipt data should still be generated when using StoreKit 2 APIs - is there a way to guarantee it is populated after successfully completing a purchase and during transaction handling?
Posted
by
Post not yet marked as solved
1 Replies
953 Views
As verifyReceipt has been deprecated this time, I am trying to verify the receipt using Get Transaction History Endpoint. Apparently, Apple's official document says it will return the value for a single transaction if you request it to the endpoint, but it keeps returning the value by combining all the information about different Transaction IDs. If there are developers who know about this, please answer. Also, please let me know if anyone knows how to verify the receipt using this endpoint.
Posted
by