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

# Apple Pay Integration

<div className="Goal">
  ## Goal

  Enable a user to pay with Apple Pay by initializing the Push Apple Pay launcher, displaying the payment sheet, and authorizing the payment.
</div>

<Warning>
  Apple Pay on the web requires your site to be served over HTTPS on a domain that Apple has verified. As a result, this integration cannot be tested on `localhost`. See [Setting up your server](https://developer.apple.com/documentation/applepayontheweb/setting-up-your-server) for details.
</Warning>

## Sequence Diagram

```mermaid theme={null}
sequenceDiagram
    participant User
    participant Operator
    participant SDK as Push SDK
    participant Apple as Apple Pay
    participant API as Push API

    Note over User,API: Step 1: Initialize

    User->>Operator: Load payment page
    Operator->>API: POST /user/{id}/url {type: "apple_pay"}
    API-->>Operator: {url}
    Operator->>SDK: new PushCash.ApplePay({url})
    Operator->>Operator: Check ApplePaySession.canMakePayments()
    Operator->>Operator: Render Apple Pay button

    Note over User,API: Step 2: Display Payment Sheet

    User->>Operator: Click Apple Pay button
    Operator->>SDK: launcher.display({amount, currency, direction, onAuthorize})
    SDK->>Apple: Create ApplePaySession & begin()
    Note over SDK,Apple: Push validates merchant via mTLS
    SDK->>Apple: completeMerchantValidation(session)
    Apple->>User: Display payment sheet

    Note over User,API: Step 3: Authorize Payment

    User->>Apple: Authorize (Face ID / Touch ID)
    Apple->>SDK: Receive token
    SDK->>Operator: onAuthorize(token)
    Operator->>API: POST /authorize {token, amount, currency, direction}
    API-->>Operator: {status: "approved" | "declined"}
    Operator-->>SDK: Return "approved" | "declined"
    SDK->>Apple: completePayment(status)
```

## Steps

***

## Step 1: Initialize the Apple Pay launcher

<div className="What">
  <p className="bold-header">What you need to do</p>

  Generate an Apple Pay URL, initialize the Push SDK launcher, and render the Apple Pay button if supported.<br /><br />

  If a user has not previously used Push, you must first register them following the [create-user](apireference/user/create-user) guide.
</div>

#### How to do it

1. Call [create-user-url](./apireference/user/create-user-url) with `type: "apple_pay"` when the user loads the payment page.

2. Initialize the launcher with the returned URL.

3. Check `ApplePaySession.canMakePayments()` and render the Apple Pay button.

<Accordion title="Initialization Example">
  Example code to generate a URL, initialize the Apple Pay launcher, and conditionally render the button.

  ```js theme={null}
  // the url returned from create-user-url endpoint
  const launcher = new window.PushCash.ApplePay({
    url: '<your-url>'
  });

  if (window.ApplePaySession) {
      const canMakePayments = ApplePaySession.canMakePayments();

      if (canMakePayments) {
          // render Apple Pay option to DOM
      }
  }
  ```
</Accordion>

For more information on how to style and display the button, please review Apple's [design guidelines](https://developer.apple.com/design/human-interface-guidelines/apple-pay#Using-Apple-Pay-buttons) and [official javascript guide](https://developer.apple.com/documentation/applepayontheweb/displaying-apple-pay-buttons-using-javascript).

<Note>If you want to support Apple Pay on non-Apple devices (or if you are not using Safari), install the [Apple Pay JS SDK](https://developer.apple.com/documentation/applepayontheweb/loading-the-latest-version-of-apple-pay-js) on your cashier. Initiating the payment will display a QR code which you will scan with an Apple device to authorize the payment.</Note>

## Step 2: Display the payment sheet

<div className="What">
  <p className="bold-header">What you need to do</p>

  When the user clicks the Apple Pay button, launch the payment sheet using the SDK.
</div>

#### How to do it

1. Call `launcher.display()` with the payment `amount`, `currency`, `direction`, and an `onAuthorize` callback.

2. The SDK handles merchant validation and presents the Apple Pay payment sheet to the user.

3. You may optionally provide an `onComplete` callback that runs when the Apple Pay payment sheet is dismissed.

<Accordion title="Display Example">
  Example code to launch the Apple Pay payment sheet.

  ```js theme={null}
  launcher.display({
    amount: 1000,  // amount of payment in cents
    direction: 'cash_in',
    currency: 'USD',
    onAuthorize: async (token) => {
      // see Step 3
    },
    onComplete: () => {
      // handle session completion
    }
  });
  ```
</Accordion>

To launch Apple Pay on your site, you must verify ownership of your domain. Please contact Push at [hello@pushcash.com](mailto:hello@pushcash.com) to request your Apple Pay merchant domain association file. You must place the file at `https://your-domain.com/.well-known/apple-developer-merchantid-domain-association.txt` to complete domain verification.

## Step 3: Authorize the payment

<div className="What">
  <p className="bold-header">What you need to do</p>

  Handle the `onAuthorize` callback to receive the token and call the Push API to authorize the payment.
</div>

#### How to do it

1. The `onAuthorize` callback receives a `token` after the user authorizes via Face ID / Touch ID.

2. Pass the `token`, along with `amount`, `currency`, and `direction` to [authorize-payment](/apireference/authorization/authorize-payment).

3. Return the intent status (i.e. `approved` or `declined`) from the callback to complete the Apple Pay session.

<Accordion title="Authorization Example">
  Example code to handle the `onAuthorize` callback and authorize the payment.

  ```js theme={null}
  launcher.display({
    amount: 1000,
    direction: 'cash_in',
    currency: 'USD',
    onAuthorize: async (token) => {
      // call backend to authorize payment via Push API
      // pass token to POST /authorize
      const result = await yourBackend.authorize(token);
      return result.status; // 'approved' or 'declined'
    }
  });
  ```
</Accordion>

<Note>
  The amount and currency passed to `POST /authorize` must match the values provided to `display()`. The return value of `onAuthorize` is used to complete the Apple Pay session — return `'approved'` for a successful payment or `'declined'` otherwise.
</Note>

<Info>Simulate an Apple Pay decline in sandbox by submitting an authorization for `2200` cents (\$22.00). Any other amount will be approved.</Info>

<RequestExample>
  ```bash Create User URL theme={null}
  curl --request POST \
    --url https://sandbox.pushcash.com/user/{id}/url \
    --header 'Authorization: Bearer <token>' \
    --header 'Content-Type: application/json' \
    --data '
  {
    "type": "apple_pay"
  }
  '
  ```

  ```bash Authorize Payment theme={null}
  curl --request POST \
    --url https://sandbox.pushcash.com/authorize \
    --header 'Authorization: Bearer <token>' \
    --header 'Content-Type: application/json' \
    --data '
  {
    "amount": 1000,
    "currency": "USD",
    "direction": "cash_in",
    "token": "token_mbDRHFi3dxIZEtykHsgUGC"
  }
  '
  ```
</RequestExample>

<ResponseExample>
  ```json Create User URL - 200 OK theme={null}
  {
    "url": "https://cdn.pushcash.com/applepay/?param=1&param=2&param=3"
  }
  ```

  ```json Authorize Payment - 200 OK theme={null}
  {
    "id": "intent_sandbox_mbDRHFi3dxIZEtykHsgUGC",
    "status": "approved"
  }
  ```

  ```json Authorize Payment - Declined theme={null}
  {
    "id": "intent_sandbox_mbDRHFi3dxIZEtykHsgUGC",
    "status": "declined"
  }
  ```
</ResponseExample>

## Integration checklist

* Simulate an approved transaction by submitting a payment
* Simulate a declined transaction by submitting a payment for `2200` cents (\$22.00)
* Verify domain association file is in place at `https://your-domain.com/.well-known/apple-developer-merchantid-domain-association.txt`

## Next steps

Set up webhooks to receive asynchronous updates about payment status. Refer to the [enabling webhooks](/enabling-webhooks) guide for details.
