Payments
Published
A PWA takes payment with the same three layers as any web page: the browser’s Payment Request API, a wallet that plugs into it (Apple Pay in Safari, Google Pay in Chromium and others), and a payment provider’s JavaScript SDK that falls back to a hosted form. Which layer works depends on the engine and its version, not on whether the page is installed.
How it works
Section titled “How it works”The browser owns the checkout sheet. Your code describes the methods it accepts and the total, and the engine decides which wallets it can show; a provider SDK sits on top and chooses between that sheet and its own form.
Payment Request API
Section titled “Payment Request API”new PaymentRequest(methods, details) followed by show() opens the browser’s sheet. The
compat data (BCD api.PaymentRequest) places it in Chrome 60 on desktop and Chrome 53 on
Android, Edge 15, Safari 11.1 on macOS and iOS, Samsung Internet following Chrome for Android,
and Android WebView 136. Firefox 55 contains an implementation that is disabled by default
behind dom.payments.request.enabled and a dom.payments.request.supportedRegions country
list, so a Firefox user sees no sheet. The API is limited to secure contexts, and a cross-origin
<iframe> gets it only with the allowpaymentrequest attribute.
- Legend
- Yes
- Partial
- Flag
- No
- Unknown
| Browser / Platform | Support | Versions | Confidence | Source | Notes |
|---|---|---|---|---|---|
| Chrome (Android) | Yes | 61 | medium | source | — |
| Chrome (Desktop) | Yes | 61 | medium | source | — |
| Edge (Desktop) | Yes | 79 | medium | source | — |
| Safari (iOS) | Yes | 11.1 | medium | source | 1 |
| Safari (macOS) | Yes | 11.1 | medium | source | 2 |
| Firefox (Desktop) | No | — | medium | source | 3 |
| Samsung Internet | Yes | 7.0 | medium | source | — |
- Backed by Apple Pay as the payment method.
- Backed by Apple Pay.
- Implementation shipped then disabled; not available by default.
Ecosystem & commercial policy
| Entity | Type | Context | Status | Sponsored | Notes |
|---|---|---|---|---|---|
| Apple Pay | payment_sdk | Safari / iOS | Yes | No | Works in Safari via Payment Request; merchant-domain verification required. |
| Stripe | payment_sdk | Cross-browser | Yes | No | Stripe wraps Payment Request as the Payment Request Button / Payment Element. |
| Google Play billing | store_policy | Google Play TWA | No | No | TWAs distributing digital goods must use Play Billing, not Payment Request, per Play policy. |
Detection has two steps, because a browser can expose the constructor and still support none of your methods:
async function startCheckout(methods, details) { if (!('PaymentRequest' in window)) return openProviderForm(); const request = new PaymentRequest(methods, details); if (!(await request.canMakePayment())) return openProviderForm(); try { const response = await request.show(); await response.complete('success'); } catch (err) { if (err.name === 'AbortError') return; // the user closed the sheet return openProviderForm(); }}Apple Pay
Section titled “Apple Pay”In Safari the only method behind Payment Request is Apple Pay; the sheet is the same one
Apple Pay JS opens. Apple’s planning page states that merchants anywhere can accept Apple Pay
“as long as their payment service provider supports Apple Pay”, that “in China mainland, Apple
Pay on the web is supported in Safari on iOS only”, and that platforms register merchant
websites through the Apple Pay Web Merchant Registration API. Web content shown in an
SFSafariViewController can use Apple Pay as in Safari; a WKWebView cannot, and Apple
directs those apps to move the request into native code.
Google Pay
Section titled “Google Pay”Google’s setup guide lists the browsers in which the Google Pay API for web runs: “Google Chrome, Mozilla Firefox, Apple Safari, Microsoft Edge, Opera, or UCWeb UC Browser”, and requires “an HTTPS webpage with a TLS domain-validated certificate”. The API returns a payment token for the chosen method, which your backend forwards to the processor. Google lists Firefox and Safari although Payment Request does not surface Google Pay in either engine.
Provider SDKs
Section titled “Provider SDKs”A provider SDK is ordinary JavaScript and loads in a PWA as in a tab. Stripe’s Payment Request
Button, which wrapped PaymentRequest to show Apple Pay, Google Pay, or Link, is marked
deprecated in Stripe’s documentation in favour of the Express Checkout Element. The question an
installed PWA adds is navigation: a redirect-based 3-D Secure or bank flow that leaves the
manifest scope runs under the browser’s out-of-scope UI (Microsoft documents a URL and
title bar for Store-installed Edge PWAs), so prefer
providers whose authentication runs in a popup or inline frame when you ship a standalone app.
| Layer | Where it works | Precondition |
|---|---|---|
| Payment Request API | Chrome 60 / 53 Android, Edge 15, Safari 11.1, Samsung Internet, WebView 136 | Secure context; transient user activation for show() |
| Apple Pay | Safari (macOS, iOS); SFSafariViewController |
Merchant registration; PSP that supports Apple Pay |
| Google Pay | Chrome, Firefox, Safari, Edge, Opera, UC Browser | HTTPS with TLS domain-validated certificate |
| Provider SDK | Any engine the SDK supports | Provider account; fallback form for unsupported wallets |
Observed behaviour
Section titled “Observed behaviour”See also
Section titled “See also”- Payment Request API (w3.org)
- PaymentRequest: show() method (developer.mozilla.org)
- Set up Google Pay API for web (developers.google.com)
- Payment Request API compatibility
- Payment Request API reference
- Monetization
- Digital Goods API
← Back to the Ecosystem overview.