The Node.js server library for the App Store Server API and App Store Server Notifications. Also available in Swift, Python, and Java.
Installation
Documentation
Usage
Support
Node 16+
# With NPMnpm install @apple/app-store-server-library --save# With Yarnyarn add @apple/app-store-server-library
Documentation
WWDC Video
To use the App Store Server API or create promotional offer signatures, a signing key downloaded from App Store Connect is required. To obtain this key, you must have the Admin role. Go to Users and Access > Integrations > In-App Purchase. Here you can create and manage keys, as well as find your issuer ID. When using a key, you'll need the key ID and issuer ID as well.
Download and store the root certificates found in the Apple Root Certificates section of the Apple PKI site. Provide these certificates as an array to a SignedDataVerifier to allow verifying the signed data comes from Apple.
import { AppStoreServerAPIClient, Environment, SendTestNotificationResponse } from "@apple/app-store-server-library"const issuerId = "99b16628-15e4-4668-972b-eeff55eeff55"const keyId = "ABCDEFGHIJ"const bundleId = "com.example"const filePath = "/path/to/key/SubscriptionKey_ABCDEFGHIJ.p8"const encodedKey = readFile(filePath) // Specific implementation may varyconst environment = Environment.SANDBOXconst client = new AppStoreServerAPIClient(encodedKey, keyId, issuerId, bundleId, environment)try {const response: SendTestNotificationResponse = await client.requestTestNotification()console.log(response)} catch (e) {console.error(e)}import { SignedDataVerifier } from "@apple/app-store-server-library"const bundleId = "com.example"const appleRootCAs: Buffer[] = loadRootCAs() // Specific implementation may varyconst enableOnlineChecks = trueconst environment = Environment.SANDBOXconst appAppleId = undefined // appAppleId is required when the environment is Productionconst verifier = new SignedDataVerifier(appleRootCAs, enableOnlineChecks, environment, bundleId, appAppleId)const notificationPayload = "ey..."const verifiedNotification = await verifier.verifyAndDecodeNotification(notificationPayload)console.log(verifiedNotification)import { AppStoreServerAPIClient, Environment, GetTransactionHistoryVersion, ReceiptUtility, Order, ProductType, HistoryResponse, TransactionHistoryRequest } from "@apple/app-store-server-library"const issuerId = "99b16628-15e4-4668-972b-eeff55eeff55"const keyId = "ABCDEFGHIJ"const bundleId = "com.example"const filePath = "/path/to/key/SubscriptionKey_ABCDEFGHIJ.p8"const encodedKey = readFile(filePath) // Specific implementation may varyconst environment = Environment.SANDBOXconst client =new AppStoreServerAPIClient(encodedKey, keyId, issuerId, bundleId, environment)const appReceipt = "MI..."const receiptUtil = new ReceiptUtility()const transactionId = receiptUtil.extractTransactionIdFromAppReceipt(appReceipt)if (transactionId != null) {const transactionHistoryRequest: TransactionHistoryRequest = {sort: Order.ASCENDING,revoked: false,productTypes: [ProductType.AUTO_RENEWABLE]}let response: HistoryResponse | null = nulllet transactions: string[] = []do {const revisionToken = response !== null && response.revision !== null ? response.revision : nullresponse = await client.getTransactionHistory(transactionId, revisionToken, transactionHistoryRequest, GetTransactionHistoryVersion.V2)if (response.signedTransactions) {transactions = transactions.concat(response.signedTransactions)}} while (response.hasMore)console.log(transactions)}import { PromotionalOfferSignatureCreator } from "@apple/app-store-server-library"const keyId = "ABCDEFGHIJ"const bundleId = "com.example"const filePath = "/path/to/key/SubscriptionKey_ABCDEFGHIJ.p8"const encodedKey = readFile(filePath) // Specific implementation may varyconst productId = "<product_id>"const subscriptionOfferId = "<subscription_offer_id>"const applicationUsername = "<application_username>"const nonce = "<nonce>"const timestamp = Date.now()const signatureCreator = new PromotionalOfferSignatureCreator(encodedKey, keyId, bundleId)const signature = signatureCreator.createSignature(productId, subscriptionOfferId, applicationUsername, nonce, timestamp)console.log(signature)Only the latest major version of the library will receive updates, including security updates. Therefore, it is recommended to update to new major versions.