---
title: "Apple Pay for API only"
description: "Add Apple Pay to an existing API-only integration."
url: "https://docs.adyen.com/payment-methods/apple-pay/api-only"
source_url: "https://docs.adyen.com/payment-methods/apple-pay/api-only.md"
canonical: "https://docs.adyen.com/payment-methods/apple-pay/api-only"
last_modified: "2025-03-05T18:05:00+01:00"
language: "en"
---

# Apple Pay for API only

Add Apple Pay to an existing API-only integration.

Accept Apple Pay payments using our APIs, and build your own payment form to have full control over the look and feel of your checkout page.

Adyen does not currently support China UnionPay cards when using Apple Pay. You cannot send the [merchantCapability](https://developer.apple.com/documentation/apple_pay_on_the_web/applepaypaymentrequest/1916123-merchantcapabilities) "supportsEMV" in your Apple Pay integration.

## Requirements

| Requirement                                                               | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Integration type**                                                      | Make sure that you have built an Advanced flow [API-only integration](/online-payments/build-your-integration/advanced-flow?platform=Web\&integration=API%20only).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| **[Customer Area roles](/account/user-roles)**                            | **Change payment methods** [role](/development-resources/api-credentials/roles/#management-api).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| **[API credential roles](/development-resources/api-credentials/roles/)** | To [process live Apple Pay payments](#going-live) make sure that you have the following role- **API Clientside Encryption Payments role**.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| **Setup steps**                                                           | Before you begin, make sure that you have:- Set up Apple Pay with your own or Adyen's [Apple Pay certificate](/payment-methods/apple-pay/apple-pay-certificate). You can use Adyen's Apple Pay certificate if you have a web integration, which makes it quicker to set up Apple Pay. If you have a mobile integration, use your own Apple Developer account and certificate which requires extra configuration steps.
- [Added Apple Pay in your Customer Area](/payment-methods/add-payment-methods).
- Read the Apple Pay documentation to learn about how you can offer Apple Pay on the [web](https://developer.apple.com/documentation/apple_pay_on_the_web/apple_pay_js_api), or in your [mobile app](https://developer.apple.com/documentation/passkit/offering-apple-pay-in-your-app). |

## Build your payment form for Apple Pay

After you have finished setting up Apple Pay, you can show Apple Pay as an available payment method in [countries/regions where Apple Pay is supported](https://www.adyen.com/payment-methods#pmx=apple-pay). You can [download logos](/online-payments/build-your-integration/advanced-flow/?platform=Web\&integration=API%20only#downloading-logos) for Apple Pay which you can use on your payment form.

When the shopper selects Apple Pay, they are presented with a prompt to verify the payment using Touch ID or Face ID. If the shopper is using a Mac without Touch ID, they will be prompted to verify the payment using an iPhone or Apple Watch registered to the same iCloud account.

1. Make a [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) request, specifying:

   * [countryCode](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods): Countries/regions where Apple Pay is supported. For example, **NL**.
   * [amount.currency](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods#request-amount): Any supported currency. For example, **EUR**.
   * [channel](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods#request-channel): Set this to **Web** if the payment is being initiated from Safari, or **iOS** for in-app payments.

2. In the response, you receive:

   * `type`: **applepay**.
   * `merchantId` and `merchantName`: If you use Adyen's Apple Pay certificate, you need these details in the next step to [complete the Apple Pay session validation](/payment-methods/apple-pay/api-only?tab=adyen-certificate-validation_1).

```json
{
  "paymentMethods": [
    ...
    {
        "brands": [
            "amex",
            "mc"
        ],
        "configuration": {
            "merchantId": "com.test.merchant",
            "merchantName": "Your Store"
        },
        "details": [
            {
                "key": "applepay.token",
                "type": "applePayToken"
            }
        ],
        "name": "Apple Pay",
        "type": "applepay"
    },
    ...
  ]
}
```

## Complete the Apple Pay session validation

This step is only required for web integrations. You do not need to complete the Apple Pay session validation for in-app payments.

When the shopper selects to pay with Apple Pay, you get the [`onvalidatemerchant` ](https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession/1778021-onvalidatemerchant)event handler. You then need to complete the Apple Pay session validation using the [`completeMerchantValidation` ](https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession/1778015-completemerchantvalidation)method.

You can do this by using Adyen's Apple Pay certificate, or you can use your own:

### Tab: Use Adyen's Apple Pay certificate

1. Make an `/applePay/sessions` call to retrieve the payment session for Apple Pay, and include:

   | Parameters           | Required                                                                                    | Description                                                                                                                                                       |
   | -------------------- | ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
   | `displayName`        | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The value of the `configuration.merchantName` field from the [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) response. |
   | `domainName`         | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The domain name you provided when you added Apple Pay in your Customer Area. This has to match the `window.location.hostname` of the web shop.                    |
   | `merchantIdentifier` | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | The value of `configuration.merchantId` field from the [/paymentMethods](https://docs.adyen.com/api-explorer/Checkout/latest/post/paymentMethods) response.       |

   **/applePay/sessions request**

   ```sh
   curl https://checkout-test.adyen.com/v64/applePay/sessions \
   -H 'x-api-key: ADYEN_API_KEY' \
   -H 'content-type: application/json' \
   -d '{
     "displayName": "YOUR_MERCHANT_NAME",
     "domainName": "YOUR_DOMAIN_NAME",
     "merchantIdentifier": "YOUR_MERCHANT_ID"
   }'
   ```

2. Decode the base64-encoded `data` object you get in the response:

   **/applePay/sessions response**

   ```json
   {
     "data": "BASE_64_ENCODED_DATA"
   }
   ```

3. Pass the decoded data as an object to the [`completeMerchantValidation` ](https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession/1778015-completemerchantvalidation)method to complete the Apple Pay session validation.

### Tab: Use your own Apple Pay certificate

1. [Request a valid session](https://developer.apple.com/documentation/apple_pay_on_the_web/apple_pay_js_api/requesting_an_apple_pay_payment_session) from the Apple Pay server.

2. Use the session object from the response to [complete the Apple Pay session validation](https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession/1778015-completemerchantvalidation)

The Apple Pay session data expires after five minutes, so make sure you complete the Apple Pay session validation within this time.

If the Apple Pay session is successfully validated, Apple Pay prompts the shopper to authorize the payment using Touch ID or Face ID.

## Make a payment

1. After the shopper authorizes the payment, get the token from the Apple Pay framework and decrypt it in one of two ways:

   * [Let Adyen handle the decryption](/payment-methods/apple-pay/api-only/apple-pay-token-decryption#let-adyen-handle-the-decryption)
   * [Handle the decryption yourself](/payment-methods/apple-pay/api-only/apple-pay-token-decryption#handle-the-decryption-on-your-own). This is only allowed if you are PCI-compliant.

2. Stringify and Base64-encode the entire `paymentData` object.

3. From your server, make a [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) request providing:

   * `paymentMethod.type`: **applepay**
   * `applePayToken`: The stringified and base64 encoded `paymentData` you retrieved from the Apple framework. 

   #### curl

   ```bash
   curl https://checkout-test.adyen.com/v72/payments \
   -H 'x-api-key: ADYEN_API_KEY' \
   -H 'content-type: application/json' \
   -d '{
     "merchantAccount":"ADYEN_MERCHANT_ACCOUNT",
     "reference":"YOUR_ORDER_NUMBER",
     "amount":{
       "currency":"EUR",
       "value":1000
     },
     "paymentMethod":{
       "type":"applepay",
       "applePayToken": "QWIwMmI0YzAhQlFBQkFnQjMv.."
     },
     "returnUrl":"https://your-company.example.com/checkout?shopperOrder=12xy.."
   }'
   ```

   #### Java

   ```java
   // Adyen Java API Library v27.0.0
   import com.adyen.Client;
   import com.adyen.enums.Environment;
   import com.adyen.model.checkout.*;
   import java.time.OffsetDateTime;
   import java.util.*;
   import com.adyen.model.RequestOptions;
   import com.adyen.service.checkout.*;

   // For the live environment, additionally include your liveEndpointUrlPrefix.
   Client client = new Client("ADYEN_API_KEY", Environment.TEST);

   // Create the request object(s)
   Amount amount = new Amount()
     .currency("EUR")
     .value(1000L);

   ApplePayDetails applePayDetails = new ApplePayDetails()
     .applePayToken("QWIwMmI0YzAhQlFBQkFnQjMv..")
     .type(ApplePayDetails.TypeEnum.APPLEPAY);

   PaymentRequest paymentRequest = new PaymentRequest()
     .reference("YOUR_ORDER_NUMBER")
     .amount(amount)
     .merchantAccount("ADYEN_MERCHANT_ACCOUNT")
     .paymentMethod(new CheckoutPaymentMethod(applePayDetails))
     .returnUrl("https://your-company.example.com/checkout?shopperOrder=12xy..");

   // Send the request
   PaymentsApi service = new PaymentsApi(client);
   PaymentResponse response = service.payments(paymentRequest, new RequestOptions().idempotencyKey("UUID"));
   ```

   #### PHP

   ```php
   // Adyen PHP API Library v19.0.0
   use Adyen\Client;
   use Adyen\Environment;
   use Adyen\Model\Checkout\Amount;
   use Adyen\Model\Checkout\CheckoutPaymentMethod;
   use Adyen\Model\Checkout\PaymentRequest;
   use Adyen\Service\Checkout\PaymentsApi;

   $client = new Client();
   $client->setXApiKey("ADYEN_API_KEY");
   // For the live environment, additionally include your liveEndpointUrlPrefix.
   $client->setEnvironment(Environment::TEST);


   // Create the request object(s)
   $amount = new Amount();
   $amount
     ->setCurrency("EUR")
     ->setValue(1000);

   $checkoutPaymentMethod = new CheckoutPaymentMethod();
   $checkoutPaymentMethod
     ->setApplePayToken("QWIwMmI0YzAhQlFBQkFnQjMv..")
     ->setType("applepay");

   $paymentRequest = new PaymentRequest();
   $paymentRequest
     ->setReference("YOUR_ORDER_NUMBER")
     ->setAmount($amount)
     ->setMerchantAccount("ADYEN_MERCHANT_ACCOUNT")
     ->setPaymentMethod($checkoutPaymentMethod)
     ->setReturnUrl("https://your-company.example.com/checkout?shopperOrder=12xy..");

   $requestOptions['idempotencyKey'] = 'UUID';

   // Send the request
   $service = new PaymentsApi($client);
   $response = $service->payments($paymentRequest, $requestOptions);
   ```

   #### C\#

   ```cs
   // Adyen .net API Library v17.0.0
   using Adyen;
   using Environment = Adyen.Model.Environment;
   using Adyen.Model;
   using Adyen.Model.Checkout;
   using Adyen.Service.Checkout;

   // For the live environment, additionally include your liveEndpointUrlPrefix.
   var config = new Config()
   {
       XApiKey = "ADYEN_API_KEY",
       Environment = Environment.Test
   };
   var client = new Client(config);

   // Create the request object(s)
   Amount amount = new Amount
   {
     Currency = "EUR",
     Value = 1000
   };

   ApplePayDetails applePayDetails = new ApplePayDetails
   {
     ApplePayToken = "QWIwMmI0YzAhQlFBQkFnQjMv..",
     Type = ApplePayDetails.TypeEnum.Applepay
   };

   PaymentRequest paymentRequest = new PaymentRequest
   {
     Reference = "YOUR_ORDER_NUMBER",
     Amount = amount,
     MerchantAccount = "ADYEN_MERCHANT_ACCOUNT",
     PaymentMethod = new CheckoutPaymentMethod(applePayDetails),
     ReturnUrl = "https://your-company.example.com/checkout?shopperOrder=12xy.."
   };

   // Send the request
   var service = new PaymentsService(client);
   var response = service.Payments(paymentRequest, requestOptions: new RequestOptions { IdempotencyKey = "UUID"});
   ```

   #### NodeJS (JavaScript)

   ```js
   // Adyen Node API Library v18.0.0
   // Require the parts of the module you want to use
   const { Client, CheckoutAPI } = require('@adyen/api-library');
   // Initialize the client object
   // For the live environment, additionally include your liveEndpointUrlPrefix.
   const client = new Client({apiKey: "ADYEN_API_KEY", environment: "TEST"});

   // Create the request object(s)
   const paymentRequest = {
     merchantAccount: "ADYEN_MERCHANT_ACCOUNT",
     reference: "YOUR_ORDER_NUMBER",
     amount: {
       currency: "EUR",
       value: 1000
     },
     paymentMethod: {
       type: "applepay",
       applePayToken: "QWIwMmI0YzAhQlFBQkFnQjMv.."
     },
     returnUrl: "https://your-company.example.com/checkout?shopperOrder=12xy.."
   }

   // Send the request
   const checkoutAPI = new CheckoutAPI(client);
   const response = checkoutAPI.PaymentsApi.payments(paymentRequest, { idempotencyKey: "UUID" });
   ```

   #### Go

   ```go
   // Adyen Go API Library v10.4.0
   import (
     "context"
     "github.com/adyen/adyen-go-api-library/v9/src/common"
     "github.com/adyen/adyen-go-api-library/v9/src/adyen"
     "github.com/adyen/adyen-go-api-library/v9/src/checkout"
   )
   // For the live environment, additionally include your liveEndpointUrlPrefix.
   client := adyen.NewClient(&common.Config{
     ApiKey:      "ADYEN_API_KEY",
     Environment: common.TestEnv,
   })

   // Create the request object(s)
   amount := checkout.Amount{
     Currency: "EUR",
     Value: 1000,
   }

   applePayDetails := checkout.ApplePayDetails{
     ApplePayToken: "QWIwMmI0YzAhQlFBQkFnQjMv..",
     Type: common.PtrString("applepay"),
   }

   paymentRequest := checkout.PaymentRequest{
     Reference: "YOUR_ORDER_NUMBER",
     Amount: amount,
     MerchantAccount: "ADYEN_MERCHANT_ACCOUNT",
     PaymentMethod: checkout.ApplePayDetailsAsCheckoutPaymentMethod(&applePayDetails),
     ReturnUrl: "https://your-company.example.com/checkout?shopperOrder=12xy..",
   }

   // Send the request
   service := client.Checkout()
   req := service.PaymentsApi.PaymentsInput().IdempotencyKey("UUID").PaymentRequest(paymentRequest)
   res, httpRes, err := service.PaymentsApi.Payments(context.Background(), req)
   ```

   #### Python

   ```py
   # Adyen Python API Library v12.5.1
   import Adyen

   adyen = Adyen.Adyen()
   adyen.client.xapikey = "ADYEN_API_KEY"
   # For the live environment, additionally include your liveEndpointUrlPrefix.
   adyen.client.platform = "test" # The environment to use library in.

   # Create the request object(s)
   json_request = {
     "merchantAccount": "ADYEN_MERCHANT_ACCOUNT",
     "reference": "YOUR_ORDER_NUMBER",
     "amount": {
       "currency": "EUR",
       "value": 1000
     },
     "paymentMethod": {
       "type": "applepay",
       "applePayToken": "QWIwMmI0YzAhQlFBQkFnQjMv.."
     },
     "returnUrl": "https://your-company.example.com/checkout?shopperOrder=12xy.."
   }

   # Send the request
   result = adyen.checkout.payments_api.payments(request=json_request, idempotency_key="UUID")
   ```

   #### Ruby

   ```rb
   # Adyen Ruby API Library v9.5.1
   require "adyen-ruby-api-library"

   adyen = Adyen::Client.new
   adyen.api_key = 'ADYEN_API_KEY'
   # For the live environment, additionally include your liveEndpointUrlPrefix.
   adyen.env = :test # Set to "live" for live environment

   # Create the request object(s)
   request_body = {
     :merchantAccount => 'ADYEN_MERCHANT_ACCOUNT',
     :reference => 'YOUR_ORDER_NUMBER',
     :amount => {
       :currency => 'EUR',
       :value => 1000
     },
     :paymentMethod => {
       :type => 'applepay',
       :applePayToken => 'QWIwMmI0YzAhQlFBQkFnQjMv..'
     },
     :returnUrl => 'https://your-company.example.com/checkout?shopperOrder=12xy..'
   }

   # Send the request
   result = adyen.checkout.payments_api.payments(request_body, headers: { 'Idempotency-Key' => 'UUID' })
   ```

   #### NodeJS (TypeScript)

   ```ts
   // Adyen Node API Library v18.0.0
   // Require the parts of the module you want to use
   import { Client, CheckoutAPI, Types } from "@adyen/api-library";
   // Initialize the client object
   // For the live environment, additionally include your liveEndpointUrlPrefix.
   const client = new Client({apiKey: "ADYEN_API_KEY", environment: "TEST"});

   // Create the request object(s)
   const amount: Types.checkout.Amount = {
     currency: "EUR",
     value: 1000
   };

   const applePayDetails: Types.checkout.ApplePayDetails = {
     applePayToken: "QWIwMmI0YzAhQlFBQkFnQjMv..",
     type: Types.checkout.ApplePayDetails.TypeEnum.Applepay
   };

   const paymentRequest: Types.checkout.PaymentRequest = {
     reference: "YOUR_ORDER_NUMBER",
     amount: amount,
     merchantAccount: "ADYEN_MERCHANT_ACCOUNT",
     paymentMethod: applePayDetails,
     returnUrl: "https://your-company.example.com/checkout?shopperOrder=12xy.."
   };

   // Send the request
   const checkoutAPI = new CheckoutAPI(client);
   const response = checkoutAPI.PaymentsApi.payments(paymentRequest, { idempotencyKey: "UUID" });
   ```

   The response contains the result of the payment.

   ```json
   {
     "pspReference": "881539337151149C",
     "resultCode": "Authorised"
   }
   ```

## Present the payment result

Use the `resultCode` that you received in response to your [/payments](https://docs.adyen.com/api-explorer/Checkout/latest/post/payments) call to present the payment result to your shopper.

The `resultCode` values you can receive for Apple Pay are:

| resultCode     | Description                                    | Action to take                                                             |
| -------------- | ---------------------------------------------- | -------------------------------------------------------------------------- |
| **Authorised** | The payment was successful.                    | Inform the shopper that the payment has been successful.                   |
| **Refused**    | The payment was refused by the shopper's bank. | Ask the shopper to try the payment again using a different payment method. |

## Recurring payments

To make recurring Apple Pay payments, first [create a shopper token](/online-payments/tokenization/create-tokens) and then [make subsequent recurring transactions](/online-payments/tokenization/make-token-payments) with the token.

## Test and go live

Use Apple's test card numbers to test your integration.

For a full list of test cards and instructions how to add these to your test device, see [Sandbox testing](https://developer.apple.com/apple-pay/sandbox-testing/) on Apple's Developer website.

Check the status of an Apple Pay test payment in your [Customer Area](https://ca-test.adyen.com/) > **Transactions** >&#x20;**&#xA0;Payments**.

### Going live

To process live Apple Pay payments, your API credential needs to have the **API Clientside Encryption Payments role**. You can check this in your [live Customer Area](https://ca-live.adyen.com/) or ask your Admin user to verify.

Enable Apple Pay either using Adyen's Apple Pay certificate, which is quicker, or you can also use your own Apple Developer account and certificate which requires extra configuration steps:

### Tab: Use Adyen's Apple Pay certificate

1. Download and unzip the [domain association file](/payment-methods/apple-pay/api-only/apple-developer-merchantid-domain-association-2024.zip).

2. Host the domain association file on each domain you want to use, including subdomains. To host the file, use the exact file name **apple-developer-merchantid-domain-association** under the following path:

   ```bash
   /.well-known/apple-developer-merchantid-domain-association
   ```

   The file must:

   * Have `Content-Type: text/plain` in the header.
   * Be externally accessible.
   * Not be password protected.
   * Not be behind a proxy or redirect.

   See an example of a [working domain association file](https://eu.adyen.link/.well-known/apple-developer-merchantid-domain-association).

3. [Add Apple Pay in your live Customer Area](/payment-methods/add-payment-methods)

   * You'll be asked for **Shop websites**: your website URLs, for example `https://www.mystore.com`. If you add more than one, separate them with a comma.

4. To update or add new Apple Pay domains:

   1. Go to [live Customer Area](https://ca-live.adyen.com/) > **Payment Methods**.

   2. Select the specific Apple Pay payment method you want to update.

   3. In the sidebar on the right, go to the **Apple Pay domains** section to find a list of domains currently configured for this payment method. To update the domains, select the **Edit** button next to the Apple Pay domains heading.\
      A new sidebar opens where you can make the necessary changes. If there are any errors, this is indicated with red dot.

   4. To view and fix any errors, select **Edit** next to the affected domain.

      * You must be assigned the **Change payment methods** role in Customer Area to be able to make domain updates.
      * Domain configuration updates apply only to the generic Apple Pay payment method. Scheme-specific variants, like AMEX Apple Pay, Visa Apple Pay, and Mastercard Apple Pay, do not require domain configuration and are not supported by this flow.

### Tab: Use your own Apple Pay certificate

1. [Set up Apple Pay](/payment-methods/apple-pay/apple-pay-certificate/web) on your Apple Pay Developer account for your live merchant identifier.

2. Configure your firewall's allow-list:

   * [Allow Apple IP Addresses for Domain Verification](https://developer.apple.com/documentation/apple_pay_on_the_web/setting_up_your_server)
   * Include `out.adyen.com` in your configuration to allow communication from our network.

   We do not provide a list of IP addresses for allow-listing, because over time the list may change for various reasons, for example, due to ISP configuration changes.

   If you are unable to configure your firewall with a domain allow-list, attempt to resolve our IP addresses by performing a DNS lookup on `out.adyen.com`, and then add those IP addresses to your allow-list. Beware that you still run the risk of a disruption if the IP addresses change.

## See also

* [API-only integration guide](/online-payments/api-only)
* [Apple Pay documentation](https://developer.apple.com/apple-pay/implementation)
* [Tokenization](/online-payments/tokenization)
* [Apple Pay error codes](/development-resources/error-codes#apple-pay-error-codes)
* [API Explorer](https://docs.adyen.com/api-explorer/#/CheckoutService/latest/overview)
