Apple Pay on the Web with Stripe.js v2

This guide takes you through the process of getting set up with Apple Pay on the Web, all the way through making your first charge. Refer to our iOS app guide for integrating Apple Pay into a native iOS app.

Apple Pay on the Web lets you access payment details that your users have stored in their Wallet. If they're using Safari on their iPhone or iPad, when they tap "Buy with Apple Pay" on your site, they'll be shown a modal payment sheet. If they're using Safari on their Mac, and have an iOS device in range, they'll be prompted on their device to authorize the payment, which will then be sent to the browser. The underlying JavaScript is exactly the same—you can write a single integration, and it'll work in both circumstances.

Try it out!

You can see what it's like right here on this page! Don't worry, your card won't be charged.

If you have Xcode 8 installed, you can also develop your site in Safari inside the iOS simulator.

Step 1: Set up the Apple Pay Sandbox

To use Apple Pay while developing your site, you'll need to use the Apple Pay Sandbox. Getting it set up takes just a few minutes.

  1. If you don't have one already, create an Apple Developer account.
  2. Log into iTunes Connect.
  3. Select Users and Roles, then select the Sandbox Testers link at the top of the page.
  4. Next to "Testers", click to create a new test user. Fill out the page, taking note of the email and password you used, and click Save in the upper right.
  5. On your test iOS device, open the Settings app and tap iCloud. If you're signed in, tap Sign Out at the bottom.
  6. Log in using the new test credentials you just made.
  7. Tap Back to return to the first page in Settings, then tap Wallet & Apple Pay.
  8. Tap Add Credit or Debit Card, then when prompted to photograph your card tap Enter Card Details Manually.
  9. Enter 4761 1200 1000 0492, expiration 11/2022, CVV 533 (this is a test Visa card; for more test cards see the Apple Pay Sandbox Guide).

Step 2: Add an Apple Pay button to your site

Start by adding a button to the HTML on your product page. Safari now ships with built-in Apple Pay images; you can use them with Safari's -webkit-named-image feature. This button should be hidden by default.

<style> #apple-pay-button { display: none; background-color: black; background-image: -webkit-named-image(apple-pay-logo-white); background-size: 100% 100%; background-origin: content-box; background-repeat: no-repeat; width: 100%; height: 44px; padding: 10px 0; border-radius: 10px; } </style> <button id="apple-pay-button"></button>

(You can, of course, build and style this input however you like; the above snippet renders a black Apple Pay button identical to the one in the demo above.)

Next, ensure that Stripe.js v2 is included on your page.

<script type="text/javascript" src=""></script>

After you set your publishable key, you can use the checkAvailability function to determine whether or not to show an Apple Pay button.

Stripe.setPublishableKey('pk_test_TYooMQauvdEDq54NiTphI7jx'); Stripe.applePay.checkAvailability(function(available) { if (available) { document.getElementById('apple-pay-button').style.display = 'block'; } });

Note that this function executes asynchronously; you must pass it a callback function. When using the Apple Pay Sandbox as described above, this will always callback with true. Otherwise it will callback with false until you verify your domain as explained in Going Live below.

Step 3: Start an Apple Pay Session

Assuming Apple Pay is available, when the user taps this payment button, show the Apple Pay sheet. This must be done in response to a tap or click event, so we'll do this by adding an event listener to the button's click event.

document.getElementById('apple-pay-button').addEventListener('click', beginApplePay);

Within the event listener, first create a PaymentRequest object. The total, countryCode, and currencyCode properties are all required; Stripe will set sane defaults for everything else. Note that unlike with other Stripe APIs that use an integer amount in cents to represent prices (e.g., 1999), Apple uses a formatted string for total.amount(e.g., '19.99').

function beginApplePay() { var paymentRequest = { countryCode: 'US', currencyCode: 'USD', total: { label: '', amount: '19.99' } }; var session = ...; // continued below }

Next, use another helper function in Stripe.js, buildSession, to turn this PaymentRequest into an ApplePaySession.

The second argument to buildSession is a function that will be called when the user has authorized the payment. This function takes two arguments. The first, result, will contain a Stripe token. You should pass this token to your server and create a charge (the example below uses jQuery to POST the token to a hypothetical /charges API on your server). If you're looking to make a recurring payment, you can instead attach the token to a customer and then subscribe them to a Plan. When you're done doing this work on your server, call the second parameter, completion, with ApplePaySession.STATUS_SUCCESS or ApplePaySession.STATUS_FAILURE depending on if your charge succeeded or failed. This will then show the user a success or failure animation in the payment sheet and dismiss it.

The third argument to buildSession is optional; it is a function that will be called if Stripe encounters an error with your configuration or has a problem with your user's payment information.

If the user declines to authorize payment and dismisses the modal payment sheet, the session object will trigger a cancel event. You can implement custom behavior for the event by attaching an event listener or oncancel function to the session object.

function beginApplePay() { var paymentRequest = ...; // see above var session = Stripe.applePay.buildSession(paymentRequest, function(result, completion) { $.post('/charges', { token: }).done(function() { completion(ApplePaySession.STATUS_SUCCESS); // You can now redirect the user to a receipt page, etc. window.location.href = '/success.html'; }).fail(function() { completion(ApplePaySession.STATUS_FAILURE); }); }, function(error) { console.log(error.message); }); session.oncancel = function() { console.log("User hit the cancel button in the payment window"); }; session.begin(); }

Finally, after building your ApplePaySession using the buildSession helper, call begin() on it to show the user the payment sheet!

Step 4: Verify your domain to go live

To use Apple Pay with your live API key, you need to register with Apple all of your web domains that will be showing an Apple Pay button. This includes both top-level domains (e.g., and subdomains (e.g.,

Important note: Apple's documentation for Apple Pay on the Web describes their process of "merchant validation", which Stripe handles for you behind the scenes. You do not need to create an Apple Merchant ID, CSR, etc., as described in their documentation, and should instead just follow these steps:

  1. Download this domain association file and host it at /.well-known/apple-developer-merchantid-domain-association on your site. For example, if you're registering, make that file available at
  2. Next, tell Stripe to register your domain with Apple. You can do this by either going to the Apple Pay settings in the Dashboard, or by directly using the API with your live secret key as shown below. Note that we've redacted your live secret key here. You can find your API key in the Dashboard and replace sk_live_•••••••••••••••••••••••• below with your live secret key.
    curl \ -u sk_live_••••••••••••••••••••••••: \ -d domain_name=""
    Stripe.api_key = 'sk_live_••••••••••••••••••••••••' Stripe::ApplePayDomain.create({ domain_name: '', })
    stripe.api_key = 'sk_live_••••••••••••••••••••••••' stripe.ApplePayDomain.create( domain_name='', )
    \Stripe\Stripe::setApiKey('sk_live_••••••••••••••••••••••••'); \Stripe\ApplePayDomain::create([ 'domain_name' => '', ]);
    var stripe = require('stripe')('sk_live_••••••••••••••••••••••••'); stripe.applePayDomains.create({ domain_name: '' });
    Stripe.apiKey = "sk_live_••••••••••••••••••••••••"; Map<String, Object> domainParams = new HashMap<String, Object>(); domainParams.put("domain_name", ""); ApplePayDomain.create(domainParams);
    stripe.Key = "sk_live_••••••••••••••••••••••••"; params := &stripe.ApplePayDomainParams{ DomainName: stripe.String(""), } domain, _ := applepaydomain.New(params)
    StripeConfiguration.ApiKey = "sk_live_••••••••••••••••••••••••"; var options = new ApplePayDomainCreateOptions { DomainName = "", }; var service = new ApplePayDomainService(); var domain = service.Create(options);
  3. Once you're registered, you'll be able to make payments on your site outside of the Apple Pay Sandbox using your live API keys.

Set up Apple Pay with Stripe Connect (optional)

If you have a Connect application and would like to accept payments on behalf of your users via Apple Pay, make these two changes to your integration:

  • On your frontend, before calling any Apple Pay code, you should set the Stripe.applePay.stripeAccount property to your connected account's Stripe ID:
    Stripe.applePay.stripeAccount = 'acct_rS1eBdDRIyD4jo';
  • When registering domains, you should always use the API, not the Dashboard. You should use your platform's secret key to authenticate the request, and you should set the Stripe-Account header to your connected account's Stripe ID, as described in Making API calls for connected accounts.
    curl \ -u {PLATFORM_SECRET_KEY}: \ -H "Stripe-Account: {{CONNECTED_STRIPE_ACCOUNT_ID}}" \ -d domain_name=""
    Stripe.api_key = '{{PLATFORM_SECRET_KEY}}' Stripe::ApplePayDomain.create( {domain_name: ''}, {stripe_account: '{{CONNECTED_STRIPE_ACCOUNT_ID}}'} )
    stripe.api_key = '{{PLATFORM_SECRET_KEY}}' stripe.ApplePayDomain.create( domain_name='', stripe_account='{{CONNECTED_STRIPE_ACCOUNT_ID}}' )
    \Stripe\Stripe::setApiKey('{{PLATFORM_SECRET_KEY}}'); \Stripe\ApplePayDomain::create( ['domain_name' => ''], ['stripe_account' => '{{CONNECTED_STRIPE_ACCOUNT_ID}}'] );
    Stripe.apiKey = "{{PLATFORM_SECRET_KEY}}"; RequestOptions requestOptions = RequestOptions.builder().setStripeAccount("{{CONNECTED_STRIPE_ACCOUNT_ID}}").build(); Map<String, Object> domainParams = new HashMap<String, Object>(); domainParams.put("domain_name", ""); ApplePayDomain.create(domainParams, requestOptions);
    var stripe = require('stripe')('{{PLATFORM_SECRET_KEY}}'); const applePayDomain = await stripe.applePayDomains.create( {domain_name: ''}, {stripeAccount: '{{CONNECTED_STRIPE_ACCOUNT_ID}}'} );
    stripe.Key = "sk_live_••••••••••••••••••••••••"; params := &stripe.ApplePayDomainParams{ DomainName: stripe.String(""), } params.SetStripeAccount("{{CONNECTED_STRIPE_ACCOUNT_ID}}") domain, _ := applepaydomain.New(params)
    StripeConfiguration.ApiKey = "sk_live_••••••••••••••••••••••••"; var options = new ApplePayDomainCreateOptions { DomainName = "", }; var requestOptions = new RequestOptions(); requestOptions.StripeAccount = "{{CONNECTED_STRIPE_ACCOUNT_ID}}"; var service = new ApplePayDomainService(); var domain = service.Create(options, requestOptions);

Next steps

Once you've successfully made an Apple Pay charge on your website, you can optionally start collecting your users' billing/shipping address, offering them different shipping options, and more.

Was this page helpful?
Questions? Contact us.
Developer tutorials on YouTube.