App Store Server Notifications

RSS for tag

Monitor subscription events in real time with server notifications from the App Store using App Store Server Notifications.

App Store Server Notifications Documentation

Posts under App Store Server Notifications tag

104 Posts
Sort by:
Post not yet marked as solved
0 Replies
404 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
Post not yet marked as solved
2 Replies
678 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
by
Post not yet marked as solved
0 Replies
384 Views
Hi, Please take a response to me about my Notification Service Entitlement Request. I have requested 5 times but i didn't get any repsonses. The application cannot be released because authorization is not granted. Please check my case and leave a response as soon as. Thanks,
Posted
by
Post not yet marked as solved
1 Replies
561 Views
Hello With V1 notifications, all you had to do was check status 21007 in production to switch to sandbox, but with V2 how do you do that? At best you get a 401 if you query production with a sandbox transactionID. How can I ensure that transaction validation via AppStore Server uses the correct environment during the Apple review? What is the procedure for V2 notifications and Apple review? If my code deployed in production is on the product environment, what happens at review time? I don't think anyone on the web has asked this question... Any help would be appreciated Nicolas
Posted
by
Post not yet marked as solved
1 Replies
436 Views
Hi, I have some questions about App Store Server Notifications that I can't seem to figure out. Specifically, those related to Family Shared purchases, that contain the 'FAMILY_SHARED' inAppOwnershipType. I'll focus on 'OFFER_REDEEMED' notifications, but I have the same questions for regular subscription purchases (with no offers involved): When a user redeems an offer code for a given subscription, do we receive a notifications for each of the family members? In that case, should we receive one with ownership 'PURCHASED', and the rest with the 'FAMILY_SHARED', or could we just receive notifications for 'FAMILY_SHARED' if that's the one who redeemed it? Assuming the redeemed offer was a free trial, whenever that user disables auto renewal, should we again receive one notification for each family member? We are certainly receiving disabled_renewal notifications with ownership type 'FAMILY_SHARED'. Is there any way of linking a given 'FAMILY_SHARED' ownership event/notification to the original or parent 'PURCHASED' notification/purchase? They usually come later in time, with no specific order. If we were to track the proceeds or active subscriptions, should we just ignore any notification with ownership 'FAMILY_SHARED', and focus on 'PURCHASED' ones ? In other words, is it safe to assume that we would always receive a notification of ownership 'PURCHASED', even if the one redeeming the offer code is a family member? (not sure if that is a possible scenario). Thank you.
Posted
by
Post not yet marked as solved
1 Replies
367 Views
Received 'REFUND' notification from server for 'App Store Server Notification V1'. Among the 'responseBodyV1' properties, the 'original_transaction_id' value and Should I find and process transactions that match 'unified_receipt' > 'latest_receipt_info' > 'original_transaction_id'? Sometimes there are no transactions in the history of 'latest_receipt_info' that match 'original_transaction_id'.
Posted
by
Post marked as solved
1 Replies
411 Views
Hello, I have configured V2 server notifications for my applications. I am receiving different types of notifications (https://developer.apple.com/documentation/appstoreservernotifications/notificationtype) in my webhook. Something changed after November 18th. EXPIRED notifications are no longer received. Has something changed in the API? Other notification types still work.
Posted
by
Post not yet marked as solved
1 Replies
558 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
Post not yet marked as solved
0 Replies
328 Views
Our live app uses V1 notifications in both production and sandbox. We deployed a new endpoint, registered it in the App Store, and switched to V2 for Sandbox only. After that, we created a subscription from a debug build with a sandbox account. This resulted in our old endpoint still being hit with V1 notifications. Do you have any idea what are we missing?
Posted
by
Post marked as solved
1 Replies
693 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
by
Post not yet marked as solved
1 Replies
388 Views
Hello, We have a few FAMILY_SHARED subscriptions which received a DID_RENEW notification, with all the cancellation fields completed, the expiration date in the future and no pending_renewal_info array in it. We are not sure why did we get the DID_RENEW notification with the cancelation details, shouldn't we get a REVOKE notification? We found this in the Apple documentation: The pending_renewal_info array is returned only for app receipts that contain auto-renewable subscriptions. If customers voluntarily cancel a subscription renewal while in the grace period, the App Store pauses billing retry, and removes the transaction from pending_renewal_info. The subscription is in the grace period if the key grace_period_expires_date_ms is present and the expiration date hasn't passed. We do not handle any cancelation related logic for the DID_RENEW notification. Should we adjust the logic for this scenario or there should be a different notification type sent out. This is how the latest element looks like from the lattest_recipt_info: "auto_renew_status": "true", "unified_receipt": { "status": 0, "environment": "Production", "latest_receipt_info": [{ "quantity": "1", "product_id": "product_id", "transaction_id": "transaction_id", "purchase_date": "2023-11-07 23:01:41 Etc/GMT", "purchase_date_ms": "1699398101000", "purchase_date_pst": "2023-11-07 15:01:41 America/Los_Angeles", "original_purchase_date": "2021-10-07 22:01:42 Etc/GMT", "original_purchase_date_ms": "1633644102000", "original_purchase_date_pst": "2021-10-07 15:01:42 America/Los_Angeles", "expires_date": "2024-11-07 23:01:41 Etc/GMT", "expires_date_ms": "1731020501000", "expires_date_pst": "2024-11-07 15:01:41 America/Los_Angeles", "web_order_line_item_id": "web_order_line_item_id", "is_trial_period": "false", "is_in_intro_offer_period": "false", "original_transaction_id": "original_transaction_id", "cancellation_date": "2023-11-07 15:37:03 Etc/GMT", "cancellation_date_ms": "1699371423020", "cancellation_date_pst": "2023-11-07 07:37:03 America/Los_Angeles", "cancellation_reason": "0", "in_app_ownership_type": "FAMILY_SHARED", "subscription_group_identifier": "subscription_group_identifier" }
Posted
by
Post not yet marked as solved
1 Replies
764 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
Post not yet marked as solved
1 Replies
610 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
Post not yet marked as solved
1 Replies
316 Views
We are currently implementing a feature that will allow us to extend the subscription period for users who have suffered losses due to our negligence. Regarding the problem that is occurring in the sandbox environment during the testing stage, please check whether it is due to the sandbox specifications. ■Reproduction steps Sandbox account A starts charging in the sandbox environment (sandbox account A is in the state of automatic contract renewal) Execute extension process for a specific period for sandbox account A. Confirm that the period of sandbox account A has been extended. Confirm that sandbox account A has reached the expiration date after the extension and that the next contract renewal will be performed automatically. Delete the purchase history of sandbox account A by following the steps below.AppStoreConnect->Users and Access->Sandbox->Test Account->Edit "Clear Purchase History". Proceed with steps 1 to 3 again for sandbox account A. Due to the expiration of the period in step 4, the automatic contract renewal for sandbox account A was canceled and subsequent contract renewals were no longer performed. (This is the problem) I've run similar tests with other accounts, and in every test the problem doesn't occur until I clear my purchase history, but the problem occurs after I clear my purchase history. When I checked the log information, the following notification was received at the timing of step 7, and it seems that the user took the initiative to cancel the automatic update. 「"notificationType": "EXPIRED", "subtype": "VOLUNTARY"」 Please let me know if the behavior is as specified.
Posted
by
Post not yet marked as solved
1 Replies
399 Views
What is the best way to trigger App Store Server Notifications to test your endpoint? There is a document on Request Test Notification but this only has information on the URL without any info on the expected request parameters, etc. The ideal experience would be that StoreKit2 debugging inside XCode fires server notifications to a specified URL, but it doesn't seem to be supported.
Posted
by
Post not yet marked as solved
2 Replies
434 Views
We have a server to server setup for subscription management for the Apple subscriptions. Lately we observed that we are getting a lot of DID_RENEW notification, after decoded with the /verifyReceipt endpoints, these notifications have no purchase in them. We are in the Production environment. The original_purchase_date is set to "1970-01-20 11:45:27 Etc/GMT" and we can se also the preorder_date field set to the date when we receive the notification. All our products are approved and released at the moment(nothing to be released). There are no other "usable" details for us in the decoded notification(data to identify user). Can somebody please help explaining this scenario? Why are we receiving these notifications? Thanks, David.
Posted
by
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
Post not yet marked as solved
0 Replies
329 Views
I'm using the flutter_local_notificationspackage to display notifications in and outside the app (background mode). Everything is working as expected on Android (debug + release) and iOS debug mode but, strangely, local notifications are not displayed in background mode for iOS release. I don't know why the iOS release mode behaves differently, any thoughts? Thanks. What I already checked: use of the latest version of the flutter_local_notifications package (v16.1.0) checking "Signing & Capabilities" for both debug and release mode (Background modes : fetch, remote notifications)
Posted
by
Post not yet marked as solved
3 Replies
711 Views
I am facing this issue. I create curl command with jwt token like this import jwt from "jsonwebtoken" import { readFileSync } from "fs" import {bid, iss, kid, p8FilePath} from "./values.js" const currentDate = Math.floor(new Date().getTime() / 1000); const expiryDate = currentDate + (10 * 60); const header = { typ: "JWT", alg: "ES256", kid: kid, }; const payload = { iss: iss, aud: "appstoreconnect-v1", iat: currentDate, exp: expiryDate, bid: bid, }; const privateKey = readFileSync(p8FilePath); const token = jwt.sign(payload, privateKey, { algorithm: "ES256", header, }); // curl command console.log(`curl -v -H 'Authorization: Bearer ${token}' -X POST "https://api.storekit-sandbox.itunes.apple.com/inApps/v1/notifications/test"`) and curl responds always * Trying 17.36.202.8:443... * Connected to api.storekit-sandbox.itunes.apple.com (17.36.202.8) port 443 (#0) * ALPN: offers h2,http/1.1 * (304) (OUT), TLS handshake, Client hello (1): * CAfile: /etc/ssl/cert.pem * CApath: none * (304) (IN), TLS handshake, Server hello (2): * (304) (IN), TLS handshake, Unknown (8): * (304) (IN), TLS handshake, Certificate (11): * (304) (IN), TLS handshake, CERT verify (15): * (304) (IN), TLS handshake, Finished (20): * (304) (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / AEAD-AES256-GCM-SHA384 * ALPN: server accepted h2 * Server certificate: * subject: businessCategory=Private Organization; jurisdictionCountryName=US; jurisdictionStateOrProvinceName=California; serialNumber=C0806592; C=US; ST=California; L=Cupertino; O=Apple Inc.; CN=api.storekit-sandbox.itunes.apple.com * start date: Oct 17 19:50:08 2023 GMT * expire date: Oct 16 20:00:08 2024 GMT * subjectAltName: host "api.storekit-sandbox.itunes.apple.com" matched cert's "api.storekit-sandbox.itunes.apple.com" * issuer: C=US; O=Apple Inc.; CN=Apple Public EV Server ECC CA 1 - G1 * SSL certificate verify ok. * using HTTP/2 * h2 [:method: POST] * h2 [:scheme: https] * h2 [:authority: api.storekit-sandbox.itunes.apple.com] * h2 [:path: /inApps/v1/notifications/test] * h2 [user-agent: curl/8.1.2] * h2 [accept: */*] * h2 [authorization: Bearer eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ilc1QjVRNzJONUwifQ.eyJpc3MiOiI2OWE2ZGU3Yy0yMmFlLTQ3ZTMtZTA1My01YjhjN2MxMWE0ZDEiLCJhdWQiOiJhcHBzdG9yZWNvbm5lY3QtdjEiLCJpYXQiOjE2OTkyMjE2MTIsImV4cCI6MTY5OTIyMjIxMiwiYmlkIjoiY29tLm1pcmFpamEudGVzdCJ9.xLDfV6oDmx0RM6soUix7XMM-ilzV3YtSjrbGXe3ZzAj8jbEpGoFLafhPtRYEnEoSYWAY6GZmFPSzxQxO2i60MA] * Using Stream ID: 1 (easy handle 0x7ff1d000b800) > POST /inApps/v1/notifications/test HTTP/2 > Host: api.storekit-sandbox.itunes.apple.com > User-Agent: curl/8.1.2 > Accept: */* > Authorization: Bearer eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Ilc1QjVRNzJONUwifQ.eyJpc3MiOiI2OWE2ZGU3Yy0yMmFlLTQ3ZTMtZTA1My01YjhjN2MxMWE0ZDEiLCJhdWQiOiJhcHBzdG9yZWNvbm5lY3QtdjEiLCJpYXQiOjE2OTkyMjE2MTIsImV4cCI6MTY5OTIyMjIxMiwiYmlkIjoiY29tLm1pcmFpamEudGVzdCJ9.xLDfV6oDmx0RM6soUix7XMM-ilzV3YtSjrbGXe3ZzAj8jbEpGoFLafhPtRYEnEoSYWAY6GZmFPSzxQxO2i60MA > < HTTP/2 401 < server: daiquiri/3.0.0 < date: Sun, 05 Nov 2023 22:07:20 GMT < content-type: text/plain < strict-transport-security: max-age=31536000; includeSubDomains < x-apple-jingle-correlation-key: MDKTT2CACBWVV4F4V37D6QV6KI < x-daiquiri-instance: daiquiri:45824002:st44p00it-hyhk15104701:7987:23RELEASE169:daiquiri-amp-commerce-clients-ext-001-st < Unauthenticated Request ID: MDKTT2CACBWVV4F4V37D6QV6KI.0.0 * Connection #0 to host api.storekit-sandbox.itunes.apple.com left intact how can I fix this????
Posted
by