App Store Receipts

RSS for tag

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

Posts under App Store Receipts tag

70 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Receipt Problem
We have some questions regarding the receipt fields: Our receipt validation refers to this document: Validating Receipts on the Device(https://developer.apple.com/documentation/appstorereceipts/validating_receipts_on_the_device). We would like to know if preorder receipts can also be validated using the methods outlined in the above document. If so, may I ask which ASN.1 Field Type corresponds to the preorder_date_ms? Additionally, we found other receipt fields in this document: Receipt Fields(https://developer.apple.com/library/archive/releasenotes/General/ValidateAppStoreReceipt/Chapters/ReceiptFields.html#//apple_ref/doc/uid/TP40010573-CH106-SW1). If possible, it would be appreciated if someone could supplement the definitions of each ASN.1 Field Type.
0
0
114
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
211
3w
Re-enabling cancelled subscription before the expiry date
My app has a single subscription group called Premium that contains two products with different billing periods - monthly and yearly. All tests are made in Apples's Sandbox environment with sandbox user. I am currently testing a scenario, where the user is subscribed to the monthly product, subsequently cancels the subscription from the App Store subscriptions page, and before the subscription expires, he wants to re-enable it (same monthly product). If the subscription is re-enabled from the App Store subscriptions page, my server gets a notification about the changed subscription renewal status and everything works well. This scenario is documented at the bottom of the page here: https://developer.apple.com/documentation/storekit/in-app_purchase/testing_in-app_purchases_with_sandbox/testing_disabling_auto-renew#3780478 I however also want to support the scenario where the user can re-enable the subscription before it expires from the app itself. To do so, if the subscription is cancelled, but not yet expired, I show the user a button Re-activate. When this button is clicked, I initiate a purchase of the same monthly product, the IAP correctly shows the payment sheet and once I click Subscribe in the In App Purchase payment sheet, it goes through without any issues. However, my app subsequently receives a callback that the purchase failed: <SKPaymentQueue: 0x280f1fa10>: Payment completed with error: Error Domain=ASDErrorDomain Code=500 "Unhandled exception" UserInfo={NSUnderlyingError=0x2803a4720 {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}}, NSLocalizedFailureReason=An unknown error occurred, NSLocalizedDescription=Unhandled exception} This seems like the purchase failed with invalid status, but strangely enough, my server receives a notification that the subscription renewal status was changed to AUTO_RENEW_ENABLED and if I check the App Store subscriptions, I can see that its not cancelled anymore. The subscription also gets renewed at the end of the billing period, where it would have otherwise been cancelled. So in other words, everything seems to work except the purchase error above. My question is, what could be the reason for this? Perhaps Apple does not support re-enabling subscription directly from the App, but only from the App Store subscription page? Or perhaps its just a limitation of Apple's sandbox environment and I would not receive this payment error in production environment?
0
1
190
4w
App rejected for 1.4.0 Safety: Physical Harm
Hi, I developped an app which is an alcohol level calculator (cf image for few screens). I did lots of modification to the app is accepted, but none works. I also asked to the verification team, but they can't help me more. However similar app already exists like https://apps.apple.com/fr/app/alcootel-by-maaf/id6444157056 or https://apps.apple.com/fr/app/%C3%A9thylom%C3%A8tre/id688242393. I even copy the description of the first app. So, could you help me about what I can change in order to the app is validated, or do the new rules make my app "out of the Apple laws". Thank you
0
0
199
Apr ’24
Extracting Transaction IDs from App Receipts
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
2
0
324
Apr ’24
Regular check of subscription status for IAP
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.
1
0
341
Apr ’24
verifyReceipt API returns a status of 21005.
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?
2
0
391
Mar ’24
Visit https://sandbox.itunes.apple.com/verifyReceipt failed
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.
2
0
441
Mar ’24
paymentQueue FinishTransaction never gets called after in app purchase
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]) { // } }
1
0
363
Apr ’24
verifyReceipt The underlying connection was closed: An unexpected error occurred on a send
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...
3
0
446
Mar ’24
which auto_renew_status field I should use to identify user action?
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" }
1
0
335
Mar ’24
TLS_ISSUE with IAP Server Setup on AppStore Connect
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.
1
0
439
Feb ’24
Receipt Verification 21004 code for Consumable Item on Production
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,
2
0
482
Feb ’24
Missing receipt and verification
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
1
0
441
Jan ’24
Receiving the same original transactional ID for two different subscriptions has occurred.
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": "" }], } }
1
0
485
Jan ’24
Verification failed with status INVALID_APP_IDENTIFIER
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)```
2
0
867
Feb ’24