Overview
- Apple Pay - Appears on Safari (macOS and iOS) when the customer has Apple Pay set up. Setup depends on your gateway (see below).
- Google Pay - Appears on supported browsers when a Google Pay wallet is available. With NMI it appears on Android devices only. With Stripe it can also appear on desktop Chrome.
- Both options appear on the checkout page only. By default they render inside
<checkout-cc-panel>, or you can place them anywhere on the page with<checkout-wallet />.
How to configure / enable
Setup differs by gateway. Choose your gateway below.Stripe
Google Pay (Stripe)
No configuration is required beyond domain registration (see Apple Pay step below). Google Pay appears automatically on checkout when the customer has a Google Pay wallet. With Stripe, Google Pay can appear on desktop Chrome in addition to Android devices.Apple Pay (Stripe)
Stripe handles Apple’s merchant validation behind the scenes. You do not need to create an Apple Merchant ID, CSR, or host a.well-known verification file. Follow these steps:
Step 1: Make sure your Stripe account is in live mode
Step 2: Register your checkout domain(s) with Stripe
- In the Stripe Dashboard, make sure you are in live mode (toggle at the top of the dashboard).
- Go to Settings → Payment method domains.
- Click Add a new domain.
- Enter the exact domain customers use at checkout (e.g.
checkout.yourstore.com). - Click Save and continue.
- Repeat for any additional domains or subdomains (including
www).
Domains registered in live mode are automatically available in sandbox/test mode as well. For local testing, use a tool like ngrok to get an HTTPS domain and register that. However, Apple Pay itself still requires live keys to appear on supported devices.
NMI
Google Pay (NMI)
No configuration is required.- Ensure the domain uses an NMI merchant.
- Ensure that merchant uses tokenization (Collect.js): in the merchant settings, tokenization mode should be Collect.js and the public / tokenization key should be set.
- Assign that NMI merchant to your checkout domain under Settings → Domains → Edit Domain → Merchant.
Apple Pay (NMI)
Prerequisites: NMI merchant with tokenization (Collect.js), and the checkout domain linked to that merchant (as above). Step 1: Enable Apple Pay in NMI- Log in to the NMI Merchant Portal.
- Go to Settings → Apple Pay.
- Enable Apple Pay for your account (if your processor supports it).
- In the NMI Merchant Portal, add your checkout domain(s) to the Apple Pay allowed list (see NMI’s Apple Pay / domain registration section).
- If ElasticFunnels later adds an in-app “Register domains” action for your NMI merchant, you can use that to sync your linked domains; otherwise configure the list in NMI’s portal.
- Download the domain verification file from NMI (in the NMI Merchant Portal under the Apple Pay settings, or from Apple’s developer resources as NMI directs you).
- Host it at:
https://<your-checkout-domain>/.well-known/apple-developer-merchantid-domain-association
Replace<your-checkout-domain>with the exact domain customers use at checkout (e.g.checkout.yourstore.com). - Ensure the file is publicly accessible over HTTPS. Recommended: In the app, go to Domains → edit the checkout domain → Apple Pay tab, and paste the exact contents of the verification file. The offer site will then serve it at
/.well-known/apple-developer-merchantid-domain-associationfor that domain. Alternatively, you can set the env varAPPLE_PAY_DOMAIN_VERIFICATION_CONTENTon the offer server as a fallback (same content for all domains on that server). If neither is set, the path returns 404 and you must host the file elsewhere.
Placement options
There are three ways to include Apple Pay / Google Pay on your checkout page:Default - wallet tab inside the card panel
or pay with card divider - is only used as a fallback when the tab layout is unavailable (non-HTTPS page, an unsupported gateway, or an #applePay container already on the page from <checkout-wallet>).
Standalone - wallet buttons anywhere on the page
Use<checkout-wallet /> to place the wallet buttons wherever you want, and disable them inside the card panel with data-applepay="false":
<div class="ef-wallet-standalone"> containing both the #applePay and #googlePay containers. Because the panel skips its own wallet tab whenever an #applePay element already exists, adding <checkout-wallet> is enough on its own - but data-applepay="false" keeps the intent explicit.
Both attributes are plain attributes, not
data- prefixed. The tag may be written self-closing (<checkout-wallet />) or with an explicit closing tag.
<checkout-apple-pay /> is the legacy single-wallet version of this tag. It still works and accepts force="true", but it only ever renders the Apple Pay container. Prefer <checkout-wallet /> for new pages.Disable wallet buttons in the card panel
data-applepay-layout is read by the client-side panel, but the server-side tag expander does not forward it: <checkout-cc-panel> is rewritten into a <div class="checkout-cc-panel"> carrying only data-gateway, data-accepted-cards, data-applepay and data-applepay-force. Writing data-applepay-layout="separated" on the tag therefore has no effect - use <checkout-wallet /> for an above-the-panel wallet instead.Conditional display
Two scope variables drive wallet-aware layouts:
Use them to show or hide parts of your checkout layout:
checkout.wallet_available starts as { applePay: false, googlePay: false } and is only updated after the payment library loads and detects wallet support (NMI Collect.js or Stripe.js). This can take 1-2 seconds after page load, so a template-if on it will briefly evaluate false on first paint. Prefer checkout.wallet_visible (or <checkout-wallet force="true">) when you need the layout stable immediately.Example: wallet-first checkout
This layout shows the wallet buttons prominently at the top, with the card form below:How wallet payment works
When a customer taps the Apple Pay or Google Pay button:- The native wallet sheet appears (Face ID / Touch ID for Apple Pay, or Google Pay authentication).
- The wallet provides the payment token and contact data (name, address, email, phone).
- The system automatically fills the checkout form fields with the wallet data.
- The form auto-submits. No further action from the customer.
shipping_country / billing_country, which are always overwritten with the wallet’s value.
Wallet contact field auto-detection
This auto-detection applies to NMI / Collect.js checkouts only. On Stripe, the payment request is created with
requestPayerName, requestPayerEmail and requestShipping always enabled and no phone request, regardless of which fields are on the page.
Only the first-name variants are checked. A page carrying
last_name without any *_first_name field does not trigger the name request.
Digital product example: A checkout page with only email and a payment panel (no name or address fields) causes Apple Pay to request only the customer’s email. This is ideal for digital goods where shipping details are unnecessary.
Subscriptions and recurring payments
When a customer purchases a subscription using Apple Pay or Google Pay, the system stores the payment method for future use:- NMI: A customer vault entry is created during the initial charge. All subsequent subscription charges (renewals, rebills) use this vault entry server-to-server. Requires Customer Token Vault — see below.
- Stripe: The PaymentMethod is saved to the Stripe customer with
setup_future_usage: 'off_session'. All subsequent charges use this stored payment method server-to-server.
Checking whether a wallet subscription will renew
If the first charge succeeds but no
customer_vault_id is recorded, the subscription will
not renew. Fix the vault configuration before sending traffic rather than after.
One-click upsells
When a customer pays with Apple Pay or Google Pay on the main checkout, the payment method is stored for reuse. Subsequent one-click upsell charges on the same funnel use this stored method server-to-server. No additional customer interaction is needed. The customer sees upsell pages and clicks “Yes, add this” as usual; the charge happens instantly. This works the same as card-based one-click upsells for both NMI and Stripe.Billing address handling
When a customer pays with Apple Pay or Google Pay, the wallet provides the correct billing address associated with the card. The wallet’s billing values always overwrite the internalcheckout.customer.billing_* scope object, so the address used for verification (AVS) comes from the wallet rather than from anything typed earlier. This prevents address verification mismatches and declined payments.
No configuration is needed. This is handled automatically.
The scope object and the form inputs behave differently.
checkout.customer.billing_* is always replaced with the wallet address, but the corresponding form fields are only overwritten when they were empty (billing_country and shipping_country excepted - those are always replaced). On a page that shows editable billing address inputs above the wallet button, a value the customer already typed is what gets submitted.For non-US addresses, Apple Pay may not return a state/region value (many countries don’t use states in their address format). The checkout validation automatically skips state validation for wallet payments, so this does not cause errors.
Troubleshooting
Apple Pay button does not show
Stripe:- Confirm you are using live API keys. Apple Pay does not appear when the Stripe merchant is in test mode. This is the most common cause of Apple Pay not showing with Stripe. Switch to live mode in the Stripe Dashboard and ensure your checkout domain is using the live publishable key.
- Confirm the domain is registered in the Stripe Dashboard under Payment method domains and shows as Enabled. Make sure you registered the domain in live mode.
- Check that the customer is on Safari (macOS or iOS) and the page is served over HTTPS.
- No
.well-knownverification file is needed for Stripe. Stripe handles merchant validation. If you previously used NMI and have a verification file on the domain, it does not interfere. - If using
<checkout-wallet />or<checkout-apple-pay />, make sure the tag is on the page.
- Confirm the domain uses an NMI merchant with Collect.js (tokenization) and a public/tokenization key.
- Check that the customer is on Safari (macOS or iOS) and the page is served over HTTPS.
- Confirm the domain is registered with NMI for Apple Pay and that the Apple verification file is reachable at
https://<your-checkout-domain>/.well-known/apple-developer-merchantid-domain-association. - If using
<checkout-wallet />(or legacy<checkout-apple-pay />), make sure the tag is on the page (it renders a container; the button appears inside it when supported). - If you set
data-applepay-layouton<checkout-cc-panel>and nothing changed, that is expected - the attribute is dropped during server-side expansion. Use<checkout-wallet />instead.
Google Pay button does not show
- NMI: Google Pay only appears on Android devices. It does not show on desktop Chrome or other desktop browsers. Confirm the domain uses an NMI merchant with Collect.js (tokenization) and a public/tokenization key.
- Stripe: Google Pay can appear on desktop Chrome as well as Android. Confirm the domain is registered under Payment method domains.
Verification file not found (NMI / Apple Pay)
- Ensure the file is at the exact
.well-knownpath and that the domain matches the one used at checkout. - If you use a subdomain for checkout, that subdomain must be the one registered with NMI and Apple and must serve the verification file.
- This does not apply to Stripe - Stripe handles verification without a hosted file.
Other issues
- Wallet payment cancelled or failed - The customer can pay with card instead; the card form remains available. No page reload is required.
- State/region error on wallet payment - This should be handled automatically. If you see state validation errors after a wallet payment, ensure you are on the latest version of the checkout plugin.
- Subscription charges fail after initial wallet purchase - Verify the payment created a stored payment method. For NMI, check the transaction record for a
customer_vault_id. For Stripe, check for a storedpayment_methodon the customer. - One-click upsell charges fail after wallet payment - Same as above - ensure the payment method was stored during the initial charge.