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
0 Replies
43 Views
Hello everyone, I'm currently in the process of updating my code to remove the deprecated verifyReceipt method in line with the latest documentation and guidelines. I have a question regarding the Receipt Usage example provided in the documentation here: https://github.com/apple/app-store-server-library-java?tab=readme-ov-file#receipt-usage ReceiptUtility receiptUtil = new ReceiptUtility(); String transactionId = receiptUtil.extractTransactionIdFromAppReceipt(appReceipt); My question is: Why does this method only return one transactionId? I had assumed that it might return a list of different transaction IDs present in the encoded receipt. Thank you in advance for any assistance! Best regards, Maria
Posted
by mariadab.
Last updated
.
Post not yet marked as solved
1 Replies
180 Views
I have implemented this StoreObserver and I have registered it in AppDelegate but my paymentQueue func never gets called whenever there is a successful purchase. The reason I need it to be called is firstly to finish the transaction but to also send the device receipt to the server. Currently, my receipt is always null. The purchases themselves work OK, both in XCode and in Sandbox. I can't figure out what I'm doing wrong in terms of the setup of the storeobserver. Any help will be greatly appreciated. AppDelegate.swift let iapObserver = StoreObserver.shared func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { UIApplication.shared.registerForRemoteNotifications() UNUserNotificationCenter.current().delegate = self SKPaymentQueue.default().add(iapObserver) return true } StoreObserver.swift class StoreObserver: NSObject, SKPaymentTransactionObserver { static var shared = StoreObserver() func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { for transaction in transactions { switch (transaction.transactionState) { case .purchased: SKPaymentQueue.default().finishTransaction(transaction) //print the receipt but it is always nil. (I will be saving this on the backend for validation) if let url = Bundle.main.appStoreReceiptURL, let data = try? Data(contentsOf: url) { var receiptDataString = data.base64EncodedString() print(receiptDataString) } break case .failed: SKPaymentQueue.default().finishTransaction(transaction) break case .restored: SKPaymentQueue.default().finishTransaction(transaction) break case .deferred, .purchasing: break default: break } } } func paymentQueue(_ queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) { // } func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) { // } func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) { // } func paymentQueue(_ queue: SKPaymentQueue, updatedDownloads downloads: [SKDownload]) { // } }
Posted Last updated
.
Post not yet marked as solved
1 Replies
123 Views
Hi, For a user who subscribed a product via In-App Purchase, how does the application backend know that the user is still subscribed? The initial purchase happens on the mobile app. Via receiving and validating the receipt of initial purchase, the backend of mobile app would be informed. However, what is the appropriate option for the subsequent subscription payments? How do I know whether the user is still paying? Thanks.
Posted
by selbe.
Last updated
.
Post not yet marked as solved
1 Replies
141 Views
We are using apple's verifyReceipt API. (https://buy.itunes.apple.com/verifyReceipt) In one receipt, it returns a status of 21005. This probrem is occured by not all receipt but one receipt. The documentation describes it as "The receipt server was temporarily unable to provide the receipt. Try again.". (https://developer.apple.com/documentation/appstorereceipts/status) However, after more than a month, the API still returns the same status for this receipt. Does anyone know the cause of this?
Posted Last updated
.
Post not yet marked as solved
2 Replies
200 Views
Hi When we add IAP for our app a few years ago, we setup our server to visit https://sandbox.itunes.apple.com/verifyReceipt, to verify our customer's receipt after the purchase the IAP. Everything goes well for the past few years. But since March 22, 2024, our server cannot visit the URL above any more, and the returned failure is "SSLException: Received fatal alert: protocol_version"(from JAVA). From this we guess that Apple have made some changes about the SSL/TLS protocol requirement of your server api. Could you guys tell us which SSL/TLS is required to visit this URL? We need these information to make a plan of our server code upgrade or something like that, and continue the receipt verification. Thank you. Hope to hear from you soon.
Posted
by neuswcjr.
Last updated
.
Post not yet marked as solved
1 Replies
223 Views
Hi, Starting this weekend our backend fails to connect to the production Apple verifyReceipt endpoint. It's a C# .NET service running on windows server. The full exception received is: Exception: "The underlying connection was closed: An unexpected error occurred on a send". Inner Exception: "Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host". Is someone else facing a similar issue? sending a request to the Apple production verifyReceipt URL via Postman (located on the same server) succeeds. Thanks in advance...
Posted Last updated
.
Post not yet marked as solved
1 Replies
181 Views
I received a version 1 server notification. auto_renew_status is true and another pending_renewal_info.auto_renew_status is 0. So did the user turn the subscription on or off? What does this mean and which field I should use to identify user action? Could anyone help me with that? The contents are as follows: { "environment": "PROD", "unified_receipt": { "status": 0, "environment": "Production", "latest_receipt_info": [ { "quantity": "1", "product_id": "com.protect.adpatrol.weekly2", "expires_date": "2023-03-19 18:12:56 Etc/GMT", "purchase_date": "2023-03-12 18:12:56 Etc/GMT", "transaction_id": "700001139057782", "expires_date_ms": "1679249576000", "is_trial_period": "false", "expires_date_pst": "2023-03-19 11:12:56 America/Los_Angeles", "purchase_date_ms": "1678644776000", "purchase_date_pst": "2023-03-12 11:12:56 America/Los_Angeles", "in_app_ownership_type": "PURCHASED", "original_purchase_date": "2023-02-28 06:18:59 Etc/GMT", "web_order_line_item_id": "700000519235393", "original_transaction_id": "700001128802427", "is_in_intro_offer_period": "false", "original_purchase_date_ms": "1677565139000", "original_purchase_date_pst": "2023-02-27 22:18:59 America/Los_Angeles", "subscription_group_identifier": "20900376" }, { "quantity": "1", "product_id": "com.protect.adpatrol.weekly2", "expires_date": "2023-03-03 06:18:57 Etc/GMT", "purchase_date": "2023-02-28 06:18:57 Etc/GMT", "transaction_id": "700001128802427", "expires_date_ms": "1677824337000", "is_trial_period": "true", "expires_date_pst": "2023-03-02 22:18:57 America/Los_Angeles", "purchase_date_ms": "1677565137000", "purchase_date_pst": "2023-02-27 22:18:57 America/Los_Angeles", "in_app_ownership_type": "PURCHASED", "original_purchase_date": "2023-02-28 06:18:59 Etc/GMT", "web_order_line_item_id": "700000519235392", "original_transaction_id": "700001128802427", "is_in_intro_offer_period": "false", "original_purchase_date_ms": "1677565139000", "original_purchase_date_pst": "2023-02-27 22:18:59 America/Los_Angeles", "subscription_group_identifier": "20900376" } ], "pending_renewal_info": [ { "product_id": "com.protect.adpatrol.weekly2", "auto_renew_status": "0", "auto_renew_product_id": "com.protect.adpatrol.weekly2", "original_transaction_id": "700001128802427" } ] }, "auto_renew_status": "true", "notification_type": "DID_CHANGE_RENEWAL_STATUS", "auto_renew_product_id": "com.protect.adpatrol.weekly2", "original_transaction_id": 700001128802427, "auto_renew_status_change_date": "2023-03-12 18:12:58 Etc/GMT", "auto_renew_status_change_date_ms": "1678644778000", "auto_renew_status_change_date_pst": "2023-03-12 11:12:58 America/Los_Angeles" }
Posted
by chasel_h.
Last updated
.
Post not yet marked as solved
3 Replies
275 Views
Steps: Configure iOS App IAP Run the app and purchasing finished with sandbox account Get the receipt data from Bundle.main.appStoreReceiptURL Verify the receipt Result: receipt data error 21002 Analysis: the base64Encoding should be ok. It seems that the receipt data itself is wrong. How to find the root cause? Thanks!
Posted Last updated
.
Post not yet marked as solved
2 Replies
565 Views
Hi, We are trying to verify transaction IDs using the App Store Server Library for Python. We have been able to successfully send a test notification, but then when trying to get transaction information for a specific transaction ID we are receiving the InvalidAppIdentifierError (error code: 4000002). We have verified that the bundle_id is correct and matches what we see in App Store Connect, and the bundle_id seems to be valid and work when we sent a test notification. We have also tried setting the bundle_id to be equal to our <TEAM ID>.<BUNDLE_ID>, which is the format for the application-identifier in our TestFlight Build Metadata, but we still receive the same error when doing so. We would greatly appreciate any help or advice on how to resolve this, and please let me know if any more information is needed to help us. import os from appstoreserverlibrary.api_client import AppStoreServerAPIClient, APIException from appstoreserverlibrary.models.Environment import Environment from appstoreserverlibrary.signed_data_verifier import VerificationException, SignedDataVerifier from typing import List private_key_path = "REDACTED" with open(private_key_path, 'rb') as file: private_key = file.read() key_id = "REDACTED" issuer_id = "REDACTED" bundle_id = "REDACTED" environment = Environment.SANDBOX client = AppStoreServerAPIClient(private_key, key_id, issuer_id, bundle_id, environment) def load_root_certs(root_certificate_dir: str) -> List[bytes]: root_certificates = [] for file_name in os.listdir(root_certificate_dir): if not file_name.endswith('.cer'): continue root_cert = file_name with open(os.path.join(root_certificate_dir, root_cert), 'rb') as file: root_certificates.append(file.read()) return root_certificates root_certificates = load_root_certs("REDACTED") enable_online_checks = True signed_data_verifier = SignedDataVerifier(root_certificates, enable_online_checks, environment, bundle_id) try: response = client.get_transaction_info(transaction_id_ios) signed_transaction_info = response.signedTransactionInfo or "" print(signed_transaction_info) payload = signed_data_verifier.verify_and_decode_notification(signed_transaction_info) print(payload) except (APIException, VerificationException) as e: print(e)```
Posted Last updated
.
Post not yet marked as solved
0 Replies
282 Views
I am going to offer a Bundle of ten(10) apps having auto-renewing subscriptions. My question is when user will purchase a subscription in ONE app. Will all other apps(non-purchased) also have RECEIPT available of the one purchased app's receipt? So,i can validate user have purchased one of apps from Bundle.
Posted
by israr786.
Last updated
.
Post not yet marked as solved
4 Replies
1.4k Views
Hello! Please let me know after I make a request for purchase information GET https://api.storekit-sandbox.itunes.apple.com/inApps/v1/transactions/2000000411047647 I receive encrypted information in this format { "signedTransactionInfo":"eyJhbGciOiJFUzI1NiIsIng1YyI6WyJNSUlFTURDQ0E3YWdBd0lCQWdJUWZUbGZkMGZOdkZXdnpDMVlJQU5zWGpBS0JnZ3Foa2pPUFFRREF6QjFNVVF3UWdZRFZRUURERHRCY0hCc1pTQlhiM0pzWkhkcFpHVWdSR1YyWld4dmNHVnlJRkpsYkdGMGFXOXVjeUJEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVURUxNQWtHQTFVRUN3d0NSell4RXpBUkJnTlZCQW9NQ2tGd2NHeGxJRWx1WXk0eEN6QUpCZ05WQkFZVEFsVlRNQjRYRFRJek1Ea3hNakU1TlRFMU0xb1hEVEkxTVRBeE1URTVOVEUxTWxvd2daSXhRREErQmdOVkJBTU1OMUJ5YjJRZ1JVTkRJRTFoWXlCQmNIQWdVM1J2Y21VZ1lXNWtJR2xVZFc1bGN5QlRkRzl5WlNCU1pXTmxhWEIwSUZOcFoyNXBibWN4TERBcUJnTlZCQXNNSTBGd2NHeGxJRmR2Y214a2QybpBQmhpVm9kSFJ3T2k4dmIyTnpjQzVoY0hCc1pTNWpiMjB2YjJOemNEQXpMWGQzWkhKbk5qQXlNSUlCSGdZRFZSMGdCSUlCRlRDQ0FSRXdnZ0VOQmdvcWhraUc5Mk5rQlFZQk1JSCtNSUhEQmdnckJnRUZCUWNDQWpDQnRneUJzMUpsYkdsaGJtTmxJRzl1SUhSb2FYTWdZMlZ5ZEdsbWFXTmhkR1VnWW5rZ1lXNTVJSEJoY25SNUlHRnpjM1Z0WlhNZ1lXTmpaWEIwWVc1alpTQnZaaUIwYUdVZ2RHaGxiaUJoY0hCc2FXTmhZbXhsSUhOMFlXNWtZWEprSUhSbGNtMXpJR0Z1WkNCamIyNWthWFJwYjI1eklHOW1JSFZ6WlN3Z1kyVnlkR2xtYVdOaGRHVWdjRzlzYVdONUlHRnVaQ0JqWlhKMGFXWnBZMkYwYVc5dUlIQnlZV04wYVdObElITjBZWFJsYldWdWRITXVNRFlHQ0NzR0FRVUZCd0lCRmlwb2RIUndPaTh2ZDNkM0xtRndjR3hsTG1OdmJTOWpaWEowYVdacFkyRjBaV0YxZEdodmNtbDBlUzh3SFFZRFZSME9CQllFRkFNczhQanM2VmhXR1FsekUyWk9FK0dYNE9vL01BNEdBMVVkRHdFQi93UUVBd0lIZ0RBUUJnb3Foa2lHOTJOa0Jnc0JCQUlGQURBS0JnZ3Foa2pPUFFRREF3Tm9BREJsQWpFQTh5Uk5kc2twNTA2REZkUExnaExMSndBdjVKOGhCR0xhSThERXhkY1BYK2FCS2pqTzhlVW85S3BmcGNOWVVZNVlBakFQWG1NWEVaTCtRMDJhZHJtbXNoTnh6M05uS20rb3VRd1U3dkJUbjBMdmxNN3ZwczJZc2xWVGFtUllMNGFTczVrPSIsIk1JSURGakNDQXB5Z0F3SUJBZ0lVSXNHaFJ3cDBjMm52VTRZU3ljYWZQVGp6Yk5jd0NnWUlLb1pJemowRUF3TXdaekViTUJrR0ExVRWUVFERER0QmNIQnNaU0JYYjNKc1pIZHBaR1VnUkdWMlpXeHZjR1Z5SUZKbGJHRj000OUJBTURBMmdBTUdVQ01RQ0Q2Y0hFRmw0YVhUUVkyZTN2OUd3T0FFWkx1***5UmhIRkQvM21lb3locG12T3dnUFVuUFdUeG5TNGF0K3FJeFVDTUcxbWloREsxQ" } Please tell me how I can decode the information signedTransactionInfo ? and what is needed for this? (I'm trying to decode on Node.js)
Posted Last updated
.
Post not yet marked as solved
1 Replies
282 Views
Hi colleagues! I've encountered a technical issue during the setup of my In-App Purchase (IAP) server for my app (com.forgetmenuts) on AppStore Connect. In the "Info" section of my app's page on AppStore Connect, I've configured the "App Store Server Notifications" endpoints to: https://sys-conf.com/hooks/subscription/ios/debug. Here's the challenge I'm facing: When I initiate a "Request a Test Notification," everything seems to function as expected. I successfully receive the "testNotificationToken." However, the issue arises when I attempt to request the status of this token. At this stage, I encounter an error with the firstSendAttemptResult indicating a TLS_ISSUE. the error is described here: app store docs. I have verified the TLS configurations of my domain (sys-conf.com). Both TLS 1.2 and 1.3 are active and functioning correctly (verified through this TLS Checker: site24x7.com/tools/tls-checker.html I am looking for guidance on how to resolve this TLS issue. Any insights or suggestions from the community would be greatly appreciated, especially from those who might have faced and resolved similar challenges.
Posted
by luck-duck.
Last updated
.
Post not yet marked as solved
2 Replies
320 Views
Hello, One of our customer's purchases of IAP consumable product have issue on its receipt verification. Verification via "https://buy.itunes.apple.com/verifyReceipt" returns {"environment": "Production", "status": 21004}. He purchased 3 consumable items and only verification of 3rd purchase successfully got verified. All of other purchases in our app before and after had no problem with same secret, same server. I once heard 21004 is for auto renewable subscription, not for consumable. Can it be returned for consumable purchase? Is there any other known issue for receipt verification? We have no change of code, server, secret at that time and all other verification succeeded but two failed. Thanks in advance. Regards,
Posted
by Tak19.
Last updated
.
Post not yet marked as solved
1 Replies
309 Views
Hi, I have two projects (older ones, but rebuild and adjusted for the newest versions) made in XCode 15.2 in objective-c. Now I want to put it on app store. I'm trying to validate receipt but the receipt is not downloaded in _MASReceipt/reciept in App Bundle. I'm trying: NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL]; NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL]; but dataWithContentsOfURL returns missing file, the receipt is not created. Can you help me, what I missing here? Thank you
Posted
by _Filip_.
Last updated
.
Post not yet marked as solved
1 Replies
337 Views
User purchased the initial subscription and transmitted the relevant data to our server, where the receipt is stored for subscription validation. As per the documentation, the "Original Transaction Identifier" is expected to be unique across all receipts in a chain of renewals for an auto-renewable subscription. Specifically, for subscription "S1," all auto-renewed receipts consistently share the same original transaction ID. However, following several auto-renewals of the first subscription (User 1), information from Apple's response revealed details about a second subscription (S2), and remarkably, the second subscription (User 2) has the same original transaction ID as the first one. Is there a potential connection with Apple's test environment? We currently lack any information or clues regarding the differentiation of accounts. Webhook Request from App Store (iOS Payment Notification) For Subscription (S1) - For User 1 { "id": "***", "auto_renew_adam_id": "***", "auto_renew_product_id": "com.globalmed.loveeveryday.monthlysub", "auto_renew_status": "true", "unified_receipt": { "id": "", "environment": "", "latest_receipt": "", "latest_receipt_info": [ { "id": "***", "expires_date": "2024-01-19 05:47:24Etc\/GMT", "expires_date_ms": "1705686444000", "expires_date_pst": "***", "in_app_ownership_type": "***", "is_in_intro_offer_period": "***", "is_trial_period": "true", "is_upgraded": "false", "offer_code_ref_name": "", "original_purchase_date": "2023-05-19 03:54:26Etc\/GMT", "original_purchase_date_ms": "", "original_purchase_date_pst": "", "original_transaction_id": "580000785864406", "promotional_offer_id": "", "product_id": "com.globalmed.loveeveryday.monthlysub", "purchase_date": "2023-11-19 04:54:20Etc\/GMT", "purchase_date_ms": "1700412860000", "purchase_date_pst": "", "quantity": "", "subscription_group_identifier": "", "transaction_id": "580001118634891", "web_order_line_item_id": "" }], } } For Subscription (S2) for For User 2 { "id": "***", "auto_renew_adam_id": "***", "auto_renew_product_id": "com.globalmed.loveeveryday.monthlysub", "auto_renew_status": "true", "unified_receipt": { "id": "", "environment": "", "latest_receipt": "", "latest_receipt_info": [ { "id": "***", "expires_date": "2024-02-19 05:47:24Etc\/GMT", "expires_date_ms": "1708364844000", "expires_date_pst": "***", "in_app_ownership_type": "***", "is_in_intro_offer_period": "***", "is_trial_period": "true", "is_upgraded": "false", "offer_code_ref_name": "", "original_purchase_date": "2024-01-08 04:37:02Etc\/GMT", "original_purchase_date_ms": "1704731822996", "original_purchase_date_pst": "", "original_transaction_id": "580000785864406", "promotional_offer_id": "", "product_id": "com.globalmed.loveeveryday.monthlysub", "purchase_date": "2024-01-19 05:47:24Etc\/GMT", "purchase_date_ms": "1705686444000" , "purchase_date_pst": "", "quantity": "", "subscription_group_identifier": "", "transaction_id": "580001139103833", "web_order_line_item_id": "" }], } }
Posted
by marun22.
Last updated
.
Post not yet marked as solved
1 Replies
380 Views
first, i am new with apple in-app purchase. in-app purchase step (is this right?): front processing in-app purchase. front send receipt data to validate on server (server get transaction to check it) confirm purchase to apple the 3rd step i know that front can confirm the purchase. my question: from the the 3rd step, can server confirm it after validated? if it can, how do i imprement it?
Posted
by Fice.
Last updated
.
Post not yet marked as solved
0 Replies
369 Views
Hello, I want to provide in- app subscription option for my application services inside other apps. Is this possible? Does Apple in app subscription guidelines allow this? Reading the guidelines this use case is not clear. UseCase: I am embedding the services that my app provides inside other 3rd party apps (embed my application Framework/library within the other application) but want to provide in-app subscription option to use services provided by my library. Users can purchase this service by subscribing to monthly subscription option using Apple in-app subscription. Because there are multiple other 3rd party applications that will include my library and since these 3rd party applications in some cases are not from the same developer account I do not want to use individual in-app subscription for each application. Instead, I am looking for a way to create in-app subscription from my main application and provide the same purchase option within all other 3rd party apps that embed my application library. Can this be done? Does Apple in-app subscription allow this use case?
Posted Last updated
.
Post not yet marked as solved
1 Replies
482 Views
This is re-posted from this Stack Overflow post. I am looking at validating the purchase of a paid app from Mac AppStore. Based on this WWDC video about StoreKit 2, I am attempting to this with AppTransaction. I have not found meaningful high-level documentation about this specific use case beyond that. My approach is to first get the "cached" AppTransaction by calling AppTransaction.shared. If that is not there I proceed to getting it from Apple, via AppTransaction.refresh(). If they don't have it, or when the network is down, the user automagically gets the familiar "log in to your store account" UI that has been around as long as the Mac AppStore. Once I have the AppTransaction I use it to verify we are on the right device, using code like this, where the returned Bool represents validation success: guard let deviceVID = AppStore.deviceVerificationID?.uuidString.lowercased() else { return false } let nonce = appTransaction.deviceVerificationNonce.uuidString.lowercased() let combo = nonce + deviceVID let digest = SHA384.hash(data: Data(combo.utf8)) return (digest == appTransaction.deviceVerification) My first question is: Does that look like the right approach? Is there something else I should do, or check? My second question is around testing this approach. Refreshing the AppTransaction in the sandbox invariably yields a valid item, even if the app version does not yet exist in AppStoreConnect. This is also the case when I log out in the App Store app on the Mac. This makes me think it is using my AppleID which I am logged into in System Settings. Does that sound right? I would like to be able to remove / delete the cached AppTransactions - where might I find those on the system? Thanks for everyone's help!
Posted
by rainer.
Last updated
.