***

title: Apple Pay
subtitle: Accept Apple Pay for fast, secure checkout on Safari and iOS devices.
---------------------

For clean Markdown of any page, append .md to the page URL. For a complete documentation index, see https://docs.paymentkit.com/guides/integration/sdk-reference/payment-kit-js/llms.txt. For full documentation content, see https://docs.paymentkit.com/guides/integration/sdk-reference/payment-kit-js/llms-full.txt.

Apple Pay lets customers pay using cards saved to their Apple Wallet with a single tap or glance.

# Prerequisites

Apple Pay requires a two-step prepare/submit flow. Before the customer clicks the Apple Pay button, you must call `prepareApplePay` to initialize the payment session. This is required because Apple Pay sessions must be created in response to a user gesture (browser security requirement).

<Tabs>
  <Tab title="Stripe processor">
    Add Stripe.js to your page:

    ```html
    <script src="https://js.stripe.com/v3/"></script>
    ```
  </Tab>

  <Tab title="Airwallex processor">
    No additional scripts required. PaymentKit uses the native `ApplePaySession` API directly for Airwallex.
  </Tab>
</Tabs>

# Setup

<Tabs>
  <Tab title="CDN">
    ```html
    <script src="https://unpkg.com/@payment-kit-js/vanilla/dist/cdn/paymentkit.min.js"></script>
    <script>
      const paymentKit = PaymentKit.default({
        environment: 'production',
        secureToken: 'your_secure_token',
        paymentMethods: [PaymentKit.PaymentMethods.applePay]
      });
    </script>
    ```
  </Tab>

  <Tab title="NPM/ES Modules">
    ```typescript
    import PaymentKit from '@payment-kit-js/vanilla';
    import ApplePayPaymentMethod from '@payment-kit-js/vanilla/payment-methods/apple-pay';

    const paymentKit = PaymentKit({
      environment: 'production',
      secureToken: 'your_secure_token',
      paymentMethods: [ApplePayPaymentMethod]
    });
    ```
  </Tab>
</Tabs>

# Prepare Apple Pay

Before showing the Apple Pay button, call `prepareApplePay` to check availability and pre-initialize the session. This must happen before the user clicks the button.

```typescript
import { prepareApplePay, isApplePayPrepared, clearPreparedApplePay } from '@payment-kit-js/vanilla/payment-methods/apple-pay';

const result = await prepareApplePay(
  'https://app.paymentkit.com',  // API base URL
  'your_secure_token',
  {
    processorId: 'proc_abc123',
    processorType: 'airwallex',  // Required for Airwallex processors
    customerInfo: {
      first_name: 'Jane',
      last_name: 'Smith'
    },
    country: 'US'
  },
  'production'  // environment
);

if (result.success) {
  // Show Apple Pay button
}
```

<Callout intent="warning">
  **Airwallex processors**: You must pass `processorType: 'airwallex'` in both `prepareApplePay` and `submit` options. Without this, the SDK will route the payment through the Stripe flow instead of Airwallex, causing a backend error. Stripe processors work without `processorType`.
</Callout>

# Submit payment

```typescript
document.getElementById('apple-pay-button').addEventListener('click', () => {
  paymentKit.submit({
    fields: {
      customer_name: 'Jane Smith',
      customer_email: 'jane@example.com',
      customer_country: 'US',
      customer_zip_code: '94102'
    },
    paymentMethod: 'apple_pay',
    options: {
      processorId: 'proc_abc123',
      processorType: 'airwallex',  // Required for Airwallex processors
      customerInfo: {
        first_name: 'Jane',
        last_name: 'Smith'
      },
      country: 'US'
    },
    onSuccess: (result) => {
      console.log('Transaction ID:', result.transaction_id);
      console.log('Checkout Session:', result.checkout_session_id);
      window.location.href = '/success';
    },
    onError: (errors) => {
      if (errors.apple_pay === 'Apple Pay not available') {
        // Hide button, show card form instead
      }
    }
  });
});
```

# Cleanup

When unmounting your checkout component or navigating away, clear the prepared state:

```typescript
clearPreparedApplePay();
```

# Options

## `prepareApplePay` options

| Option                    | Type                      | Description                                                                                      |
| ------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------ |
| `processorId`             | `string`                  | **Required.** Your processor ID with Apple Pay enabled                                           |
| `processorType`           | `"stripe" \| "airwallex"` | **Required for Airwallex.** Set to `"airwallex"` when using an Airwallex processor               |
| `customerInfo.first_name` | `string`                  | **Required.** Customer's first name                                                              |
| `customerInfo.last_name`  | `string`                  | **Required.** Customer's last name                                                               |
| `country`                 | `string`                  | **Required.** Two-letter country code (e.g., `"US"`)                                             |
| `amount`                  | `number`                  | Amount in atomic units (cents) for the Apple Pay sheet display                                   |
| `currency`                | `string`                  | Currency code (e.g., `"usd"`)                                                                    |
| `merchantName`            | `string`                  | Merchant display name shown on the Apple Pay sheet                                               |
| `mockScenario`            | `ApplePayMockScenario`    | Testing only. Use `"success"` or `"cancelled"` to simulate Apple Pay flows without a real device |

## Submit options

| Option                    | Type                      | Description                                                                  |
| ------------------------- | ------------------------- | ---------------------------------------------------------------------------- |
| `processorId`             | `string`                  | **Required.** Your processor ID with Apple Pay enabled                       |
| `processorType`           | `"stripe" \| "airwallex"` | **Required for Airwallex.** Must match the value passed to `prepareApplePay` |
| `customerInfo.first_name` | `string`                  | **Required.** Customer's first name                                          |
| `customerInfo.last_name`  | `string`                  | **Required.** Customer's last name                                           |
| `country`                 | `string`                  | **Required.** Two-letter country code (e.g., `"US"`)                         |
| `amount`                  | `number`                  | Amount in atomic units (cents) for the Apple Pay sheet display               |
| `currency`                | `string`                  | Currency code (e.g., `"usd"`)                                                |
| `merchantName`            | `string`                  | Merchant display name shown on the Apple Pay sheet                           |
| `mockScenario`            | `ApplePayMockScenario`    | Testing only. Use `"success"` or `"cancelled"`                               |

# Browser support

Apple Pay works on:

* Safari on macOS (with Touch ID or a paired iPhone/Apple Watch)
* Safari on iOS and iPadOS (with Face ID, Touch ID, or passcode)

<Callout intent="info">
  Apple Pay requires Safari. For Stripe processors, PaymentKit.js uses Stripe's Payment Request API, which also only surfaces Apple Pay in Safari. For Airwallex processors, the native `ApplePaySession` API is used directly, which is Safari-only. Always provide card payments as a fallback.
</Callout>

# Error handling

| Error                                                                                       | Cause                                                                                      |
| ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `Processor ID is required`                                                                  | Missing `processorId` in options                                                           |
| `Apple Pay not available on this device (requires Safari)`                                  | Airwallex: device or browser does not support Apple Pay (non-Safari)                       |
| `Apple Pay not available on this device`                                                    | Airwallex: `canMakePayment()` returned false — no cards in wallet or hardware restriction  |
| `Apple Pay is not available on this device or Stripe account`                               | Stripe: `prepareApplePay` could not confirm Apple Pay availability via Payment Request API |
| `Stripe.js not loaded. Add <script src="https://js.stripe.com/v3/"></script> to your page.` | Stripe.js script not present when initializing the Stripe adapter                          |
| `Apple Pay cancelled by user`                                                               | Customer dismissed the Apple Pay sheet                                                     |
| `Failed to start Apple Pay`                                                                 | API call to the `/apple-pay/start` endpoint failed                                         |
| `Apple Pay failed`                                                                          | Airwallex payment sheet returned a non-cancelled failure                                   |
| `3DS authentication failed`                                                                 | Airwallex 3DS challenge completed without success                                          |
| `Too many authentication attempts. Please try again.`                                       | Airwallex 3DS loop exceeded the maximum retry limit                                        |
| `Payment failed`                                                                            | Confirm or verify endpoint returned a non-success charge status                            |
| `Apple Pay error: {message}`                                                                | Unexpected exception during the payment flow                                               |