> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stigg.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Apple App Store

## Overview

The Apple App Store is the primary distribution channel for iOS, iPadOS, macOS, tvOS, and visionOS applications. When customers purchase subscriptions via in-app purchases (IAP), Apple handles billing, payments, and tax, acting as the Merchant of Record.

Stigg's native integration with the Apple App Store allows you to manage entitlements and the subscription lifecycle for iOS subscribers using the same infrastructure you use for all other billing channels. This means your access-control logic, feature gating, and usage reporting work consistently regardless of whether a customer subscribed through your website or through the App Store.

The integration is built on Apple's **App Store Server Notifications V2** framework.

Key capabilities:

1. Automatic ingestion of App Store Server Notifications V2 to keep subscription state in sync.
2. Customer identification via `appAccountToken` (mapping App Store transactions to Stigg customers).
3. Full subscription lifecycle management - provisioning, renewals, upgrades, downgrades, cancellations, and billing retries.
4. Informational invoicing - Stigg generates read-only invoice records for visibility, while Apple remains the Merchant of Record.
5. Migration API for onboarding existing iOS subscribers into Stigg.

## How it works

The integration follows a server-to-server architecture where Stigg acts as the **System of Record for entitlements**, while Apple remains the System of Record for billing.

```mermaid theme={null}
flowchart LR
  A["iOS App (StoreKit 2)"]
  B["Apple App Store Server"]
  C["Stigg Platform"]
  D["Your Backend"]

  A -- "Purchase" --> B
  B -- "V2 Notifications" --> C
  C --> D
```

1. A customer initiates a purchase in your iOS app using StoreKit 2.
2. Apple processes the transaction and sends an **App Store Server Notification V2** to Stigg's endpoint.
3. Stigg verifies the JWS-signed notification, maps the transaction to a Stigg customer (via `appAccountToken`), and updates the subscription state.
4. Your backend queries Stigg for the customer's entitlements to enforce access.

## Prerequisites

Before configuring the App Store integration, ensure you have:

* Access to [App Store Connect](https://appstoreconnect.apple.com/) with an **Admin** role.
* Plans created in Stigg with [custom pricing](/documentation/modeling-your-pricing-in-stigg/plans/custom-plans), with separate plans for monthly and annual App Store subscriptions.

## Setting up the integration

### Step 1: Create an API Key in App Store Connect

1. Log in to [App Store Connect](https://appstoreconnect.apple.com/).
2. Navigate to **Users and Access**.
3. Select the **Integrations** tab.
4. Under **Keys**, choose **App Store Connect API**.
5. Click **Generate API Key** and assign the **App Manager** role.
6. Download and store the private key in a secure location.

<Warning>
  The private key can only be downloaded once. Store it securely as you'll need it for the integration setup.
</Warning>

### Step 2: Configure the integration in Stigg

1. Open the [Stigg app](https://app.stigg.io), navigate to the **Integrations** section and add **Apple App Store**.
2. Enter the following credentials from App Store Connect:
   * **Key ID**
   * **Issuer ID**
   * **Private Key**
3. Toggle the **Sandbox Environment** if you are testing with Apple's sandbox environment.
4. Copy the **Notification URL** provided by Stigg and configure webhook notifications in App Store Connect:
   1. Go to [App Store Connect](https://appstoreconnect.apple.com/).
   2. Navigate to **Apps** → select your target app.
   3. Go to **General Information** → **App Store Server Notifications**.
   4. Paste the Notification URL into:
      * **Production Server URL**: for production notifications
      * **Sandbox Server URL**: for sandbox/testing notifications
5. **Connect your application**: after entering the credentials, Stigg will fetch available applications from the App Store Connect API. Select the application you want to connect to Stigg.
6. **Map App Store subscription products to Stigg plans**: available subscription products will be fetched automatically. Map each App Store subscription product to a previously created Stigg plan.

<Note>
  An App Store subscription product maps to a Stigg **plan**, not a Stigg subscription. When configuring the integration, you are mapping App Store subscription products to Stigg plans.
</Note>

### Step 3: Configure Customer Billing ID

Customers must be created or updated in Stigg with a `billingId` that matches the `appAccountToken` UUID used in Apple App Store purchases.

<Warning>
  The customer's `billingId` in Stigg must exactly match the `appAccountToken` passed during App Store purchase transactions. This linkage is required to correctly associate App Store purchases with Stigg customers and to properly manage subscriptions using App Store Server notifications.
</Warning>

## Importing customers and subscriptions

You can import existing App Store customers and subscriptions into Stigg using the bulk import API.

### Prerequisites

* `@stigg/node-server-sdk` version **4.13.0** or higher.
* API Key from the [Stigg app](https://app.stigg.io).
* Configured App Store integration in Stigg (copy the integration ID from the integration settings).

### Customer and subscription linkage

To properly link Stigg customers to App Store users, use the `appAccountToken` from the app as the `billingId` when importing customers into Stigg. For subscriptions, use the `originalTransactionId` from the in-app purchase as the `billingId` when importing subscriptions into Stigg.

* [`More details about appAccountToken`](https://developer.apple.com/documentation/appstoreserverapi/appaccounttoken)
* [`More details about originalTransactionId`](https://developer.apple.com/documentation/appstoreserverapi/originaltransactionid)

### Code example

<CodeGroup>
  ```typescript Node.js theme={null}
  import Stigg from '@stigg/node-server-sdk';

  const API_KEY = '<API Key from Stigg web>';
  const APP_STORE_INTEGRATION_ID = '<Id from configured integration>';

  const stiggClient = Stigg.initialize({ apiKey: API_KEY });

  await stiggClient.waitForInitialization();

  // Import customers — use appAccountToken as billingId
  await stiggClient.importCustomerBulk({
    integrationId: APP_STORE_INTEGRATION_ID,
    customers: [
      {
        customerId: 'customer-import-demo-1001',
        billingId: 'uuidv4-used-in-app', // set appAccountToken as billingId here
        name: 'Demo1001 withBillingId',
      },
      {
        customerId: 'customer-import-demo-1002',
        name: 'Demo1002 withoutBillingId',
      },
    ],
  });

  // Import subscriptions — use originalTransactionId as billingId
  await stiggClient.importSubscriptionsBulk({
    integrationId: APP_STORE_INTEGRATION_ID,
    subscriptions: [
      {
        customerId: 'customer-import-demo-1001',
        planId: 'plan-revvenu-essentials-app-store',
        billingId: '20000011-1001', // set originalTransactionId as billingId here
      },
      {
        customerId: 'customer-import-demo-1002',
        planId: 'plan-revvenu-essentials-app-store',
        billingId: '20000011-1002', // set originalTransactionId as billingId here
      },
    ],
  });
  ```
</CodeGroup>
