Sign in
An image of the Stripe logo
Create account
Sign in
Home
Payments
Business operations
Financial services
Developer tools
No-code
All products
Home
Payments
Business operations
Home
Payments
Business operations
Financial services
Developer tools
Support
Overview
Online payments
Products and prices
Invoicing
Subscriptions
Quotes
In-person payments
Multiparty payments
After the payment
Add payment methods
Payment Links
Stripe Checkout
Stripe Elements
    Overview
    Elements
    Address Element
    Payment Element
    Payment Request Button
    Other Guides
    Elements Appearance API
About the APIs
Regulation support
Implementation guides
Testing
Elements
·
HomePaymentsStripe Elements

Payment Request Button

Collect payment and address information from customers who use Apple Pay, Google Pay, or Link.
Either your browser does not support the Payment Request API, or you do not have a saved payment method. To try out the Payment Request Button live demo, switch to one of the supported browsers below, and make sure you have a saved payment method.

The Payment Request Button Element gives you a single integration for Apple Pay, Google Pay, and Link—Stripe’s one-click checkout product.

Apple Pay Button, Google Pay Button, and Link Button

The relevant button will be displayed automatically.

The Payment Request Button dynamically displays wallet options to optimize checkout for your customers. Customers see Apple Pay or Google Pay if they’ve enabled them on their device, and depending on what browser they’re using. If a customer doesn’t have Apple Pay or Google Pay enabled on their device, they see Link. Additionally, customers using Chrome with active, authenticated Link sessions see Link.

Browser + WalletPayment Button
Safari + Apple Pay enabledApple Pay
Chrome + Link authenticatedLink
Chrome + Google Pay enabled and Link not authenticatedGoogle Pay
Chrome on iOS 16 + Apple Pay and Google Pay enabledApple Pay
Any browser + No active Apple Pay or Google PayLink

Prerequisites

Before you start, you need to:

  • Review the requirements for each payment button type:
    • Apple Pay requires additional steps, and requires macOS 10.12.1+ or iOS 10.1+.
    • Compatible devices automatically support Google Pay.
  • Add a payment method to your browser. For example, you can save a card in Chrome, add a card to your Google Pay account or add a card to your Wallet for Safari.
  • Serve your application over HTTPS. This is a requirement both in development and in production. One way to get up and running is to use a service like ngrok.
  • Verify your domain with Apple Pay, both in development and production.

Verify your domain with Apple Pay

To use Apple Pay, you need to register with Apple all of your web domains that will show an Apple Pay button. This includes both top-level domains (for example, stripe.com) and subdomains (for example, shop.stripe.com). You need to do this for domains you use in both production and testing. When testing locally, use a tool like ngrok to get an HTTPS domain.

Apple’s documentation for Apple Pay on the Web describes their process of “merchant validation,” which Stripe handles for you behind the scenes. You don’t need to create an Apple Merchant ID, CSR, and so on, as described in their documentation. Instead, follow the steps in this section.

  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 https://example.com, make that file available at https://example.com/.well-known/apple-developer-merchantid-domain-association.

  2. Next, tell Stripe to register your domain with Apple. You can do this by either going to the Apple Pay tab in the Account Settings of your Dashboard, or by directly using the API with your live secret key as shown below.

    We’ve redacted your live secret key here—head to your Dashboard and replace sk_live_•••••••••••••••••••••••• below with your live secret key. All domains, whether in production or testing, must be registered with your live secret key.

Command Line
curl https://api.stripe.com/v1/apple_pay/domains \ -u "sk_live_••••••••••••••••••••••••": \ -d domain_name="example.com"
  1. After registering your domains, you can make payments on your site using your live API keys.

Set up Stripe Elements
Client-side

Elements is available as part of Stripe.js. Include this in your page and create a container that will be used for the paymentRequestButton Element:

<script src="https://js.stripe.com/v3/"></script> <div id="payment-request-button"> <!-- A Stripe Element will be inserted here. --> </div>

Your Stripe publishable API key is also required as it identifies your website to Stripe:

client.js
const stripe = Stripe(
'pk_test_TYooMQauvdEDq54NiTphI7jx'
, { apiVersion: "2022-11-15", });

Create a paymentRequest instance
Client-side

Create an instance of stripe.paymentRequest with all required options.

client.js
const paymentRequest = stripe.paymentRequest({ country: 'US', currency: 'usd', total: { label: 'Demo total', amount: 1099, }, requestPayerName: true, requestPayerEmail: true, });

Use the requestPayerName parameter to collect the payer’s billing address for Apple Pay and Link. You can use the billing address to perform address verification and block fraudulent payments. All other payment methods automatically collect the billing address when one is available.

Create and mount the paymentRequestButton
Client-side

Create the paymentRequestButton Element and check to make sure that your customer has an active payment method using canMakePayment(). If they do, mount the Element to the container to display the Payment Request Button. If they don’t, you can’t mount the Element, and we encourage you to show a traditional checkout form instead.

If you accept Apple Pay with the Payment Request Button, you must offer Apple Pay as the primary payment option on your website per Apple guidelines. Internally, the Payment Request Button uses the Apple Pay canMakePaymentWithActiveCard API.

client.js
const elements = stripe.elements(); const prButton = elements.create('paymentRequestButton', { paymentRequest, }); (async () => { // Check the availability of the Payment Request API first. const result = await paymentRequest.canMakePayment(); if (result) { prButton.mount('#payment-request-button'); } else { document.getElementById('payment-request-button').style.display = 'none'; } })();

Create a PaymentIntent
Server-side

Stripe uses a PaymentIntent object to represent your intent to collect payment from a customer, tracking charge attempts and payment state changes throughout the process.

Create a PaymentIntent on your server with an amount and currency. Always decide how much to charge on the server side, a trusted environment, as opposed to the client. This prevents malicious customers from being able to choose their own prices.

Command Line
curl https://api.stripe.com/v1/payment_intents \ -u
sk_test_4eC39HqLyjWDarjtT1zdp7dc
: \ -d "amount"=1099 \ -d "currency"="usd"

Included in the returned PaymentIntent is a client secret, which you’ll use to securely complete the payment process instead of passing the entire PaymentIntent object. Send the client secret back to the client to use in the next step.

Complete the payment
Client-side

Listen to the paymentmethod event to receive a PaymentMethod object. Pass the PaymentMethod ID and the PaymentIntent’s client secret to stripe.confirmCardPayment to complete the payment.

client.js
paymentRequest.on('paymentmethod', async (ev) => { // Confirm the PaymentIntent without handling potential next actions (yet). const {paymentIntent, error: confirmError} = await stripe.confirmCardPayment( clientSecret, {payment_method: ev.paymentMethod.id}, {handleActions: false} ); if (confirmError) { // Report to the browser that the payment failed, prompting it to // re-show the payment interface, or show an error message and close // the payment interface. ev.complete('fail'); } else { // Report to the browser that the confirmation was successful, prompting // it to close the browser payment method collection interface. ev.complete('success'); // Check if the PaymentIntent requires any actions and if so let Stripe.js // handle the flow. If using an API version older than "2019-02-11" // instead check for: `paymentIntent.status === "requires_source_action"`. if (paymentIntent.status === "requires_action") { // Let Stripe.js handle the rest of the payment flow. const {error} = await stripe.confirmCardPayment(clientSecret); if (error) { // The payment failed -- ask your customer for a new payment method. } else { // The payment has succeeded. } } else { // The payment has succeeded. } } });

The customer can dismiss the payment interface in some browsers even after they authorize the payment. This means that you might receive a cancel event on your PaymentRequest object after receiving a paymentmethod event. If you’re using the cancel event as a hook for canceling the customer’s order, make sure you also refund the payment that you just created.

Test your integration

To test your integration you must use HTTPS and a supported browser. If you’re using the paymentRequestButton Element within an iframe, the iframe must have the allow attribute set to equal “payment *”.

In addition, each payment method and browser has specific requirements:

Safari

  • Safari on Mac running macOS Sierra or later.
  • A compatible device with a card in its Wallet paired to your Mac with Handoff, or a Mac with TouchID. You can find instructions on Apple’s Support site.
  • Make sure you’ve verified your domain with Apple Pay.
  • When using an iframe, its origin must match the top-level origin. Two pages have the same origin if the protocol, host (full domain name), and port (if one is specified) are the same for both pages.

Mobile Safari

  • Mobile Safari on iOS 10.1 or later.
  • A card in your Wallet (go to Settings > Wallet & Apple Pay).
  • Make sure you’ve verified your domain with Apple Pay.
  • When using an iframe, its origin must match the top-level origin. Two pages have the same origin if the protocol, host (full domain name), and port (if one is specified) are the same for both pages.

As of iOS 16, Apple Pay might work in some non-Safari mobile browsers with a card saved in your Wallet.

Collect shipping information

To collect shipping information, begin by including requestShipping: true when creating the payment request.

You can also provide an array of shippingOptions at this point, if your shipping options don’t depend on the customer’s address.

const paymentRequest = stripe.paymentRequest({ country: 'US', currency: 'usd', total: { label: 'Demo total', amount: 1099, }, requestShipping: true, // `shippingOptions` is optional at this point: shippingOptions: [ // The first shipping option in this list appears as the default // option in the browser payment interface. { id: 'free-shipping', label: 'Free shipping', detail: 'Arrives in 5 to 7 days', amount: 0, }, ], });

Next, listen to the shippingaddresschange event to detect when a customer selects a shipping address. Use the address to fetch valid shipping options from your server, update the total, or perform other business logic. The address data on the shippingaddresschange event can be anonymized by the browser to not reveal sensitive information that isn’t necessary for shipping cost calculation.

The customer must supply valid shippingOptions at this point to proceed in the flow.

paymentRequest.on('shippingaddresschange', async (ev) => { if (ev.shippingAddress.country !== 'US') { ev.updateWith({status: 'invalid_shipping_address'}); } else { // Perform server-side request to fetch shipping options const response = await fetch('/calculateShipping', { data: JSON.stringify({ shippingAddress: ev.shippingAddress }) }); const result = await response.json(); ev.updateWith({ status: 'success', shippingOptions: result.supportedShippingOptions, }); } });

Display line items

Use displayItems to display PaymentItem objects and show the price breakdown in the browser’s payment interface.

const paymentRequest = stripe.paymentRequest({ country: 'US', currency: 'usd', total: { label: 'Demo total', amount: 2000, }, displayItems: [ { label: 'Sample item', amount: 1000, }, { label: 'Shipping cost', amount: 1000, } ], });

Style the button

Use the following parameters to customize the Element:

elements.create('paymentRequestButton', { paymentRequest, style: { paymentRequestButton: { type: 'default', // One of 'default', 'book', 'buy', or 'donate' // Defaults to 'default' theme: 'dark', // One of 'dark', 'light', or 'light-outline' // Defaults to 'dark' height: '64px', // Defaults to '40px'. The width is always '100%'. }, }, });

Using your own button

If you want to design your own button instead of using the paymentRequestButton Element, you can show your custom button based on the result of paymentRequest.canMakePayment(). Then, use paymentRequest.show() to display the browser interface when your button is clicked.

When building your own button, follow Apple Pay’s Human Interface Guidelines and Google Pay’s Brand Guidelines.

Link isn’t supported in custom button configurations and won’t be shown to the customer if you decide to use one.

Use the Payment Request Button with Stripe Connect

Connect platforms that either create direct charges or add the token to a Customer on the connected account must take some additional steps when using the Payment Request Button.

  1. On your frontend, before creating the PaymentRequest instance, set the stripeAccount option on the Stripe instance:
const stripe = Stripe(
'pk_test_TYooMQauvdEDq54NiTphI7jx'
, { apiVersion: "2022-11-15", stripeAccount: 'CONNECTED_STRIPE_ACCOUNT_ID', });
  1. Register all domains where you plan to show the Payment Request Button with Apple Pay. You can use the Stripe API for this, using your platform’s secret key to authenticate the request, and setting the Stripe-Account header to your connected account’s Stripe ID, as described in Making API calls for connected accounts.

You must use your platform’s live secret key to register the domains—don’t add domains in test mode.

Command Line
curl https://api.stripe.com/v1/apple_pay/domains \ -u {PLATFORM_SECRET_KEY}: \ -H "Stripe-Account:
{{CONNECTED_ACCOUNT_ID}}
"
\ -d domain_name="example.com"

Link for Payment Request Button

Link is Stripe’s one-click checkout product. Link lets your customers securely save their payment information and reuse it on your site and across hundreds of thousands of businesses for faster checkout. When new customers come to your site, they can use Link through the Payment Request Button to pay with their saved payment details. With Link, customers don’t need to manually enter their payment information, resulting in:

  • Faster checkout
  • Higher likelihood of purchase completion
  • Increased customer purchase frequency

Link is fully compatible with the other features you receive from card payments (subscriptions, and so on). There are no additional fees. The same pricing applies to Link for Payment Request Button as for other card payments.

Over time, we’ll increase the number of funding sources customers can pay with through their Link account to match local payment method preferences.

How Link works

Authenticated Link customers can automatically view their payment details after clicking the Link button and pay with one click.

For returning Link customers, when they click the Link button they’re asked to authenticate with an SMS or email code. After the customer authenticates, Link loads their previously saved payment details, and then they can pay with one click. If this customer previously authenticated their account in the last 90 days on your site or through a different Link-enabled business, they won’t need to do it again and can pay instantly.

New Link Customers are prompted to save their information in a Link account when they click the Link button.

Customers can create a Link account by entering email, phone, and payment details for faster checkout on future payments.

You can learn more about your customer’s Link experience in the Link customer FAQ.

Link for Connect Platforms using the Payment Request Button

Link is automatically available through the Payment Request Button to any connected accounts that access the Payment Request Button through a Connect platform integration.

  • If you’re a Connect platform, you can manage Link for your connected accounts through Link settings in your Dashboard.
  • If you’re a connected account processing payments through a Connect platform, your platform manages Link for you when payments are processed through the platform. For payments processed without a platform, you can use the Link settings page in your Dashboard to manage Link for the Payment Request Button.

Managing Link for Payment Request Button

Link is available globally as a wallet through the Payment Request Button, and is enabled automatically, with no code changes required.

Link is enabled by default in the Payment Request Button for all merchants. If you want to turn off Link, you can do so in your Link settings.

See also

  • Learn about Apple Pay
  • Learn about Google Pay

Use of Apple Pay on the web is subject to the Apple Pay on the web terms of service.

Was this page helpful?
Questions? Contact us.
Watch our developer tutorials.
Check out our product changelog.
Powered by Markdoc
You can unsubscribe at any time. Read our privacy policy.
On this page
Prerequisites
Set up Stripe Elements
Create a paymentRequest instance
Create and mount the paymentRequestButton
Create a PaymentIntent
Complete the payment
Test your integration
Collect shipping information
Display line items
Style the button
Use the Payment Request Button with Stripe Connect
Link for Payment Request Button
See also
Stripe Shell
Test mode
Welcome to the Stripe Shell! Stripe Shell is a browser-based shell with the Stripe CLI pre-installed. Login to your Stripe account and press Control + Backtick on your keyboard to start managing your Stripe resources in test mode. - View supported Stripe commands: - Find webhook events: - Listen for webhook events: - Call Stripe APIs: stripe [api resource] [operation] (e.g. )
The Stripe Shell is best experienced on desktop.
$