App Store Server Library

RSS for tag

App Store Server Library is the library for the App Store Server API and App Store Server Notifications. It provides an API client, a JWS signed data verifier, a utility to extract a transaction id from a receipt, and a promotional offer signature.

Posts under App Store Server Library tag

38 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

Reporting your App Store Server Library issue
If you are experiencing an unexpected or inconsistent behavior when using the App Store Server Library, review the following resources to ensure that your implementation workflow didn’t cause the issue: Simplifying your implementation by using the App Store Server Library Explore App Store server APIs for In-App Purchase Meet the App Store Server Library If you are unable to resolve your issue using the above resources, file a GitHub issue. Alternatively, if you wish to provide specific requests, transactions, or other private information for review, submit a Feedback Assistant report with the following information: The bundleId or appAppleId of your app The date and time your issue occurred The library language(s) The version of the library The environment (i.e., Production, Sandbox, or Xcode) The GitHub issue for this report if available The endpoint(s) reproducing your issue The HTTP body and headers of the endpoint raw request The HTTP body and headers of the endpoint response To submit the report, perform these steps: Log into Feedback Assistant. Click on the Compose icon to create a new report. Select the Developer Tools & Resources topic. In the sheet that appears: Enter a title for your report. Select “App Store Server Library” from the “Which area are you seeing an issue with?” pop-up menu. Select “Incorrect/Unexpected Behavior” from the “What type of feedback are you reporting?” pop-up menu. Enter a description of your issue and how to reproduce it. Add the information gathered above to the sheet. Submit your report. After filing your report, please respond in your existing Developer Forums post with the Feedback Assistant ID. Use your Feedback Assistant ID to check for updates or resolutions. For more information, see Understanding feedback status.
0
0
125
2w
Reporting your App Store Server Notifications issue
To receive server notifications from the App Store, follow the instructions in Enabling App Store Server Notifications. If your server doesn’t receive any notifications, check your server logs for any incoming web request issues, and confirm that your server supports the Transport Layer Security (TLS) 1.2 protocol or later. If you implement version 2 of App Store Server Notifications, call the Get Notification History endpoint. If there is an issue sending a notification, the endpoint returns the error the App Store received from your server. If your issue persists, submit a Feedback Assistant report with the following information: The bundleId or appAppleId of your app The date and time your issue occurred The raw HTTP body of your notification The affected transactionId(s) if applicable The version of App Store Server Notifications (i.e., Version 1 or Version 2) The environment (i.e., Production or Sandbox) To submit the report, perform these steps: Log into Feedback Assistant. Click on the Compose icon to create a new report. Select the Developer Tools & Resources topic. In the sheet that appears: Enter a title for your report. Select “App Store Server Notifications” from the “Which area are you seeing an issue with?” pop-up menu. Select “Incorrect/Unexpected Behavior” from the “What type of feedback are you reporting?” pop-up menu. Enter a description of your issue. Add the information gathered above to the sheet. Submit your report. After filing your report, please respond in your existing Developer Forums post with the Feedback Assistant ID. Use your Feedback Assistant ID to check for updates or resolutions. For more information, see Understanding feedback status.
0
0
129
2w
ONE_TIME_CHARGE notification type in Production
Hello, We've integrated App Store Server Notifications V2 in our system. We are heavily relying on the ONE_TIME_CHARGE notification type to handle Consumable purchases, but this notification type is available only for Sandbox. And this is for a while now - starting with June 10th 2024 ( https://developer.apple.com/documentation/appstoreservernotifications/app-store-server-notifications-changelog#June-10-2024 ). Can you please provide a timeline for when the ONE_TIME_CHARGE notification type will be available in Production ? Thank you!
0
0
68
1d
Reasons why network errors occur frequently
When using the AppStoreServerAPI to retrieve user purchase information or decode a Payload, The following responses occur multiple times throughout the day. If there is no error, the process is completed successfully. HTTP response code: 502 for URL What is the cause of this error occurring repeatedly? Is there still a problem with Apple's server status? The following APIs are used to acquire and decode user purchase information.  AppStoreServerAPIClient.getAllSubscriptionStatuses  SignedDataVerifier.verifyAndDecodeTransaction  SignedDataVerifier.verifyAndDecodeRenewalInfo
0
0
114
1w
Reasons why purchase date = expiration date What are the possible cases?
When the user's purchase information was retrieved from Japan using the AppStoreServerAPI, I was able to obtain it with the status ‘1: The auto-renewable subscription is active.’, However, the expiry date in the Payload was the previous day. How can this be the case? Example: when the purchase information was retrieved on 10/02/2025 at 21:00:00, the expiry date for status ‘1’ was ‘2025/02/09’.
0
0
107
1w
About the payment status of App store Server API
Please let me ask you about the following status code obtained from the AppStoreServerAPI. 3: The auto-renewable subscription is in a Billing retry period. 4: The auto-renewable subscription is in a Billing Grace Period. 5: The auto-renewable subscription is revoked. the App Store refunded the transaction or revoked it from Family Sharing. For these status codes 3 to 5, would this mean that the service has not been purchased? And will they change to a status of ‘2: The auto-renewable subscription is expired’ after a certain period of time without the payment issue being resolved?
0
0
97
1w
Best practices: ensuring server-side that the AppReceipt sent up by a client belongs to the client
Hi, all! I have an AppStore Server-side question. User sends up an AppReceipt that I am validating. What's the best way to tell the receipt belongs to said user? I want to make sure that the source of the AppReceipt was actually the original purchaser of the item. Is fetching Transaction + AppAccountToken the only way? AppAccountToken can only be utilized if the original purchase used it, and it is associated with the user's data. Is there another way?
0
0
143
2w
Apple Computer, Inc Root certificate expiring on Monday, 10 February 2025
Hi apple team, I'm using Apple Root Certificates from https://www.apple.com/certificateauthority/ for communicating with App Store Server Library for receipt validation API. Apple Computer, Inc Root certificate from the website is Not Valid After: Monday, 10 February 2025 at 01:18:14 Central European Standard Time. When we can expect update of this certificate. Thank you
0
1
204
2w
Keys are missing in App Store Server API
For the subscription API, we’re using the Get All Subscription Statuses API to replace the deprecated verifyReceipt method. To determine if a user has canceled their subscription, we’re using the expirationIntent key from JWSRenewalInfo data. However, we’ve noticed that we sometimes receive this key and other times not. We’re also facing an issue with the offertype key. We use this key to determine if a user is currently in the introductory offer, the promotion offer, or neither. To obtain this key, we’re using JWSTransaction, but we occasionally receive it and other times not. Note: These issues are being tested in the sandbox environment. Thank you.
1
0
153
3w
Inquiries about API SERVER Notification
Inquire the types of notifications that can occur in a SANDBOX environment Hello, WWDC 2024 is trying to conduct a test to receive notifications related to ONE_TIME_CHARGE, CONNSUMPTION_REQUEST, CONMSUMPTION_INFO, REFUND, and REFUND_DECLINED as described in the example of purchasing consumables, but as a result of the continuous search, I found that it is difficult to occur except for ONE_TIME_CHARGE. So, in order to verify only the business logic as shown below, we are testing only the business logic without actually calling the API after purchasing the test and saving the signaled Payload that we received in response to ONE_TIME_CHARGE. Can we actually request a refund for the test purchase and receive the corresponding notification and actually send the response? public void handleSignedNotification(String signedNotification) throws Exception { ResponseBodyV2DecodedPayload payload = signedDataVerifier.verifyAndDecodeNotification(signedNotification); NotificationTypeV2 type = payload.getNotificationType(); //For Apple Server Notification, only ONE_TIME_CHARGE notifications are enabled in the test environment, so for testing, change them as below to test whether they are running business logic type = NotificationTypeV2.REFUND; log.info("Apple NotificationType : {}", type); switch (type) { case CONSUMPTION_REQUEST: handleConsumptionRequest(payload); break; case REFUND: handleRefund(payload); break; case REFUND_DECLINED: handleRefundDeclined(payload); break; // For other necessary notifications, just take a log default: log.info("Unhandled notification: {}", type); } } Regarding the call of 'CONSUMPTION_INFO', which is the response of 'CONSUMPTION_REQUEST' Is there a value that WWDC 2024 must include when sending CONMSUMPTION_INFO, which is the response to CONNSUMPTION_REQUEST described in the refund example? I'm going to call the API with only sample provision and consumption like the sample code you introduced in the video. I was told to submit my refund preference within 12 hours, but can I submit it as UNDECLARED at first and use the method to express my intention? When I receive the notification, I will save it in the DB and save it in the administrator page of the service so that the administrator can choose. 2-1. Some of the materials I looked for are told that Apple can proceed with the refund even 12 hours ago, and to express your opinion as soon as I receive the notification, but I wonder if this is correct. If you get a notification as below, you should write whether you used it or not by referring to the consumption information. I think the customer said to check whether the data was provided when applying for a refund. Should I take it out of decodedTransaction, check the value, and just call it NO_PREFERENCE? I'd appreciate it if you could give me some advice. Below is a part of the code I implemented. private void handleConsumptionRequest(ResponseBodyV2DecodedPayload notification) throws Exception { // 1. transaction ID get String signedTransactionInfo = notification.getData().getSignedTransactionInfo(); JWSTransactionDecodedPayload decodedTransaction = signedDataVerifier.verifyAndDecodeTransaction(signedTransactionInfo); String transactionId = decodedTransaction.getTransactionId(); // 2. Extract the relevant transaction (The following example is an in-app payment and will be accumulated in two types of DBs, stored in one of the two) Sample sample = sampleService.findByAppleTransactionId(transactionId); Example example = exampleService.findByAppleTransactionId(transactionId); Boolean canRefund = false; // 3. Check consumption information if (sample != null) { canRefund = checkSampleStatusForApplePurchaseRefund(sample); } else if (example != null) { canRefund = checkExampleStatusForApplePurchaseRefund(example); } // 4. Create Refund Preferences RefundPreference refundPreference = determineRefundPreference(canRefund); // 5. Creating a ConsumptionRequest Object ConsumptionRequest request = new ConsumptionRequest() .refundPreference(refundPreference) .sampleContentProvided(true); log.info("forTest~ canRefund: {}", canRefund); log.info("forTest~ sample: {}", sample.toString()); log.info("forTest~ example: {}", example.toString()); log.info("forTest~ refundPreference: {}", refundPreference); log.info("forTest~ request: {}", request); // 6. Transfer to App Store (annotated with dummy requests that only confirm current business requests are going right) // appStoreServerAPIClient.sendConsumptionData(transactionId, request); }
0
0
155
3w
App Store Server Notifications v1 deprecation timelime
Greetings! I was reviewing the documentation for the Apple Store Server Notification v1 APIs and saw the deprecation notice. We are currently unable to migrate to v2 in the near future. With that in mind, I want to know if there were any plans to shut off v1, and if so, was there any timeline we could expect? Thank you in advance. Reference: https://developer.apple.com/documentation/appstoreservernotifications/app-store-server-notifications-version-1
0
0
167
3w
Verification failed with status INVALID_APP_IDENTIFIER using Sandbox
I get this error: Verification failed with status INVALID_APP_IDENTIFIER we use this method: payload = signed_data_verifier.verify_and_decode_notification(notification_data) I use Production environment (this is automatically set in our server) and use my device (connected to Mac) to test the purchase. When trying to purchase I get the Sandbox environment in the Widget. This works when manually setting the environment to Sandbox before calling the function. The time it works because it does not check the apple app id (because of the environment). Now my question is: Which is the apple app id? Is it the App Id "Apple-ID" in the app store connect? Or is it the TeamId+BundleId? Could it be that my function doesnt work because the Payment was done in Sandbox and the environment is Production?
0
0
179
3w
Official document for CONSUMPTION_REQUEST - What kind of data we are receiving?
This documentation describes what kind of data we should be sending to Apple server, once we are receiving CONSUMPTION_REQUEST https://developer.apple.com/documentation/appstoreserverapi/consumptionrequest But, it doesn't describe what kind of data we are receiving, when we are receiving CONSUMPTION_REQUEST? May I know, is such a document available? Thank you.
0
0
339
Dec ’24
App Rejectied due to ATT Prompt
Hello. I am trying to give an update to my app but it again and again gets rejected due to the ATT Prompt. Before this late week I gave the update and it got live without any issue. Now I done some minor changes in the App. Apple Response. The app uses the AppTrackingTransparency framework, but we are unable to locate the App Tracking Transparency permission request when reviewed on iPadOS 18.2. Next Steps Explain where we can find the App Tracking Transparency permission request in the app. The request should appear before any data is collected that could be used to track the user. If App Tracking Transparency is implemented but the permission request is not appearing on devices running the latest operating system, review the available documentation and confirm App Tracking Transparency has been correctly implemented. If your app does not track users, update your app privacy information in App Store Connect to not declare tracking. You must have the Account Holder or Admin role to update app privacy information. My Response: Hello Apple Team Thank you for your feedback. We have tested the app on iPadOS 18.2, also on iPhone 18.1 and the App Tracking Transparency dialogue is appearing as expected on the main home screen when the user enters the app. To help demonstrate this, we’ve attached a video showing the ATT prompt in action. If there is still an issue with the dialogue or if it needs to be placed in a different position, we kindly request your guidance on what needs to be adjusted. Please let us know the details so we can address it promptly. Thank you for your support "I uploaded a video with images showcasing the ATT prompt but now again they rejected the update with the exact same reply. Which I am thinking it may be a bot reply. Now what to do how to solve it?
2
2
739
Dec ’24
App Store Server Notifications and API Client - Toggling Sandbox vs Production Environment
The documentation mentions the following: Verify your receipt first with the production URL; then verify with the sandbox URL if you receive a 21007 status code. This approach ensures 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. This way, you can use one server environment to handle both Sandbox and Production environments. It is necessary to pass App Review. However, I'm not manually hitting these URLs - I'm using Apple's libraries. Specifically, the environment is used in SignedDataVerifier and AppStoreServerAPIClient. (I can't link to these because, for some reason, the domain apple.github.io is not allowed. The documentation for these is only found there. You can find it quickly by searching these terms and the domain.) Here is how SignedDataVerifier is being used: const verifier = new SignedDataVerifier( appleRootCertificates, APPLE_ENABLE_ONLINE_CHECKS, APPLE_ENVIRONMENT, APPLE_BUNDLE_ID, APPLE_APP_ID ) const verifiedNotification: ResponseBodyV2DecodedPayload = await verifier.verifyAndDecodeNotification(signedPayload) if (!verifiedNotification) { // Failure return } Here is how AppStoreServerAPIClient is being used: const appStoreServerAPIClient = new AppStoreServerAPIClient( SIGNING_KEY, APPLE_IAP_KEY_ID, APPLE_IAP_ISSUER_ID, APPLE_BUNDLE_ID, APPLE_ENVIRONMENT ) const statusResponse: StatusResponse = await appStoreServerAPIClient.getAllSubscriptionStatuses(originalTransactionId, [Status.ACTIVE]) In the source code for SignedDataVerifier.verifyAndDecodeNotification, I can see that it throws a VerificationException(VerificationStatus.INVALID_ENVIRONMENT) error . So for SignedDataVerifier is it as simple as wrapping my code in a try/catch and checking that the error's status code is 21007? I'm unsure about this because if you scroll to the bottom of the linked source code file, you can see the enumeration VerificationStatus, but it's unclear if this member has a value of 21007. The source code for AppStoreServerAPIClient only says that it throws an APIException if a response could not be processed, so I'm not too sure about how to handle this one.
1
1
435
Dec ’24
In-App Purchase Transaction Handling and Refund Implications in App Store API
Hello, I am currently encountering an issue while using the server-side API for in-app purchase integration. Suppose a user has already purchased a product, and the App Store returns a transactionId of 1. After some time, the user repeats the purchase for some reason, and the App Store returns a transactionId of 2. However, when I use the Get Transaction History interface to query the transaction information for transactionId 2, I see that the data returned by the App Store does not include the transaction data for transactionId 2; it only contains the transaction data for transactionId 1. In this situation, my guess is that when the user makes a repeat purchase, the App Store recognizes that the user has already purchased the item and has not executed a refund. Therefore, the App Store generates a new transactionId for this request (the user's purchase) and associates it with the previous purchase's transaction data. This is my inference. If this user has made 5 repeat purchases, when the user successfully requests a refund, if I query the transaction information through the Get Transaction History interface, will the revocationDate for all 5 transactions in the App Store's official database be modified to the same date? Additionally, after the user successfully refunds and makes another purchase, will the new transactionId still be associated with the previous transaction data?
0
0
362
Nov ’24
Delayed App Store Server Notification(V2) for Subscription Purchase
We experienced an issue with delayed App Store Server notifications for an Auto-Renewable Subscription purchase in our app. On September 27, 2024, at 22:28:28 GMT+0900, a user successfully purchased a Premium membership subscription (transaction ID: 190002223966278, webOrderLineItemId: 190001007274949). However, our server did not receive the corresponding App Store notification for this transaction after purchase. The App Store Server Notification was only received 66 minutes later, at 23:35:16 (transaction ID: 190002224000004, webOrderLineItemId: 190001007274949). The delayed notification contained a different transaction ID than the initial purchase. We would like to inquire about the cause of this delay and request assistance in understanding why the notification took 66 minutes to be delivered to our server, instead of arriving immediately after the transaction was completed. Additionally, we would appreciate your guidance on how to prevent or mitigate such delays in the future, ensuring a seamless experience for our users. Are there any best practices or recommended approaches we should implement to handle potential notification delays more effectively? We have provided detailed information about the received notification and the related transactions in the Feedback Assistant (FB15330451). Thank you for your assistance in resolving this matter. Key Details Purchase time: 2024-09-27T22:28:28 GMT+0900 (1727443708000) Notification received: 2024-09-27T23:35:16 GMT+0900 (1727447716463) Delay: 66 minutes and 48 seconds Initial Purchase Transaction ID: 190002223966278 Initial Purchase Web Order Line Item ID: 190001007274949 Transaction ID in Delayed Notification: 190002224000004 Web Order Line Item ID in Delayed Notification: 190001007274949 Additional info Bundle ID: com.reppley.ReppleyApp SKU: com.reppley.ReppleyApp Feedback Assistant Number: FB15330451
1
0
540
Oct ’24