### Install App Store Server Library Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/README.md Install the library using npm. This is the first step before using any of its features. ```bash npm install @apple/app-store-server-library ``` -------------------------------- ### Configure AppStoreServerAPIClient with Environment Variables Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/configuration.md Example of creating an AppStoreServerAPIClient instance using configuration values read from environment variables. This setup is suitable for both sandbox and production environments. ```typescript import fs from 'fs' import { AppStoreServerAPIClient, Environment } from '@apple/app-store-server-library' // Read configuration from environment variables const signingKey = fs.readFileSync(process.env.APP_STORE_KEY_PATH, 'utf8') const keyId = process.env.APP_STORE_KEY_ID const issuerId = process.env.APP_STORE_ISSUER_ID const bundleId = process.env.APP_BUNDLE_ID const environment = process.env.NODE_ENV === 'production' ? Environment.PRODUCTION : Environment.SANDBOX // Create client const client = new AppStoreServerAPIClient( signingKey, keyId, issuerId, bundleId, environment ) export default client ``` -------------------------------- ### Install App Store Server Library with NPM or Yarn Source: https://github.com/apple/app-store-server-library-node/blob/main/README.md Use NPM or Yarn to add the library to your project. Ensure you have Node 16+ installed. ```bash # With NPM npm install @apple/app-store-server-library --save # With Yarn yarn add @apple/app-store-server-library ``` -------------------------------- ### Configuration Guide Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/DOCUMENTATION_MANIFEST.txt Instructions for setting up and configuring the App Store Server Library, including constructor parameters, environment configuration, certificate management, and security best practices. Covers webhook configuration, rate limiting, and credential rotation. ```APIDOC ## Configuration Guide ### Description Guide to setting up and configuring the App Store Server Library for Node.js. ### Topics Covered - Constructor parameter documentation - Environment configuration - Certificate management - Required files and credentials - Environment variables patterns - Security best practices - Webhook configuration - Rate limiting strategies - Credential rotation procedures ### Documentation - Full details available in `configuration.md`. ``` -------------------------------- ### Example Configuration with Environment Variables Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/configuration.md Configures the SignedDataVerifier using environment variables for dynamic settings like production/sandbox and app details. This is recommended for production environments. ```typescript import fs from 'fs' import { SignedDataVerifier, Environment } from '@apple/app-store-server-library' const verifier = new SignedDataVerifier( [ fs.readFileSync('AppleRootCA-G3.cer'), fs.readFileSync('AppleRootCA-G4.cer') ], process.env.NODE_ENV === 'production' ? true : false, process.env.NODE_ENV === 'production' ? Environment.PRODUCTION : Environment.SANDBOX, process.env.APP_BUNDLE_ID, process.env.NODE_ENV === 'production' ? parseInt(process.env.APP_APPLE_ID) : undefined ) export default verifier ``` -------------------------------- ### Initiate Performance Test Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/endpoints.md Starts a performance test for the realtime endpoint. This helps in evaluating the performance and latency of message delivery. ```APIDOC ## POST /inApps/v1/messaging/performanceTest ### Description Starts a performance test of realtime endpoint. ### Method POST ### Endpoint /inApps/v1/messaging/performanceTest ### Parameters #### Request Body - **appAppleId** (number) - Required - App Apple ID - **bundleId** (string) - Required - App bundle ID - **transactionId** (string) - Required - Transaction for test ### Response #### Success Response (200) - **testId** (string) - Optional - Test identifier #### Error Response - **4000211**: Invalid request - **4030026**: No passing test (production only) - **4030013**: Existing test in progress ``` -------------------------------- ### initiatePerformanceTest Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/app-store-server-api-client.md Initiates a performance test of your Get Retention Message endpoint. This helps in evaluating the performance and reliability of your notification endpoint. ```APIDOC ## initiatePerformanceTest ### Description Initiates a performance test of your Get Retention Message endpoint. ### Method POST ### Endpoint /v1/performance-tests/start ### Request Body - **performanceTestRequest** (PerformanceTestRequest) - Yes - Request with transaction ID - **appAppleId** (integer) - Required - The Apple ID of your app. - **bundleId** (string) - Required - The bundle ID of your app. - **transactionId** (string) - Required - The transaction ID for the performance test. ### Request Example ```json { "appAppleId": 123456789, "bundleId": "com.example.app", "transactionId": "transaction-id-123" } ``` ### Response #### Success Response (200) - **PerformanceTestResponse** - Response with test ID - **testId** (string) - The identifier for the initiated performance test. ### Throws APIException if the request fails ``` -------------------------------- ### getDefaultMessage Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/app-store-server-api-client.md Gets the default message for a specific product in a specific locale. Retrieves the currently configured default message details. ```APIDOC ## getDefaultMessage ### Description Gets the default message for a specific product in a specific locale. ### Method GET ### Endpoint /v1/default-messages/{productId}/{locale} ### Parameters #### Path Parameters - **productId** (string) - Yes - Product identifier of the message - **locale** (string) - Yes - Locale of the message ### Response #### Success Response (200) - **DefaultConfigurationResponse** - Response with configuration details - **messageId** (string) - The identifier of the default message. ### Throws APIException if the request fails ``` -------------------------------- ### Configure Real-time URL Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/app-store-server-api-client.md Configures the URL for your Get Retention Message endpoint. This is used for real-time notifications. ```typescript await client.configureRealtimeURL({ url: "https://example.com/retention-message" }) ``` -------------------------------- ### Get Image List Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/endpoints.md Retrieves a list of all uploaded images, including their UUID, upload state, and size. ```APIDOC ## GET /inApps/v1/messaging/image/list ### Description Gets list of all uploaded images. ### Method GET ### Endpoint /inApps/v1/messaging/image/list ### Response #### Success Response (200) - **images** (array) - Image metadata #### Response Example ```json { "images": [ { "imageId": "string", "imageState": "string", "imageSize": "string" } ] } ``` #### Status Codes - 200 OK: Image list retrieved ``` -------------------------------- ### Initiate Performance Test Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/endpoints.md Starts a performance test for the realtime endpoint. Provide the app's Apple ID, bundle ID, and a transaction ID to initiate the test. ```typescript { appAppleId: number // App Apple ID bundleId: string // App bundle ID transactionId: string // Transaction for test } ``` -------------------------------- ### Get Default Message Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/app-store-server-api-client.md Retrieves the default message for a specific product and locale. Use this to fetch existing default message configurations. ```typescript const response = await client.getDefaultMessage("com.example.subscription", "en_US") console.log(response.messageId) ``` -------------------------------- ### GET /inApps/v1/messaging/default/{productId}/{locale} Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/endpoints.md Retrieves the current default message configuration for a product in a specific locale. This is useful for displaying the currently set default message. ```APIDOC ## GET /inApps/v1/messaging/default/{productId}/{locale} ### Description Retrieves default message configuration. ### Method GET ### Endpoint /inApps/v1/messaging/default/{productId}/{locale} ### Parameters #### Path Parameters - **productId** (string) - Required - Product identifier - **locale** (string) - Required - Locale ### Response #### Success Response (200) - **messageId** (string) - Optional - Configured message UUID - **localizations** (array) - Optional - Message variants #### Response Example { "messageId": "string", "localizations": [ { "locale": "string", "localizedMessage": "string" } ] } #### Error Responses - **200 OK**: Configuration retrieved - **4000164**: Invalid locale - **4040020**: Configuration not found ``` -------------------------------- ### App Store Server API Client Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/DOCUMENTATION_MANIFEST.txt The AppStoreServerAPIClient class provides methods for interacting with the App Store Server API. It includes over 30 methods for managing subscriptions, querying transactions, processing refunds, and more. Each method is documented with full parameter tables, return types, exceptions, and code examples. ```APIDOC ## AppStoreServerAPIClient ### Description Provides methods for interacting with the App Store Server API, including subscription management, transaction queries, refunds, and more. Detailed documentation for each method is available in `api-reference/app-store-server-api-client.md`. ### Methods - Constructor - 30+ API interaction methods (e.g., getSubscriptionInfo, getTransactionHistory, processRefund) ### Parameters - Constructor parameters for environment, credentials, and configuration. - Method-specific parameters with types, requirements, and descriptions. ### Return Types - Method-specific return types, including success responses and potential exceptions. ### Exceptions - APIException, VerificationException, and other relevant error types. ### Code Examples - Code examples are provided for each method in the detailed documentation. ``` -------------------------------- ### Initiate Performance Test Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/app-store-server-api-client.md Initiates a performance test for your Get Retention Message endpoint. Provide necessary details like app ID and transaction ID. ```typescript const response = await client.initiatePerformanceTest({ appAppleId: 123456789, bundleId: "com.example.app", transactionId: "transaction-id-123" }) console.log("Test ID:", response.testId) ``` -------------------------------- ### Get Default Message Configuration Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/endpoints.md Retrieve the currently configured default message for a product and locale. The response may include the message ID and localizations. ```typescript { messageId?: string // Configured message UUID localizations?: Localization[] // Message variants } ``` -------------------------------- ### Get Realtime URL Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/endpoints.md Retrieves the currently configured realtime URL. This is the URL where the App Store Server API is set to send retention messages. ```APIDOC ## GET /inApps/v1/messaging/realtime/url ### Description Retrieves configured realtime URL. ### Method GET ### Endpoint /inApps/v1/messaging/realtime/url ### Response #### Success Response (200) - **url** (string) - Optional - Configured HTTPS URL #### Error Response - **4040021**: URL not configured ``` -------------------------------- ### Get List of Uploaded Images Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/app-store-server-api-client.md Retrieves the identifier and status for all images uploaded to the App Store. The response contains an array of image objects. ```typescript const response = await client.getImageList() response.images?.forEach(image => { console.log(`${image.imageId}: ${image.imageState}`) }) ``` -------------------------------- ### Configure Realtime URL Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/endpoints.md Sets the URL for the Get Retention Message endpoint. This allows the App Store Server API to send messages to your specified URL. ```APIDOC ## PUT /inApps/v1/messaging/realtime/url ### Description Sets the URL for the Get Retention Message endpoint. ### Method PUT ### Endpoint /inApps/v1/messaging/realtime/url ### Parameters #### Request Body - **url** (string) - Required - HTTPS endpoint URL ### Response #### Success Response (204) URL configured #### Error Response - **4000215**: Invalid URL ``` -------------------------------- ### Get Real-time URL Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/app-store-server-api-client.md Retrieves the configured URL for real-time messages. This endpoint is used for your Get Retention Message functionality. ```typescript const response = await client.getRealtimeURL() console.log(response.url) ``` -------------------------------- ### getRealtimeURL Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/app-store-server-api-client.md Gets the URL for real-time messages that points to your Get Retention Message endpoint. Retrieves the currently configured real-time notification URL. ```APIDOC ## getRealtimeURL ### Description Gets the URL for real-time messages that points to your Get Retention Message endpoint. ### Method GET ### Endpoint /v1/realtime-configurations/url ### Response #### Success Response (200) - **RealtimeUrlResponse** - Response with the configured URL - **url** (string) - The configured URL for real-time messages. ### Throws APIException if the request fails ``` -------------------------------- ### Initialize PromotionalOfferV2SignatureCreator Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/signature-creators.md Instantiate the creator with your App Store Connect private key, key ID, issuer ID, and the app's bundle ID. ```typescript const creator = new PromotionalOfferV2SignatureCreator( encodedKey, "ABCDEFGHIJ", "99b16628-15e4-4668-972b-eeff55eeff55", "com.example.app" ) ``` -------------------------------- ### Get Transaction Info Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/app-store-server-api-client.md Retrieves information about a single transaction using its ID. ```typescript const response = await client.getTransactionInfo("transaction-id-123") console.log(response.signedTransactionInfo) ``` -------------------------------- ### Initialize App Store Server API Client Source: https://github.com/apple/app-store-server-library-node/blob/main/README.md Instantiate the API client with your credentials and environment. Ensure your private key file is accessible and readable. ```typescript 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) } ``` -------------------------------- ### Get Message List Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/endpoints.md Retrieves a list of all uploaded messages, including their UUID and upload state. ```APIDOC ## GET /inApps/v1/messaging/message/list ### Description Gets list of all uploaded messages. ### Method GET ### Endpoint /inApps/v1/messaging/message/list ### Response #### Success Response (200) - **messages** (array) - Message metadata #### Response Example ```json { "messages": [ { "messageId": "string", "messageState": "string" } ] } ``` #### Status Codes - 200 OK: Message list retrieved ``` -------------------------------- ### Instantiate PromotionalOfferSignatureCreator Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/signature-creators.md Create an instance of PromotionalOfferSignatureCreator with your private key, key ID, and bundle ID. Ensure your private key is in PEM format. ```typescript const creator = new PromotionalOfferSignatureCreator( encodedKey, "ABCDEFGHIJ", "com.example.app" ) ``` -------------------------------- ### Get App Transaction Info Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/endpoints.md Retrieves app transaction information for a customer using their transaction ID. ```APIDOC ## GET /inApps/v1/transactions/appTransactions/{anyTransactionId} ### Description Gets app transaction information for a customer. ### Method GET ### Endpoint /inApps/v1/transactions/appTransactions/{anyTransactionId} ### Parameters #### Path Parameters - **anyTransactionId** (string) - Required - Any transaction ID of customer ### Response #### Success Response (200) - **signedAppTransaction** (string) - JWS signed app transaction - **bundleId** (string) - App bundle ID - **environment** (string) - SANDBOX or PRODUCTION - **appAppleId** (number) - App Apple ID #### Response Example ```json { "signedAppTransaction": "string", "bundleId": "string", "environment": "string", "appAppleId": 0 } ``` ``` -------------------------------- ### Initialize IntroductoryOfferEligibilitySignatureCreator Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/signature-creators.md Instantiate the creator with your App Store Connect credentials and app's bundle identifier. Ensure you have your private key, key ID, and issuer ID readily available. ```typescript const creator = new IntroductoryOfferEligibilitySignatureCreator( encodedKey, "ABCDEFGHIJ", "99b16628-15e4-4668-972b-eeff55eeff55", "com.example.app" ) ``` -------------------------------- ### Initialize App Store Server API Client with Environment Variables Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/configuration.md Initializes the AppStoreServerAPIClient by reading configuration from environment variables, including the private key, key ID, issuer ID, bundle ID, and environment. Ensure dotenv is configured to load the correct .env file based on NODE_ENV. ```typescript import dotenv from 'dotenv' import fs from 'fs' import { AppStoreServerAPIClient, Environment } from '@apple/app-store-server-library' dotenv.config({ path: `.env.${process.env.NODE_ENV}` }) const client = new AppStoreServerAPIClient( fs.readFileSync(process.env.APP_STORE_KEY_PATH!, 'utf8'), process.env.APP_STORE_KEY_ID!, process.env.APP_STORE_ISSUER_ID!, process.env.APP_BUNDLE_ID!, process.env.APP_STORE_ENVIRONMENT as Environment ) export default client ``` -------------------------------- ### Initialize AppStoreServerAPIClient Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/README.md Initialize the main API client with your signing key, key ID, issuer ID, bundle ID, and environment. This client is used for all server-to-server operations. ```typescript import { AppStoreServerAPIClient, Environment } from '@apple/app-store-server-library' import fs from 'fs' const signingKey = fs.readFileSync('/path/to/SubscriptionKey_KEYID.p8', 'utf8') const client = new AppStoreServerAPIClient( signingKey, "KEY_ID", "ISSUER_ID", "com.example.app", Environment.SANDBOX ) // Get all subscriptions for a customer const response = await client.getAllSubscriptionStatuses("transaction-id") console.log(response.data) ``` -------------------------------- ### deleteRealtimeURL Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/app-store-server-api-client.md Deletes the URL for your Get Retention Message endpoint. This stops real-time notifications from being sent to the configured URL. ```APIDOC ## deleteRealtimeURL ### Description Deletes the URL for your Get Retention Message endpoint. ### Method DELETE ### Endpoint /v1/realtime-configurations/url ### Response #### Success Response (200) - **void** - Indicates successful deletion. ### Throws APIException if the request fails ``` -------------------------------- ### PromotionalOfferV2SignatureCreator Constructor Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/signature-creators.md Initializes a new instance of the PromotionalOfferV2SignatureCreator class. This constructor requires your private signing key, key ID, issuer ID, and the app's bundle identifier. ```APIDOC ## PromotionalOfferV2SignatureCreator Constructor ### Description Initializes a new instance of the PromotionalOfferV2SignatureCreator class. This constructor requires your private signing key, key ID, issuer ID, and the app's bundle identifier. ### Constructor Signature ```typescript public constructor( signingKey: string, keyId: string, issuerId: string, bundleId: string ) ``` ### Parameters #### Path Parameters * **signingKey** (string) - Required - Private key (PEM format) from App Store Connect * **keyId** (string) - Required - Private key ID from App Store Connect * **issuerId** (string) - Required - Issuer ID from App Store Connect * **bundleId** (string) - Required - App's bundle identifier ### Request Example ```typescript const creator = new PromotionalOfferV2SignatureCreator( encodedKey, "ABCDEFGHIJ", "99b16628-15e4-4668-972b-eeff55eeff55", "com.example.app" ) ``` ``` -------------------------------- ### Get All Subscription Statuses Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/endpoints.md Retrieves the status of all subscriptions for a given customer using any of their transaction IDs. Supports filtering by status. ```APIDOC ## GET /inApps/v1/subscriptions/{anyTransactionId} ### Description Gets status of all subscriptions for a customer. ### Method GET ### Endpoint /inApps/v1/subscriptions/{anyTransactionId} ### Parameters #### Path Parameters - **anyTransactionId** (string) - Required - Any transaction ID of customer #### Query Parameters - **status** (string[]) - Optional - Filter by Status enum values ### Response #### Success Response (200) - **data** (SubscriptionGroupIdentifierItem[]) - Subscription statuses - **environment** (string) - SANDBOX or PRODUCTION - **appAppleId** (number) - App Apple ID - **bundleId** (string) - App bundle ID Each item includes: - **subscriptionGroupIdentifier** (string) - Subscription group ID - **lastTransactions** (LastTransactionsItem[]) - Latest transaction per state #### Response Example { "data": [ { "subscriptionGroupIdentifier": "string", "lastTransactions": [] } ], "environment": "PRODUCTION", "appAppleId": 123456789, "bundleId": "com.example.app" } #### Error Handling - 4000006, 4000026, 4000031: Invalid parameters - 4040005, 4040006: Transaction not found ``` -------------------------------- ### Configure IntroductoryOfferEligibilitySignatureCreator Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/configuration.md Instantiate IntroductoryOfferEligibilitySignatureCreator with your signing key, key ID, issuer ID, and bundle ID. Generate a JWS to check introductory offer eligibility using createSignature. ```typescript import { IntroductoryOfferEligibilitySignatureCreator } from '@apple/app-store-server-library' const creator = new IntroductoryOfferEligibilitySignatureCreator( signingKey, keyId, issuerId, bundleId ) const jws = creator.createSignature( "product-id", true, // Customer eligible for intro offer "customer-transaction-id" ) ``` -------------------------------- ### getPerformanceTestResults Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/app-store-server-api-client.md Gets the results of a performance test for the specified identifier. Use this to retrieve the outcome of a previously initiated performance test. ```APIDOC ## getPerformanceTestResults ### Description Gets the results of a performance test for the specified identifier. ### Method GET ### Endpoint /v1/performance-tests/{requestId} ### Parameters #### Path Parameters - **requestId** (string) - Yes - ID of the performance test ### Response #### Success Response (200) - **PerformanceTestResultResponse** - Response with test results - **testResults** (string) - The results of the performance test. ### Throws APIException if the request fails ``` -------------------------------- ### AppStoreServerAPIClient Constructor Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/app-store-server-api-client.md Initializes an instance of the App Store Server API client. This client is used to make authenticated requests to Apple's servers. It requires your app's signing key, key ID, issuer ID, bundle ID, and the target environment. ```APIDOC ## AppStoreServerAPIClient Constructor ### Description Creates an App Store Server API client instance for making authenticated requests to Apple's servers. ### Parameters #### Path Parameters * **signingKey** (string) - Yes - The private key (PEM format) downloaded from App Store Connect * **keyId** (string) - Yes - Your private key ID from App Store Connect * **issuerId** (string) - Yes - Your issuer ID from the Keys page in App Store Connect * **bundleId** (string) - Yes - Your app's bundle identifier * **environment** (Environment) - Yes - Target environment: PRODUCTION, SANDBOX, LOCAL_TESTING, or XCODE ### Throws Error if environment is XCODE (unsupported for API client) ### Example ```typescript const client = new AppStoreServerAPIClient( encodedKey, // Private key PEM string "ABCDEFGHIJ", // Key ID "99b16628-15e4-4668-972b-eeff55eeff55", // Issuer ID "com.example.app", // Bundle ID Environment.SANDBOX ) ``` ``` -------------------------------- ### Configure PromotionalOfferSignatureCreator Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/configuration.md Instantiate PromotionalOfferSignatureCreator with your signing key, key ID, and bundle ID. Generate a new signature for each offer using the createSignature method. ```typescript import { PromotionalOfferSignatureCreator } from '@apple/app-store-server-library' const creator = new PromotionalOfferSignatureCreator( signingKey, keyId, bundleId ) // Generate new signature for each offer const signature = creator.createSignature( "product-id", "offer-id", "app-account-token", generateUUID(), // NEW UUID for each signature Date.now() // Current timestamp ) ``` -------------------------------- ### Get Current Timestamp in Milliseconds Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/signature-creators.md Obtain the current time in UNIX milliseconds, which is the required format for timestamps in signature creation. ```typescript // Current time const now = Date.now() // Specific date const specificTime = new Date('2024-12-25').getTime() ``` -------------------------------- ### AppStoreServerAPIClient Constructor Parameters Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/configuration.md Defines the parameters required to instantiate the AppStoreServerAPIClient. These include your private signing key, key ID, issuer ID, bundle ID, and the target environment. ```typescript public constructor( signingKey: string, keyId: string, issuerId: string, bundleId: string, environment: Environment ) ``` -------------------------------- ### Create Promotional Offer Signature Source: https://github.com/apple/app-store-server-library-node/blob/main/README.md Use this snippet to create a signature for a promotional offer. Ensure you have the private key, key ID, and bundle ID correctly configured. The `readFile` function needs a specific implementation based on your environment. ```typescript 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 = "" const subscriptionOfferId = "" const appAccountToken = "" const nonce = "" const timestamp = Date.now() const signatureCreator = new PromotionalOfferSignatureCreator(encodedKey, keyId, bundleId) const signature = signatureCreator.createSignature(productId, subscriptionOfferId, appAccountToken, nonce, timestamp) console.log(signature) ``` -------------------------------- ### Delete Real-time URL Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/app-store-server-api-client.md Deletes the configured URL for your Get Retention Message endpoint. Use this if you no longer need real-time notifications. ```typescript await client.deleteRealtimeURL() ``` -------------------------------- ### Instantiate AppStoreServerAPIClient Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/app-store-server-api-client.md Creates an App Store Server API client instance for making authenticated requests to Apple's servers. Ensure you have your private key, key ID, issuer ID, bundle ID, and the target environment. ```typescript const client = new AppStoreServerAPIClient( encodedKey, // Private key PEM string "ABCDEFGHIJ", // Key ID "99b16628-15e4-4668-972b-eeff55eeff55", // Issuer ID "com.example.app", // Bundle ID Environment.SANDBOX ) ``` -------------------------------- ### IntroductoryOfferEligibilitySignatureCreator Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/signature-creators.md Creates JWS tokens for checking introductory offer eligibility. It requires authentication details from App Store Connect to initialize. ```APIDOC ## IntroductoryOfferEligibilitySignatureCreator Creates JWS tokens for checking introductory offer eligibility. ### Constructor ```typescript public constructor( signingKey: string, keyId: string, issuerId: string, bundleId: string ) ``` #### Parameters - **signingKey** (string) - Yes - Private key (PEM format) from App Store Connect - **keyId** (string) - Yes - Private key ID from App Store Connect - **issuerId** (string) - Yes - Issuer ID from App Store Connect - **bundleId** (string) - Yes - App's bundle identifier ### createSignature ```typescript public createSignature( productId: string, allowIntroductoryOffer: boolean, transactionId: string ): string ``` Creates an introductory offer eligibility signature as a JWS token. #### Parameters - **productId** (string) - Yes - Unique product identifier - **allowIntroductoryOffer** (boolean) - Yes - Whether customer is eligible for introductory offer - **transactionId** (string) - Yes - Customer's transaction ID #### Returns Signed JWS string ``` -------------------------------- ### Response Body for Get Message List Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/endpoints.md Represents the structure of the response when retrieving a list of uploaded messages. Includes an array of message metadata. ```typescript { messages?: GetMessageListResponseItem[] // Message metadata } ``` -------------------------------- ### Create Introductory Offer Eligibility Signature Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/signature-creators.md Generate a JWS token to check a customer's eligibility for an introductory offer. Provide the product ID, a boolean indicating eligibility, and the customer's transaction ID. ```typescript const jws = creator.createSignature( "com.example.subscription", true, // Customer is eligible "customer-transaction-id" ) console.log("Eligibility JWS:", jws) ``` -------------------------------- ### Response Body for Get Image List Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/endpoints.md Represents the structure of the response when retrieving a list of uploaded images. Includes an array of image metadata. ```typescript { images?: GetImageListResponseItem[] // Image metadata } ``` -------------------------------- ### Get Performance Test Results Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/app-store-server-api-client.md Retrieves the results of a performance test using its identifier. Use this to check the outcome of a previously initiated test. ```typescript const results = await client.getPerformanceTestResults("test-id-123") console.log(results.testResults) ``` -------------------------------- ### Create Promotional Offer Signature Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/signature-creators.md Generate a promotional offer signature using SHA256. A new nonce must be generated for every signature. This method requires the product identifier, subscription offer ID, app account token, a unique nonce, and a timestamp. ```typescript import { randomUUID } from 'crypto' const signature = creator.createSignature( "com.example.subscription", "discount-offer-id", "user-account-token-123", randomUUID(), Date.now() ) console.log("Signature:", signature) ``` -------------------------------- ### Get List of Uploaded Messages Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/app-store-server-api-client.md Retrieves the identifier and status for all messages uploaded for retention messaging. The response contains an array of message objects. ```typescript const response = await client.getMessageList() response.messages?.forEach(message => { console.log(`${message.messageId}: ${message.messageState}`) }) ``` -------------------------------- ### Create Promotional Offer Signature Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/README.md Creates a signature for a promotional offer, which can then be passed to the client app for a user to initiate a purchase with the offer. Requires signing key, key ID, bundle ID, product ID, offer code, app account token, and a nonce. ```typescript const creator = new PromotionalOfferSignatureCreator(signingKey, keyId, bundleId) const signature = creator.createSignature( "subscription.monthly", "summer-offer-50", appAccountToken, randomUUID(), Date.now() ) // Pass signature to client app for purchase ``` -------------------------------- ### Configure PromotionalOfferV2SignatureCreator Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/configuration.md Instantiate PromotionalOfferV2SignatureCreator with your signing key, key ID, issuer ID, and bundle ID. Use createSignature to generate a JWS for V2 promotional offers. ```typescript import { PromotionalOfferV2SignatureCreator } from '@apple/app-store-server-library' const creator = new PromotionalOfferV2SignatureCreator( signingKey, keyId, issuerId, bundleId ) const jws = creator.createSignature( "product-id", "offer-id", "transaction-id-optional" ) ``` -------------------------------- ### Get Transaction History (Paginated) Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/app-store-server-api-client.md Retrieves a customer's in-app purchase transaction history. Use the revision token to paginate through results. ```typescript const request = { sort: Order.ASCENDING, revoked: false, productTypes: [ProductType.AUTO_RENEWABLE] } let response = await client.getTransactionHistory( "any-tx-id", null, request, GetTransactionHistoryVersion.V2 ) while (response.hasMore) { response = await client.getTransactionHistory( "any-tx-id", response.revision, request, GetTransactionHistoryVersion.V2 ) if (response.signedTransactions) { // Process transactions } } ``` -------------------------------- ### API Client Methods Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/DOCUMENTATION_MANIFEST.txt Details on methods for interacting with the App Store Server API, including creating a client instance, retrieving subscription statuses, transaction history with pagination, extending renewal dates, and sending consumption information. ```APIDOC ## API Client Methods This section details the methods available for interacting with the App Store Server API using the library. ### Creating Client Instance Initializes the App Store Server API client with necessary credentials. ### Getting Subscription Statuses Retrieves the latest status information for a given app. ### Getting Transaction History Fetches a paginated history of transactions for a specific user. ### Extending Renewal Dates Allows for extending the renewal date of an in-app purchase. ### Sending Consumption Information Provides information to the App Store about the consumption of in-app purchases. ``` -------------------------------- ### Get Performance Test Results Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/endpoints.md Retrieves the results of a previously initiated performance test. This includes response times and status codes for the test requests. ```APIDOC ## GET /inApps/v1/messaging/performanceTest/result/{requestId} ### Description Retrieves performance test results. ### Method GET ### Endpoint /inApps/v1/messaging/performanceTest/result/{requestId} ### Parameters #### Path Parameters - **requestId** (string) - Required - Test identifier ### Response #### Success Response (200) - **testResults** (array) - Optional - Response metrics - **appAppleId** (number) - Optional - App Apple ID - **bundleId** (string) - Optional - App bundle ID Each result: - **duration** (number) - Optional - Response time (milliseconds) - **statusCode** (number) - Optional - HTTP response code #### Error Response - **4000212**: Invalid request ID - **4040018**: Test run not found ``` -------------------------------- ### ReceiptUtility Class Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/receipt-utility.md Initializes a new instance of the ReceiptUtility class. No constructor parameters are required. ```APIDOC ## Class: ReceiptUtility No constructor parameters required. ```typescript const receiptUtil = new ReceiptUtility() ``` ``` -------------------------------- ### SignedDataVerifier Constructor Parameters Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/configuration.md Defines the parameters required for initializing the SignedDataVerifier. Ensure all parameters match the environment and app details. ```typescript public constructor( appleRootCertificates: Buffer[], enableOnlineChecks: boolean, environment: Environment, bundleId: string, appAppleId?: number ) ``` -------------------------------- ### Get Refund History Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/endpoints.md Retrieves a paginated list of refunded in-app purchases using a transaction ID. Supports filtering by revision token for pagination. ```APIDOC ## GET /inApps/v2/refund/lookup/{anyTransactionId} ### Description Gets paginated list of refunded in-app purchases. ### Method GET ### Endpoint /inApps/v2/refund/lookup/{anyTransactionId} ### Parameters #### Path Parameters - **anyTransactionId** (string) - Required - Any transaction ID of customer #### Query Parameters - **revision** (string) - Optional - Pagination token ### Response #### Success Response (200) - **signedTransactions** (string[]) - JWS signed transactions - **revision** (string) - Pagination token - **bundleId** (string) - App bundle ID - **environment** (string) - SANDBOX or PRODUCTION - **appAppleId** (number) - App Apple ID #### Response Example ```json { "signedTransactions": [ "string" ], "revision": "string", "bundleId": "string", "environment": "SANDBOX or PRODUCTION", "appAppleId": 0 } ``` ### Error Handling - **4000005**: Invalid revision token - **4040005, 4040006**: Transaction not found ``` -------------------------------- ### configureRealtimeURL Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/app-store-server-api-client.md Configures the URL for your Get Retention Message endpoint. This allows the App Store Server API to send real-time notifications to your specified endpoint. ```APIDOC ## configureRealtimeURL ### Description Configures the URL for your Get Retention Message endpoint. ### Method POST ### Endpoint /v1/realtime-configurations/url ### Request Body - **realtimeUrlRequest** (RealtimeUrlRequest) - Yes - Request with endpoint URL - **url** (string) - Required - The URL for the Get Retention Message endpoint. ### Request Example ```json { "url": "https://example.com/retention-message" } ``` ### Response #### Success Response (200) - **void** - Indicates successful configuration. ### Throws APIException if the request fails ``` -------------------------------- ### Environment Variables for Sandbox and Production Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/configuration.md Defines environment-specific variables for sandbox and production configurations, including API keys, IDs, and bundle identifiers. Ensure these are loaded using a library like dotenv. ```bash # .env.sandbox APP_STORE_ENVIRONMENT=Sandbox APP_STORE_KEY_PATH=/path/to/SubscriptionKey_KEYID.p8 APP_STORE_KEY_ID=ABCDEFGHIJ APP_STORE_ISSUER_ID=99b16628-15e4-4668-972b-eeff55eeff55 APP_BUNDLE_ID=com.example.app.sandbox # .env.production APP_STORE_ENVIRONMENT=Production APP_STORE_KEY_PATH=/path/to/SubscriptionKey_KEYID.p8 APP_STORE_KEY_ID=ABCDEFGHIJ APP_STORE_ISSUER_ID=99b16628-15e4-4668-972b-eeff55eeff55 APP_BUNDLE_ID=com.example.app APP_APPLE_ID=123456789 ``` -------------------------------- ### App Store Server Library Environment Enum Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/configuration.md Enumerates the possible environments for the App Store Server Library. Use SANDBOX for testing, PRODUCTION for live transactions, and XCODE or LOCAL_TESTING for local development where signature verification is skipped. ```typescript enum Environment { SANDBOX = "Sandbox", // Use for testing with sandbox subscriptions PRODUCTION = "Production", // Use for production subscriptions XCODE = "Xcode", // Use in Xcode simulator (no signature verification) LOCAL_TESTING = "LocalTesting" // Use for local testing (no signature verification) } ``` -------------------------------- ### Security Considerations Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/DOCUMENTATION_MANIFEST.txt Information on secure practices for key management, credential rotation, environment variable patterns, and webhook verification. ```APIDOC ## Security Considerations This section outlines essential security practices for using the App Store Server Library. ### Key Management Practices Best practices for securely managing API keys and other sensitive credentials. ### Credential Rotation Recommendations for regularly rotating credentials to minimize security risks. ### Environment Variable Patterns Guidance on using environment variables for secure configuration, including credential storage. ### Webhook Verification Details on verifying the authenticity of incoming webhooks to prevent malicious activity. ``` -------------------------------- ### Get Refund History Response Structure Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/endpoints.md Defines the structure of the response when retrieving a paginated list of refunded in-app purchases. Use this to parse the returned data. ```typescript { signedTransactions?: string[] // JWS signed transactions revision?: string // Pagination token bundleId?: string // App bundle ID environment?: string // SANDBOX or PRODUCTION appAppleId?: number // App Apple ID } ``` -------------------------------- ### Validate Parameters Before Signing Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/signature-creators.md Implement validation checks for product ID, offer ID, nonce format, and timestamp recency before creating a signature to ensure data integrity. ```typescript function createOfferSignature(creator, productId, offerId, nonce, timestamp) { if (!productId || !offerId) { throw new Error('Product ID and offer ID required') } if (!/^[0-9a-f-]{36}$/.test(nonce)) { throw new Error('Invalid nonce format (must be UUID)') } if (timestamp < Date.now() - 86400000) { // older than 24h throw new Error('Timestamp too old') } return creator.createSignature(productId, offerId, '', nonce, timestamp) } ``` -------------------------------- ### Get Transaction History Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/endpoints.md Retrieves a paginated history of transactions for a customer. Supports filtering by various criteria such as date range, product ID, and subscription group. ```APIDOC ## GET /inApps/{version}/history/{anyTransactionId} ### Description Gets paginated transaction history for a customer. ### Method GET ### Endpoint /inApps/{version}/history/{anyTransactionId} ### Parameters #### Path Parameters - **version** (string) - Required - v1 (deprecated) or v2 (recommended) - **anyTransactionId** (string) - Required - Any transaction ID of customer #### Query Parameters - **revision** (string) - Optional - Pagination token - **startDate** (number) - Optional - Start timestamp (milliseconds) - **endDate** (number) - Optional - End timestamp (milliseconds) - **productId** (string[]) - Optional - Filter by product IDs - **productType** (string[]) - Optional - Filter by ProductType - **sort** (string) - Optional - ASCENDING or DESCENDING - **subscriptionGroupIdentifier** (string[]) - Optional - Subscription groups - **inAppOwnershipType** (string) - Optional - PURCHASED or FAMILY_SHARED - **revoked** (boolean) - Optional - Include revoked transactions ### Response #### Success Response (200) - **signedTransactions** (string[]) - Array of JWS transaction strings - **revision** (string) - Pagination token - **hasMore** (boolean) - More transactions available - **bundleId** (string) - App bundle ID - **environment** (string) - SANDBOX or PRODUCTION - **appAppleId** (number) - App Apple ID #### Response Example { "signedTransactions": [ "string" ], "revision": "string", "hasMore": true, "bundleId": "com.example.app", "environment": "PRODUCTION", "appAppleId": 123456789 } #### Error Handling - 4000005-4000031: Parameter validation errors - 4040005, 4040006: Transaction not found ``` -------------------------------- ### Signature Creation Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/DOCUMENTATION_MANIFEST.txt Information on generating signatures for promotional offers, V2 offers with optional parameters, and introductory offer eligibility. ```APIDOC ## Signature Creation This section describes how to create various types of signatures required for App Store offers. ### Creating Promotional Offer Signatures Generates signatures for standard promotional offers. ### Creating V2 Signatures Creates signatures for V2 offers, supporting optional parameters for flexibility. ### Creating Introductory Offer Eligibility Signatures Generates signatures to determine a user's eligibility for introductory offers. ``` -------------------------------- ### Secure Private Key Management in Node.js Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/configuration.md Demonstrates secure methods for accessing private keys in Node.js, emphasizing the use of environment variables or reading from securely stored files. Avoid hardcoding sensitive key material directly in the code. ```typescript // Good: Read from secure environment const key = process.env.APP_STORE_KEY // Bad: Hardcoded in code const key = "-----BEGIN..." // Never do this // Good: Read from file with restricted permissions const key = fs.readFileSync( path.join(__dirname, '../secure/key.p8'), 'utf8' ) ``` -------------------------------- ### Get App Transaction Info Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/app-store-server-api-client.md Retrieves detailed information about a specific app transaction using its ID. Ensure you have a valid transaction ID to use this method. ```typescript const response = await client.getAppTransactionInfo("any-transaction-id") console.log(response.signedAppTransaction) ``` -------------------------------- ### Set up Express Webhook Endpoint Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/configuration.md Configure an Express.js server to listen for App Store Server Notifications. This snippet shows how to verify and decode incoming notifications using the SignedDataVerifier. ```typescript import express from 'express' import { SignedDataVerifier } from '@apple/app-store-server-library' const app = express() const verifier = createVerifier() // See configuration examples above app.post('/webhook/app-store', async (req, res) => { try { // Verify and decode the incoming notification const decodedNotification = await verifier.verifyAndDecodeNotification( req.body.signedPayload ) // Process the notification await processNotification(decodedNotification) // Acknowledge receipt res.status(200).json({ success: true }) } catch (error) { console.error('Webhook error:', error) res.status(400).json({ error: 'Invalid notification' }) } }) app.listen(3000, () => { console.log('Webhook listening on port 3000') }) ``` -------------------------------- ### PromotionalOfferSignatureCreator Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/signature-creators.md Creates signatures for promotional offers using the original signature algorithm (SHA256-based). ```APIDOC ## PromotionalOfferSignatureCreator Constructor ### Description Initializes a new instance of the PromotionalOfferSignatureCreator class. ### Constructor ```typescript public constructor( signingKey: string, keyId: string, bundleId: string ) ``` ### Parameters #### Path Parameters - **signingKey** (string) - Yes - Private key (PEM format) from App Store Connect - **keyId** (string) - Yes - Private key ID from App Store Connect - **bundleId** (string) - Yes - App's bundle identifier ### Request Example ```typescript const creator = new PromotionalOfferSignatureCreator( encodedKey, "ABCDEFGHIJ", "com.example.app" ) ``` ``` ```APIDOC ## createSignature ### Description Creates a promotional offer signature using SHA256. A new nonce must be generated for every signature. ### Method ```typescript public createSignature( productIdentifier: string, subscriptionOfferID: string, appAccountToken: string, nonce: string, timestamp: number ): string ``` ### Parameters #### Path Parameters - **productIdentifier** (string) - Yes - Subscription product identifier - **subscriptionOfferID** (string) - Yes - Subscription discount identifier from App Store Connect - **appAccountToken** (string) - Yes - App account token (may be empty string) - **nonce** (string) - Yes - UUID v4 generated for this signature only - **timestamp** (number) - Yes - UNIX timestamp in milliseconds ### Returns Base64-encoded signature string ### Request Example ```typescript import { randomUUID } from 'crypto' const signature = creator.createSignature( "com.example.subscription", "discount-offer-id", "user-account-token-123", randomUUID(), Date.now() ) console.log("Signature:", signature) ``` ``` -------------------------------- ### Get Test Notification Status Source: https://github.com/apple/app-store-server-library-node/blob/main/_autodocs/api-reference/app-store-server-api-client.md Retrieves the status of a test App Store server notification. Requires the test notification token obtained from a prior request. ```typescript const response = await client.getTestNotificationStatus("test-token-123") console.log(response.notificationPayload) console.log(response.responseResult) ```