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

86 Posts
Sort by:
Post not yet marked as solved
0 Replies
414 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
489 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
376 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
.
Post not yet marked as solved
0 Replies
299 Views
The signed payload I got from the notification V2 doesn't have the bundleId and caused a verified error. I'm using the app-store-server-library-python to verify and decode verification and it raised an exception that bundleId doesn't match, from the stack I found there is no bundleId in it,
Posted
by shellfly.
Last updated
.
Post not yet marked as solved
1 Replies
412 Views
I have some questions about your Commerce refund/chargeback area. I would really appreciate it if you could help clarify these questions. As we are a Saas game backend company helping game studios build their backend, and our system is not directly integrated with your platform transaction system, it is very difficult for us to detect any refund/chargeback and perform revocation of items/VCs accordingly. So, I’m wondering if your platform provides any kind of workaround for us to gather player refund/chargeback events? Any suggestions or guidance will be highly appreciated. Thank you!
Posted
by askAB123.
Last updated
.
Post marked as solved
7 Replies
2.0k Views
We have implemented an auto-renewing subscription as an in-app-purchase for our iOS application. We are consuming the App Store Server Notifications for subscription transactions in order to update the user's account (and thereby maintain their 'Pro' access to our application). Sometimes those notifications never come to our server, and there is no evidence that they were even attempted to be sent to us. We have had some users report to our Customer Support team that they have successfully made a purchase of the subscription, but that they were not granted 'Pro' access. For the large majority of users this is not happening and all is well, but for some users the notifications just never come from the App Store Server API. We keep a record of all notifications that we receive from the App Store, and for these users we never received the "SUBSCRIBED" event. We have checked the Notification History API and there are no reports of any failure to send notifications to our server. We have checked our server logs for any sign of failure to receive incoming web requests, and there is no sign of these missing notifications. We have verified that our server supports ATS. We are keeping the transaction.originalID for all our users who are subscribed to the auto-renewing subscription. We have used this value to do some lookups into the transaction history and subscription status of the users who are being affected. Here is an example of our findings from those lookups: From the transaction history endpoint, we received an error: “Invalid transaction identifier”. From the subscription status endpoint, we received a response with the information for that user's active, valid subscription. We never received any App Store Server Notifications about this user’s subscription, and the transaction history API tells us it is an invalid transaction ID. We believe that the fact that the subscription status API returned the information showing that this user’s subscription is active and valid, and that the notification history API shows no sign of a failure to send us notifications about that subscription, shows that the App Store Server API never attempted to send us any notification for this user’s subscription. The same is true for a significant number of other users of our service. Can anyone help us determine what is going on, and how to best support these customers? It seems as though there was never an attempt to send these notifications to our server, but our users provide proof that they do in fact have an active subscription, for which they have paid (receipt email from Apple with a valid order ID).
Posted Last updated
.
Post not yet marked as solved
2 Replies
560 Views
Hi, This is first time posting in here. Now our app is using In-app purchase and i'm implementing server logics using app-store-server-api. But from yesterday, i'm facing 'http status code 401 Unauthorized error' when calling some apis. I did many trials to fix this error and issue new key for api in app store connect. But I can't resolve this error. Even can't know what is the reason. I attach my real code for calling 'get transaction info' api. Please give some help for me!!!! const jwt = require('jsonwebtoken'); const fs = require('fs'); const axios = require('axios'); getApiJWTToken = () => { // header const keyId = process.env.APP_STORE_KEY_ID; const issuerId = process.env.APP_STORE_ISSUER_ID; const appBundleId = process.env.APP_BUNDLE_ID; const header = { alg: 'ES256', kid: keyId, typ: 'JWT', }; // payload const issuedAt = Number(dayjs().unix()); const payload = { iss: issuerId, iat: issuedAt, aud: 'appstoreconnect-v1', bid: appBundleId, }; // sign const keyString = fs.readFileSync(filePath, 'utf-8'); const token = jwt.sign(payload, keyString, { algorithm: 'ES256', header: header, expiresIn: '30m', }); return btoa(token); }; requestSingleTransactionInfo = async ({ transactionId }) => { try { // jwt token const token = this.getApiJWTToken(); const envType = process.env.APP_STORE_SERVER_API_ENV; const commonUrl = `/inApps/v1/transactions/${transactionId}`; let baseUrl; if (envType === 'Sandbox') { // sandbox baseUrl = 'https://api.storekit-sandbox.itunes.apple.com'; } else if (envType === 'Production') { // production baseUrl = 'https://api.storekit.itunes.apple.com'; } const url = `${baseUrl}${commonUrl}`; const response = await axios.get(url, { headers: { Authorization: `Bearer ${token}`, }, }); const { signedTransactionInfo } = response.data; const transactionInfo = await decodeTransaction(signedTransactionInfo); console.log(transactionInfo); return transactionInfo; } catch (err) { throw err; } };
Posted Last updated
.
Post not yet marked as solved
2 Replies
377 Views
Hi, recently our system received many CONSUMPTION_REQUEST after receive REFUND request for some transaction. EX: we have one transaction wants to refund, and our system receives the first CONSUMPTION_REQUEST at 10th Oct and receives the REFUND request after two days(12th Oct), there is no CONSUMPTION_REQUEST coming between those time, and after that, we recieve many CONSUMPTION_REQUEST between 13th Otc to now. Not sure if it this is what Apple excepted, because we are not found the document related to this. Why we post this question is for our system, what we always faced is there is no CONSUMPTION_REQUEST coming after receive the REFUND request before.
Posted
by fpei.
Last updated
.
Post not yet marked as solved
1 Replies
381 Views
I received the following notifications (in this order) for the subscription: date, type, subtype 2023-10-09 10:49:17,SUBSCRIBED,INITIAL_BUY 2023-10-16 03:46:44,DID_CHANGE_RENEWAL_STATUS,AUTO_RENEW_DISABLED 2023-10-16 10:49:19,DID_FAIL_TO_RENEW,GRACE_PERIOD 2023-10-16 13:14:36,EXPIRED,BILLING_RETRY What do these mean? Why is there a DID_FAIL_TO_RENEW GRACE_PERIOD notification when the user already disabled auto-renew? Why did it expire in 2.5 hours? Why isn't there a GRACE_PERIOD_EXPIRED notification?"
Posted
by cherya.
Last updated
.
Post not yet marked as solved
0 Replies
429 Views
Hi everyone, I'm trying to understand something for analytics purpose. We see a large number of transactions coming in Transaction.update that don't initiate from our app's paywalls. When using AppStore.sync, does this send any restored transactions in Transaction.update? Or does it simply update what currentEntitlements will return. In other words, when I validate a transaction coming from Transaction.update, and the reason is .purchase, is it always a new purchase, or can it be an old purchase which is replayed? If the answer to the above question is yes, how can we distinguish actual purchases from restored transactions when verifying a transaction? Thanks! Bruno
Posted
by bvrlt.
Last updated
.
Post not yet marked as solved
0 Replies
396 Views
There are fake receipts used by hackers, which are the receipts before iOS7.The Receipt can be successfully verified with an incorrect password.Is this a bug?https://developer.apple.com/documentation/appstorereceipts/verifyreceipt --Do I need to completely drop compatibility for this? FB number is https://feedbackassistant.apple.com/feedback/13205370 but the ticket's status is Investigation complete - Unable to diagnose with current information,but No reply message
Posted
by 1x012.
Last updated
.
Post not yet marked as solved
0 Replies
414 Views
I am developing a mobile app that has a paid subscription. I am interested in triggering a push notification when users change their subscription status in the App Store - for example, if they were to turn off auto-renew on their subscription, that would trigger a push notification using APNS to offer a discount. How would I go about sending a notification to a specific user based on the Server Notification payload? It is unclear which, if any, of the response body payload can be used to identify the user. Furthermore, I need a way to associate this identification with a device token so I can send an APNS push notification to the user. I have had the notification toggle available on launch for a while. If I understand correctly, users toggling "Allow/Deny" for registerForRemoteNotifications() notifications only changes their local settings. My first instinct was to start storing user data when they consent or decline notifications on launch - I could store [some kind of user ID, notifications_allowed (bool), and the APNS device token]. That way, when receiving an App Store Server Notification, I can reference this table, then fetch their device token and send a push notification if they have agreed to notifications. However, this seems somewhat fallible because it doesn't track users who change their notification settings in their own setting later. To summarize, my questions are the following: How can I identify a user from an App Store Server Notification payload? How could I store an identifier along with the APNS device token when users consent or decline push notifications that can later be used to associate their device with an App Store Server Notification?
Posted
by wolson123.
Last updated
.
Post not yet marked as solved
0 Replies
455 Views
Dear Apple Developer Forum Community, I hope this message finds you well. We are in the process of planning a migration from the existing "verify receipt" method to the new App Store Server API using the app-store-server library in Node.js. While we are excited about the capabilities and advantages that the app-store-server library offers, we have noted that it is currently in a beta phase. As we strive to ensure a stable and reliable production environment for our application, we would like to inquire about the expected timeline for the app-store-server library to transition from beta to a production-ready release. Our decision to adopt this library is contingent upon its readiness for production use, and we are keen to align our migration plans with its development roadmap. Any insights or updates regarding the library's readiness for production use would be greatly appreciated. Thank you for your time and assistance. We look forward to your response and are eager to continue our journey of providing exceptional experiences to our users through the Apple ecosystem. Sincerely,
Posted
by ParthOpt.
Last updated
.
Post not yet marked as solved
0 Replies
473 Views
As the Title, I had an app which is available only to specific businesses or organizations, how can we get the app version on the App store by the Lookup API for the APP? I used the link for trying: (https://itunes.apple.com/lookup?bundleId=), but I got the below response: { "resultCount":0, "results": [] } Any suggestion?
Posted
by desmon.
Last updated
.
Post marked as solved
1 Replies
1.2k Views
In the old verifyReceipt endpoint doc, there is an important desc As a best practice, always call the production URL https://buy.itunes.apple.com/verifyReceipt first and proceed to verify with the sandbox URL if you receive a 21007 status code. Following this approach ensures that you don’t have to switch between URLs while your app is in testing, in review by App Review, or live in the App Store. So I can know the transactionId is for sandbox if return back 21007. And I am about to access to new App Store Server API, so the same, I wonder how can I recognize the transactionId is from sandbox by status code? The most likely desc is this: If you don’t have environment information, follow these steps: Call the endpoint using the production URL. If the call succeeds, the original transaction identifier belongs to the production environment. If you receive an [errorCode 4040005] with errorMessage as OriginalTransactionIdNotFoundError, (or HTTP response code 404 from the Send Consumption Information endpoint), call the endpoint using the sandbox environment. If the call succeeds, the original transaction identifier belongs to the sandbox environment. If the call fails with the same error code, the original transaction identifier isn’t present in either environment. And I have a try for Get Transaction Info API, but actually get 4040010, Transaction id not found. as return. So I just wanna clear that is there any doc clarify this point that I miss? Looking forward to your response, sincerely!! :)
Posted
by daydaylw3.
Last updated
.
Post not yet marked as solved
1 Replies
477 Views
I have verified that my sandbox endpoint works for App Store Server Notifications (V2), by requesting a Test Notification. When I issue a beginRefundRequest in my app for a Sandbox account, my backend does not receive a request. According to the docs this should work in Sandbox too: https://developer.apple.com/documentation/storekit/transaction/testing_refund_requests What could possible be missing if the TEST notification works, but the REFUND notification doesn't?
Posted
by Erfa.
Last updated
.