Accept a payment with the Express Checkout Element (2024)

Use a single integration to accept payments through one-click payment buttons.

The Express Checkout Element gives you a single integration for accepting payments through one-click payment buttons, including Link, PayPal, Apple Pay, Google Pay, and Amazon Pay.

Customers see different payment buttons depending on what their device and browser combination supports. Compatible devices automatically support Google Pay and Link. Supporting Apple Pay and PayPal requires additional steps.

We recommend that you collect payment details before creating an Intent when using the Express Checkout Element. If you previously integrated with the Payment Element, you might need to update your integration to this preferred approach.

Before you beginAccept a payment with the Express Checkout Element (1)

  • Add a payment method to your browser. For example, you can add a card to your Google Pay account or to your Wallet for Safari.
  • Serve your application over HTTPS. This is required in development and in production. You can use a service such as ngrok.
  • Register and verify your domain in both test mode and live mode.
  • Create a PayPal Sandbox account to test your integration.
Set up StripeServer-side

First, create a Stripe account or sign in.

Use our official libraries to access the Stripe API from your application:

Command Line

# Available as a gemsudo gem install stripe

Gemfile

# If you use bundler, you can add this line to your Gemfilegem 'stripe'

Enable payment methods

Enable the payment methods you want to support in your payment methods settings. You must enable at least one payment method.

By default, Stripe enables cards and other common payment methods. You can enable additional payment methods that are relevant for your business and customers. See our payment method integration options for product and payment method support and our pricing page for fees.

Set up Stripe ElementsClient-side

The Express Checkout Element is automatically available as a feature of Stripe.js. Include the Stripe.js script on your checkout page by adding it to the head of your HTML file. Always load Stripe.js directly from js.stripe.com to remain PCI compliant. Don’t include the script in a bundle or host a copy of it yourself.

checkout.html

<head> <title>Checkout</title> <script src="https://js.stripe.com/v3/"></script></head>

Create an instance of Stripe with the following JavaScript on your checkout page:

// Set your publishable key: remember to change this to your live publishable key in production// See your keys here: https://dashboard.stripe.com/apikeysconst stripe = Stripe(

'pk_test_TYooMQauvdEDq54NiTphI7jx'

);

Then, create an instance of Elements with the mode (payment, setup, or subscription), amount, and currency. These values determine which payment methods to show to your customer. See the next step for more configurable Elements options.

checkout.js

const options = { mode: 'payment', amount: 1099, currency: 'usd', // Customizable by using the Appearance API. appearance: {/*...*/},};// Set up Stripe.js and Elements to use in checkout form.const elements = stripe.elements(options);

Create and mount the Express Checkout ElementClient-side

The Express Checkout Element contains an iframe that securely sends the payment information to Stripe over an HTTPS connection. The checkout page address must also start with https://, rather than http://, for your integration to work.

The Express Checkout Element needs a place to live on your payment page. Create an empty DOM node (container) with a unique ID in your payment form.

checkout.html

<div id="express-checkout-element"> <!-- Express Checkout Element will be inserted here --></div><div id="error-message"> <!-- Display an error message to your customers here --></div>

When the form has loaded, create an instance of the Express Checkout Element and mount it to the container DOM node:

checkout.js

// Create and mount the Express Checkout Elementconst expressCheckoutElement = elements.create('expressCheckout');expressCheckoutElement.mount('#express-checkout-element');

Collect customer details and display line itemsClient-side

Handle the click event to pass options to the Express Checkout Element. After you receive the click event, disable interaction on your checkout page.

Collect payer information Accept a payment with the Express Checkout Element (12)

Set emailRequired: true to collect emails, and phoneNumberRequired: true to collect phone numbers. billingAddressRequired is true by default.

expressCheckoutElement.on('click', (event) => { const options = { emailRequired: true, phoneNumberRequired: true }; event.resolve(options);});

Collect shipping information Accept a payment with the Express Checkout Element (13)

Set shippingAddressRequired: true and pass an array of shippingRates.

checkout.js

expressCheckoutElement.on('click', (event) => { const options = { shippingAddressRequired: true, allowedShippingCountries: ['US'], shippingRates: [ { id: 'free-shipping', displayName: 'Free shipping', amount: 0, deliveryEstimate: { maximum: {unit: 'day', value: 7}, minimum: {unit: 'day', value: 5} } }, ] }; event.resolve(options);});

Listen to the shippingaddresschange event to detect when a customer selects a shipping address. You must call either resolve or reject if you choose to handle this event.

checkout.js

expressCheckoutElement.on('shippingaddresschange', async (event) => { const response = await fetch('/calculate-shipping', { data: JSON.stringify({ shippingAddress: event.address }) }); const result = await response.json(); event.resolve({ lineItems: result.updatedLineItems, });});

Listen to the shippingratechange event to detect when a customer selects a shipping rate. You must call either resolve or reject if you choose to handle this event.

checkout.js

expressCheckoutElement.on('shippingratechange', async (event) => { const response = await fetch('/calculate-and-update-amount', { data: JSON.stringify({ shippingRate: event.shippingRate }) }); const result = await response.json(); elements.update({amount: result.amount}) event.resolve({ lineItems: result.updatedLineItems, });});

Listen to the cancel event to detect when a customer dismisses the payment interface. Reset the amount to the initial amount.

checkout.js

expressCheckoutElement.on('cancel', () => { elements.update({amount: 1099})});

Display line items Accept a payment with the Express Checkout Element (14)

Pass in an array of lineItems:

checkout.js

expressCheckoutElement.on('click', (event) => { const options = { lineItems: [ { name: 'Sample item', amount: 1000 }, { name: 'Tax', amount: 100 }, { name: 'Shipping cost', amount: 1000 } ] }; event.resolve(options);});

Configure the Apple Pay interfaceAccept a payment with the Express Checkout Element (15)

Learn how to configure the Apple Pay interface.

Merchant initiated transactions (MIT) Accept a payment with the Express Checkout Element (16)

You can set up recurring payments, deferred payments, or automatic reload payments when a user checks out with Apple Pay by requesting the relevant merchant token type in the Express Checkout Element click event. We recommend implementing Apple Pay merchant tokens to align with Apple Pay’s latest guidelines and to future proof your integration.

Create a PaymentIntentServer-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. This must match what you set on the stripe.elements instance in step 3. Always decide how much to charge on the server-side, a trusted environment, as opposed to the client-side. This prevents malicious customers from choosing their own prices.

main.rb

require 'stripe'Stripe.api_key =

'sk_test_4eC39HqLyjWDarjtT1zdp7dc'

post '/create-intent' do intent = Stripe::PaymentIntent.create({ # To allow saving and retrieving payment methods, provide the Customer ID. customer: customer.id, # In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. automatic_payment_methods: {enabled: true}, amount: 1099, currency: 'usd', }) {client_secret: intent.client_secret}.to_jsonend

The returned PaymentIntent includes a client secret, which the client-side uses to securely complete the payment process instead of passing the entire PaymentIntent object. You can use different approaches to pass the client secret to the client-side.

Submit the payment to StripeClient-side

Use stripe.confirmPayment to complete the payment using details from the Express Checkout Element.

Note

For Amazon Pay, the amount you confirm in the PaymentIntent must match the amount the buyer pre-authorized to prevent the payment from being declined.

Provide a return_url to this function to indicate where Stripe should redirect the user after they complete the payment. Your user might be initially redirected to an intermediate site before being redirected to the return_url. Payments immediately redirect to the return_url when a payment is successful.

If you don’t want to redirect after payment completion, set redirect to if_required. This only redirects customers that check out with redirect-based payment methods.

checkout.js

const handleError = (error) => { const messageContainer = document.querySelector('#error-message'); messageContainer.textContent = error.message;}expressCheckoutElement.on('confirm', async (event) => { const {error: submitError} = await elements.submit(); if (submitError) { handleError(submitError); return; } // Create the PaymentIntent and obtain clientSecret const res = await fetch('/create-intent', { method: 'POST', }); const {client_secret: clientSecret} = await res.json(); const {error} = await stripe.confirmPayment({ // `elements` instance used to create the Express Checkout Element elements, // `clientSecret` from the created PaymentIntent clientSecret, confirmParams: { return_url: 'https://example.com/order/123/complete', }, }); if (error) { // This point is only reached if there's an immediate error when // confirming the payment. Show the error to your customer (for example, payment details incomplete) handleError(error); } else { // The payment UI automatically closes with a success animation. // Your customer is redirected to your `return_url`. }});

Test the integration

Before you go live, test each payment method integration. To determine a payment method’s browser compatibility, see supported browsers. If you use the Express Checkout Element within an iframe, the iframe must have the allow attribute set to payment *.

Caution

Don’t store real user data in test mode Link accounts. Treat them as if they’re publicly available, because these test accounts are associated with your publishable key.

Currently, Link only works with credit cards, debit cards, and qualified US bank account purchases. Link requires domain registration.

You can create test mode accounts for Link using any valid email address. The following table shows the fixed one-time passcode values that Stripe accepts for authenticating test mode accounts:

ValueOutcome
Any other 6 digits not listed belowSuccess
000001Error, code invalid
000002Error, code expired
000003Error, max attempts exceeded

Disclose Stripe to your customers

Stripe collects information on customer interactions with Elements to provide services to you, prevent fraud, and improve its services. This includes using cookies and IP addresses to identify which Elements a customer saw during a single checkout session. You’re responsible for disclosing and obtaining all rights and consents necessary for Stripe to use data in these ways. For more information, visit our privacy center.

See alsoAccept a payment with the Express Checkout Element (23)

  • Stripe Elements
  • Collect payment details before creating an Intent
  • Finalize payments on the server
Accept a payment with the Express Checkout Element (2024)
Top Articles
Latest Posts
Recommended Articles
Article information

Author: Corie Satterfield

Last Updated:

Views: 5631

Rating: 4.1 / 5 (42 voted)

Reviews: 89% of readers found this page helpful

Author information

Name: Corie Satterfield

Birthday: 1992-08-19

Address: 850 Benjamin Bridge, Dickinsonchester, CO 68572-0542

Phone: +26813599986666

Job: Sales Manager

Hobby: Table tennis, Soapmaking, Flower arranging, amateur radio, Rock climbing, scrapbook, Horseback riding

Introduction: My name is Corie Satterfield, I am a fancy, perfect, spotless, quaint, fantastic, funny, lucky person who loves writing and wants to share my knowledge and understanding with you.