App Store Server API

RSS for tag

Call this REST API from your server to request and provide information about your customers' in-app purchases.

App Store Server API

Posts under App Store Server API tag

84 Posts
Sort by:
Post not yet marked as solved
2 Replies
424 Views
I have an app in which there are two different subscription groups and One non-consumable product. User can have two(2) subscriptions and one non-consumable purchase [total three purchases] at a time. All three have different "originalTransactionIdentifier". How can i get user's purchase History in ONE App store server API request?
Posted
by israr786.
Last updated
.
Post not yet marked as solved
1 Replies
518 Views
in-app purchase: when client commit the purchase, client will send the purchase data to the server, server will get transaction to read the information but when i tested on sandbox, i get the transaction i got { errorCode: 4040010, errorMessage: 'Transaction id not found.' } give me some advice please.
Posted
by Fice.
Last updated
.
Post not yet marked as solved
1 Replies
376 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
0 Replies
382 Views
I don't often get CONSUMPTION_REQUEST or indeed REFUND but when I do I receive the same CONSUMPTION_REQUEST 3 times, 8 hours apart, before I do get the REFUND notification several hours after the 3rd and final CONSUMPTION_REQUEST. The response I get from the PUT of /inApps/v1/transactions/consumption/{transactionId} is 202 so I can only assume it was accepted and good. Is the fact I received it 3 times an indication that it was poorly formatted or incorrect somehow? Is there anyway to test the consumption PUT? I've yet to see an in-app consumable that I received a CONSUMPTION_REQUEST for, that was 100% consumed, and wasn't REFUND_DECLINED. They have all been refunded to date. This makes me suspicious that I'm doing something wrong even though all the information I'm getting says otherwise?
Posted
by Seoras68.
Last updated
.
Post not yet marked as solved
1 Replies
418 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
405 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 marked as solved
1 Replies
455 Views
Hello. Currently, I am testing for the transition to the App Store Server API(v1/transactions/{transactionId}) as the verifyReceipt API we are utilizing has become deprecated. API currently in use: https://developer.apple.com/documentation/appstorereceipts/verifyreceipt API planned to switch to: https://developer.apple.com/documentation/appstoreserverapi/get_transaction_info I am doing the testing in the sandbox, but I cannot acquire a valid transaction_id with the App Store Server API. Below, I am detailing what I conducted. 1.I call the verifyReceipt API and receive a response. ※Here's a part of the response. The product_id is a dummy. "latest_receipt_info": [ { "quantity": "1", "product_id": "dummy_product_id", "transaction_id": "2000000497573524", "original_transaction_id": "2000000293926363", "purchase_date": "2024-01-11 03:06:43 Etc/GMT", "purchase_date_ms": "1704942403000", "purchase_date_pst": "2024-01-10 19:06:43 America/Los_Angeles", "original_purchase_date": "2023-03-10 04:11:01 Etc/GMT", "original_purchase_date_ms": "1678421461000", "original_purchase_date_pst": "2023-03-09 20:11:01 America/Los_Angeles", "expires_date": "2024-01-11 03:11:43 Etc/GMT", "expires_date_ms": "1704942703000", "expires_date_pst": "2024-01-10 19:11:43 America/Los_Angeles", "web_order_line_item_id": "2000000047921358", "is_trial_period": "false", "is_in_intro_offer_period": "false", "in_app_ownership_type": "PURCHASED", "subscription_group_identifier": "20230239" } ], 2.I call the App Store Server API. Request used with transaction_id: https://api.storekit-sandbox.itunes.apple.com/inApps/v1/subscriptions/2000000497573524 Request used with original_transaction_id: https://api.storekit-sandbox.itunes.apple.com/inApps/v1/subscriptions/2000000293926363 3.I receive an error stating the transaction id cannot be found. Response: 404 Not Found: "{"errorCode":4040010,"errorMessage":"Transaction id not found."}" Additionally, as I found similar questions, I also tried shifting the numbers of the transaction_id and original_transaction_id when calling the App Store Server API. However, this did not resolve the error I received. https://developer.apple.com/forums/thread/84812 https://developer.apple.com/forums/thread/68944 In this case, what should I do with the transactionId to get the Transaction information? I would appreciate it if anyone who knows can enlighten me. Thank you in advance.
Posted
by nkekorc.
Last updated
.
Post not yet marked as solved
2 Replies
771 Views
Hello. I have a question about migrating from Original StoreKit to StoreKit2. In my app, there are two in-app purchase products implemented using Original StoreKit: Product A and Product B. For each product, there are separate backend servers, and due to certain reasons, we need to migrate one of those servers to use the AppStore Server API instead of the VerifyReceipt API. During this migration, the iOS app needs to have code that combines both Original StoreKit and StoreKit2 for each product. I heard that combining StoreKit2 with the VerifyReceipt API is not recommended. To avoid doing so, I believe the implementation would look like the below. Is this approach problematic? Is it not recommended by Apple? If anyone has successfully implemented a similar migration and has insights, I would appreciate hearing about it. Code implemented using Original StoreKit SKPaymentQueue.default().add(payment) func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) { for transaction in transactions.filter({ $0.payment.productIdentifier.hasPrefix("...Original StoreKit product only...")}) { switch transaction.transactionState { case .purchasing: break case .deferred: print(Messages.deferred) case .purchased: handlePurchased(transaction) // send base64 encoded receipt file. case .failed: handleFailed(transaction) case .restored: handleRestored(transaction) @unknown default: fatalError(Messages.unknownPaymentTransaction) } } } Code implemented using StoreKit2 let result: Product.PurchaseResult = try await product.purchase() switch result { case .success(let verification): let transaction = try checkVerified(verification) // send transaction id // ... await transaction.finish() case .pending: break case .userCancelled: break @unknown default: break } func observeTransactions() -> Task<Void, Error> { return Task(priority: .background) { for await result in Transaction.unfinished { do { let transaction = try self.checkVerified(result) guard transaction.productID.hasPrefix("... StoreKit2 product only...") else { return } // send transaction id // ... await transaction.finish() } catch { // ... } } } }
Posted Last updated
.
Post not yet marked as solved
0 Replies
354 Views
Hi! I have an iOS app which I want to publish to the App Store. Within my app, users can scan physical item bar codes in grocery stores and earn points for their scans. They are then re-directed to a marketplace on the web, where they can spend these points on physical items (e.g. clothes). Does App Store block such external linking to marketplace? Thank you in advance!
Posted Last updated
.
Post marked as solved
1 Replies
543 Views
We want to know whether the refund requested by the user for the consumable IAP of Apple is refunded fully or partially. I can get the revocation date on when the refund was processed but I also want to know whether the user got a refund fully or partially and its amount as well if possible. we tried to get transaction info and also the refund history of App Store Server API but we are only getting the revocation date and revocation reason we also want to know if the refund was processed as fully or partially and how much money did the user got back on refund successful. Also checked the webhook data we get for REFUND notificationType, we don't get back any field that helps us identify whether refund was full or partial and its amount as well.
Posted
by Ravi1207.
Last updated
.
Post not yet marked as solved
1 Replies
308 Views
my find documents(app store server notifications and app store server api), not find next billing date description, i want new subscription and renew subscription send email to customer, context contains next billing date
Posted
by huangjx.
Last updated
.
Post not yet marked as solved
1 Replies
536 Views
We are currently managing four root certificates. Checked the ChainVerifier class code in 'App Store Server Library'. I checked that the root certificate was excluded when I called the CertPathValidator.validate method. So the root certificate is not falsified? Is it okay if I don't even check my fingerprints?
Posted
by bisu.
Last updated
.
Post marked as solved
1 Replies
660 Views
We're able to successfully perform test notifications using the app-store-server-library-python in SANDBOX environment, but the second we switch to PRODUCTION (for testing purposes), the call fails with 401 and it doesn't seem to reach our server at all. This suggests that something is wrong with singing production environment headers, however I've seen posts from others that suggest this is not specific to the App Store server library code. It's very clear that the libraries are marked Beta – however, most replies to questions about the v2 API are replied to with suggestions to use the library. Just FWIW – there's some contradictory advice there. Anyway, the main point is that we're currently blocked on making sure that our v2 API hooks are working properly, since we can't send production test notifications. Any idea why the signed requests would work to send sandbox test notifications, but not production environment? We've triple checked the URLs, etc – as far as we know, the private key should be the same regardless of environment. Thanks! (P.S. If anyone has been able to send v2 test notifications with the PRODUCTION environment, please let us know!)
Posted Last updated
.
Post not yet marked as solved
1 Replies
730 Views
Is the Apple root certificate in the App Store Server API response always 'Apple Root CA - G3'? When isn't it? What criteria should I set for the 'performRevocationChecking' parameter value of the verifyChain method of the ChainVerifier class in the App Store Server Library? I am implementing the 'App Store Server API' call myself. Do you include the root certificate in the certificate chain verification process? Can root certificates be forged?
Posted
by bisu.
Last updated
.
Post not yet marked as solved
1 Replies
583 Views
Currently, 'Get Transaction History', 'Get Transaction Info', 'Get All Subscription Statuses' and 'Notifications V2' are being used in the App store Server API. When I decoded the JWS received in response and checked the root certificate, it was always 'AppleRootCA-G3'. Are there cases where the root certificate is not 'AppleRootCA-G3'?
Posted
by bisu.
Last updated
.
Post not yet marked as solved
0 Replies
393 Views
1.We are making a request to Apple's GetTransactionInfo api: request_uri: GET https://api.storekit.itunes.apple.com/inApps/v1/transactions/570xxxxxx152928 request_response_body` :{"signedTransactionInfo":"eyJh....."} 2.Parse the signedTransactionInfo content returned by the GetTransactionInfo Api JWSTransactionDecodedPayload: { "appAccountToken": "FBACxxxx376", "bundleId": "com.test.xx", "currency": "VND", "environment": "Production", "inAppOwnershipType": "PURCHASED", "originalPurchaseDate": 1700369755000, "originalTransactionId": "57xxxxxx2928", "price": -1795967296, "productId": "com.text.xx9", "purchaseDate": 1700364444000, "quantity": 1, "signedDate": 1700364444000, "storefront": "VNM", "storefrontId": "123456", "transactionId": "57xxxxxx2928", "transactionReason": "PURCHASE", "type": "Consumable" } 3. The Apple Api returned an abnormal price: -1,795,967,296. Personal speculation: The original price of the current order item [com.text.xx9] is 2,499,000 VND, and the Apple Api multiplies the price amount by 1000, resulting in a final amount of 2,499,000,000. However, due to an overflow issue in the length of the price amount, the price in the order details becomes -1,795,967,296, a negative number. Appstore api doc: GetTransactionInfo Api docGet Transaction Info | Apple Developer Documentation JWSTransactionDecodedPayload doc:JWSTransactionDecodedPayload | Apple Developer Documentation
Posted Last updated
.
Post not yet marked as solved
1 Replies
473 Views
Here is a summary of the steps we have taken: Endpoint Configuration: We have set up an HTTPS endpoint on our server hosted with Heroku. Our application is built with Node.js and Express, and it is designed to listen for POST requests for processing Apple's server notifications. App Store Connect Setup: We have entered the correct endpoint URL in App Store Connect for both production and sandbox environments. We have also ensured that we are set up to receive version 2 notifications, as this is the latest format. TLS Support: We have verified that Heroku supports TLS 1.2 by default, and our server is configured to utilize this protocol. Receipt and Shared Secret: We have generated the shared secret from App Store Connect and stored it securely as a config var in Heroku. This shared secret is used to validate receipts with Apple's verifyReceipt endpoint. Testing: We have conducted tests using Apple's sandbox environment by performing transactions to trigger server notifications. Additionally, we have also checked the Heroku logs for any incoming requests and haven't observed any related to the Apple server notifications. Firewall and IP Whitelisting: Our server does not have any IP whitelisting or firewall rules that would block incoming HTTP POST requests from external services. However, despite these measures, we have not been able to receive any server-to-server notifications
Posted Last updated
.
Post not yet marked as solved
0 Replies
364 Views
On my purchase page I use RevenueCat to make the initial purchase and in my SettingsVC I have the in-app purchase API (as required) to later resubscribe: // ... try await AppStore.showManageSubscriptions(in: window as! UIWindowScene) I followed these directions and these directions. Using an iPhone 8 simulator I logged into iCloud as a sandbox tester eg. sandboxtest%test.com, then logged into its Settings, loaded my app, made a purchase, the subscription went through and eventually expired. While in the iPhone 8 I checked my SettingsVC > in-app purchase API and it said Expired Nov 5, 2023 ... Select an option to resubscribe. So it worked. I send sandboxtest%test.com and the pw to App Review and got the below rejection: Guideline 2.1 - Performance - App Completeness We discovered one or more bugs in your app. Specifically, your app displayed an error page when the Mange Subscription tab was tapped. We found that while you have submitted in-app purchase products for your app, the in-app purchase functionality is not present in your binary. If you would like to include in-app purchases in your app, you will need to upload a new binary that incorporates the in-app purchase API to enable users to make a purchase They sent me a screenshot and the in-app purchase API said Cannot Connect - Retry. I later use my actual device and try these 3 ways: 1- While logged in as myself, without using any Sandbox Account, delete the app, run it again, then log into my app with sandboxtest%test.com 2- While logged in as myself, use a different sandbox tester such as whatever%test.com to log into the Sandbox Account, delete the app, run it again, then log into my app with sandboxtest%test.com 3- While logged in as myself, use sandboxtest%test.com for the Sandbox Account, delete the app, run it again, then log into my app with sandboxtest%test.com For all 3 RevenueCat prints the initial subscription and the expiration date, but for some reason when I go to the in-app purchase API, it always returns You do not have any subscriptions. What's strange is when I go back to the iPhone 8 while still logged in as sandboxtest%test.com, the in-app purchase API still shows Expired Nov 5, 2023 ... Select an option to resubscribe. I'm kinda lost here because to use an actual device to login, it sends a SMS, so I don't see how giving the App Reviewer the sandboxtest%test.com/pw info to login into the device and iCloud will help him/her make a purchase because they can't get the SMS. I would assume they would only need sandboxtest%test.com, but that does't work for them. Any advice?
Posted
by lance145.
Last updated
.