Guide 08 · Developer docs

Commerce

A Core dna store is a set of records and an API that moves a purchase from cart to order: products described in every language and priced in every currency the store sells in, a cart, a checkout that becomes an order, invoices, payments, tax and shipping. The site builds the storefront on top: the cart and checkout pages, their scripts, and the customer emails.

L2–L3
Unit 04 · Taking payment

Express payments

Apple Pay and Google Pay on a Core dna site come from Stripe's Express Checkout Element. Where the buttons go, how the flow differs from a card payment, and the wallet set-up to finish on the Stripe side before launch.

Who this is for. Developers adding Apple Pay or Google Pay buttons to a cart or checkout page on a site that takes payment with Stripe. After this page you can mount the buttons, turn a wallet payment into an ordinary purchase call, and know what to set up before launch.

Where Apple Pay and Google Pay come from

Apple Pay and Google Pay are delivered by Stripe's Express Checkout Element, not by a payment method of their own. There is no wallet setting on the site: a site with an active Stripe method already has what the element needs, because the payment-methods list returns that method's publishableKey and accountId (Listing the methods a shopper can choose).

The payment itself is a Stripe payment like any other. The element leads to a Stripe confirmation token, and your script sends it to the same purchase call, with the Stripe method's id as _paymentMethodId. The invoice, the currency, the answers and the webhook that makes the order are the same as for a card, so everything on Payment methods and how a payment runs applies unchanged, the currency and the amount in minor units included (The currency a payment is taken in).

How it differs from a card payment

Card paymentExpress payment
Where the shopper paysStripe's card fields on the checkout pageThe wallet's own sheet, opened from the Express Checkout Element
Email and addressesTyped into your form and written to the checkout before payingTaken from the billing and shipping details the wallet sheet returns, then written to the checkout
Where the token comes fromThe card fieldsThe wallet, through the Express Checkout Element
The purchase call_paymentMethodId and confirmationTokenThe same
Answers, order and webhookThe same for both

The flow

  1. Load Stripe with the Stripe method's publishableKey and accountId, and create an elements group in payment mode with the checkout's amount and currency, with confirmation tokens created by your script (paymentMethodCreation: 'manual'). Stripe's script loads only once its hosts are in the site's policy (Content Security Policy).
  2. Create the Express Checkout Element with Apple Pay and Google Pay, and mount it in its own container.
  3. When the shopper confirms in the wallet sheet, the element fires its confirm event with the billing and shipping details. Use the current checkout, or create one from the cart if there is none yet, and write the email and addresses to it.
  4. Create shipping and select a rate, as on Addresses and shipping at checkout, so that the checkout is ready for payment.
  5. Call elements.submit(), then stripe.createConfirmationToken({ elements }).
  6. Call purchase with the method's id and the token, and act on the answer exactly as for a card.

The billing and shipping details from the wallet become the checkout's addresses, the same address records described on Addresses and the address book. Ask the wallet for the email and addresses the checkout needs through the element's own options, which Stripe's documentation for the Express Checkout Element lists.

JavaScript js/express-checkout/stripe.js
// Express payments through Stripe's Express Checkout Element.
// method: the active Stripe entry from the payment-methods list.
// amount: the checkout's total in the currency's minor unit; currency: its code.
// api: your API layer (checkout, addresses, shipping, purchase).
export function mountExpressCheckout(method, { amount, currency }, api) {
  const stripe = Stripe(method.publishableKey, { stripeAccount: method.accountId });
  const elements = stripe.elements({
    mode: 'payment',
    amount,
    currency: currency.toLowerCase(),
    paymentMethodCreation: 'manual',
  });

  const express = elements.create('expressCheckout', {
    paymentMethods: { applePay: 'always', googlePay: 'always' },
  });
  express.mount('#express-checkout');

  express.on('confirm', async (event) => {
    const checkoutId = await api.currentOrNewCheckout();
    await api.writeWalletDetails(checkoutId, event.billingDetails, event.shippingAddress);
    await api.chooseShipping(checkoutId);

    const { error: submitError } = await elements.submit();
    if (submitError) return api.showMessage(submitError.message);

    const { error, confirmationToken } = await stripe.createConfirmationToken({ elements });
    if (error) return api.showMessage(error.message);

    const body = await api.purchase(checkoutId, {
      _paymentMethodId: method.id,
      confirmationToken: confirmationToken.id,
    });
    api.handlePurchaseAnswer(body); // the same handling as a card payment
  });
}

Where the buttons go

Mount the element in its own container above the list of payment methods, or beside it, so the wallet buttons come first and the card form follows for shoppers without a wallet. Hide the express section whenever the payment section is hidden, which includes a checkout with nothing to pay: a zero total is marked paid without a provider, so there is nothing for a wallet to do.

Wallet set-up before launch

Nothing for Apple Pay or Google Pay is set on the site. Whatever the wallets require of the domains that show their buttons is set up on the Stripe side, by following Stripe's current documentation for the Express Checkout Element.

Finish the wallet set-up well before launch day

The wallet requirements are the step teams most often meet late. Check them against every host that will show the buttons, development hosts as well as the live one, and finish them early. Then test the buttons on each host, on a device with each wallet set up, before the site goes live.

Go deeper

Was this page helpful?

Your answer goes to the docs team.