Apple App Store Server Node.js Library

repository·main·Indexed 18 days ago

https://github.com/apple/app-store-server-library-node

A programmatic interface for interacting with Apple's App Store Server APIs. This library enables developers to handle notifications, manage retention messaging, process advanced commerce data, and verify signed data using SignedDataVerifier. Key features include retrieving transaction history via AppStoreServerAPIClient, creating promotional offer signatures with PromotionalOfferSignatureCreator, and managing subscription statuses and renewal dates. Requires Node.js 16 or higher.

Tokens
4.6K
Snippets
18
Records
25
Agent score
13%

What's inside @apple/app-store-server-library

  1. Obtain Apple Root Certificates for verification

    main

    To verify that signed data (like notifications) comes from Apple, you must provide Apple's root certificates to the SignedDataVerifier.

    1. Visit the Apple PKI site.
    2. Download the root certificates from the Apple Root Certificates section.
    3. Provide these certificates as an array of Buffer objects when initializing a SignedDataVerifier.
  2. Obtain In-App Purchase keys and credentials

    main

    To use the App Store Server API or create promotional offer signatures, you need a signing key from App Store Connect.

    1. Ensure you have the Admin role in App Store Connect.
    2. Navigate to Users and Access > Integrations > In-App Purchase.
    3. Create or manage keys to obtain your:
      • Key ID
      • Issuer ID
      • Private Key (.p8 file)
  3. Retrieve transaction history using ReceiptUtility and AppStoreServerAPIClient

    main

    To get a user's transaction history, first extract the transactionId from an app receipt using ReceiptUtility, then use AppStoreServerAPIClient.getTransactionHistory in a loop to iterate through all pages of history using the revision token.

    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 vary
    const environment = Environment.SANDBOX
    
    const 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 = null
        let transactions: string[] = []
        do {
            const revisionToken = response !== null && response.revision !== null ? response.revision : null
            response = await client.getTransactionHistory(transactionId, revisionToken, transactionHistoryRequest, GetTransactionHistoryVersion.V2)
            if (response.signedTransactions) {
                transactions = transactions.concat(response.signedTransactions)
            }
        } while (response.hasMore)
        console.log(transactions)
    }
  4. Verify signed data with SignedDataVerifier

    main

    Use SignedDataVerifier to decode and verify the authenticity of App Store notifications or other signed payloads.

    Parameters:

    • appleRootCAs: An array of Buffer objects containing Apple's root certificates.
    • enableOnlineChecks: Boolean to enable/disable online checks.
    • environment: The Environment (e.g., Environment.SANDBOX).
    • bundleId: Your app's bundle ID.
    • appAppleId: (Optional) Required when the environment is Production.
    import { SignedDataVerifier } from "@apple/app-store-server-library"
    
    const bundleId = "com.example"
    const appleRootCAs: Buffer[] = loadRootCAs() // Specific implementation may vary
    const enableOnlineChecks = true
    const environment = Environment.SANDBOX
    const appAppleId = undefined // appAppleId is required when the environment is Production
    const verifier = new SignedDataVerifier(appleRootCAs, enableOnlineChecks, environment, bundleId, appAppleId)
    
    const notificationPayload = "ey..."
    const verifiedNotification = await verifier.verifyAndDecodeNotification(notificationPayload)
    console.log(verifiedNotification)
  5. Use AppStoreServerAPIClient to call App Store APIs

    main

    The AppStoreServerAPIClient is the primary class for interacting with the App Store Server API. It requires your encoded private key, key ID, issuer ID, bundle ID, and the target environment.

    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 vary
    const environment = Environment.SANDBOX
    
    const client = new AppStoreServerAPIClient(encodedKey, keyId, issuerId, bundleId, environment)
    
    try {
        const response: SendTestNotificationResponse = await client.requestTestNotification()
        console.log(response)
    } catch (e) {
        console.error(e)
    }
  6. Create promotional offer signatures with PromotionalOfferSignatureCreator

    main

    Use PromotionalOfferSignatureCreator to generate signatures required for promotional offers. It requires your encoded private key, key ID, and bundle ID.

    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 vary
    
    const productId = "<product_id>"
    const subscriptionOfferId = "<subscription_offer_id>"
    const appAccountToken = "<app_account_token>"
    const nonce = "<nonce>"
    const timestamp = Date.now()
    const signatureCreator = new PromotionalOfferSignatureCreator(encodedKey, keyId, bundleId)
    
    const signature = signatureCreator.createSignature(productId, subscriptionOfferId, appAccountToken, nonce, timestamp)
    console.log(signature)
  7. Perform retention messaging endpoint tests

    main

    Test your Get Retention Message endpoint's performance in the sandbox environment:

    • initiatePerformanceTest(performanceTestRequest): Starts a performance test. Returns a PerformanceTestResponse containing a requestId.
    • getPerformanceTestResults(requestId): Retrieves the results of a specific performance test using the requestId obtained from the initiation step.
  8. Manage retention messaging images

    main

    Use the following methods to manage images used for retention messaging:

    • uploadImage(imageIdentifier, image, imageSize?): Uploads a PNG image. imageIdentifier must be a lowercase UUID. image is a Buffer. imageSize is an optional string.
    • deleteImage(imageIdentifier): Deletes a previously uploaded image using its identifier.
    • getImageList(): Retrieves a list of all uploaded images and their current states.