Skip to main content

How to integrate Apple Pay / Google Pay in Browser Web

Overview

The checkout service provides a Hosted Payment Page with full Apple Pay and Google Pay support already built in. This guide covers integration for browser-based web applications (desktop and mobile web).

Key Integration Approach

Web applications integrate by redirecting or opening the checkout URL in a standard web browser. The checkout page then invokes native Apple Pay / Google Pay sheets directly via the browser's standard W3C Payment Request API.

Important: The web application does NOT need to integrate any payment SDK, configure Merchant IDs, or request payment entitlements. The browser handles everything natively.

Browser Support Requirements

Browser

Apple Pay

Google Pay

Safari (macOS)

✅ Supported

✅ Supported

Safari (iOS)

✅ Supported

❌ Not supported

Chrome / Chromium (desktop)

❌ Not supported

✅ Supported

Chrome / Chromium (Android)

❌ Not supported

✅ Supported

Firefox / Edge / Others

❌ Not supported

⚠️ Partial (varies)

Key points:

  • Apple Pay requires Safari on macOS or iOS

  • Google Pay requires Chrome or Chromium-based browsers or Safari on macOS

  • The checkout page automatically detects which payment methods are available based on the user's browser and device

  • Users must have at least one eligible debit card added to their device wallet (Apple Wallet or Google Pay)


Integration Flow

High-Level Flow

  1. Initiate Top-Up: Your web application calls your backend to start a top-up transaction

  2. Receive Checkout URL: Your backend returns a checkout_url (and optionally redirect_url and cancel_url)

  3. Open Checkout Page: Redirect the user to the checkout_url (or open in a new window/tab)

  4. Complete Payment: User completes payment through Apple Pay / Google Pay

  5. Handle Completion: User is redirected back to your application via redirect_url or cancel_url

What Your Application Receives from Backend

Field

Required?

Purpose

checkout_url

Required

Redirect the user to this URL to complete payment

redirect_url

Recommended

User is redirected here after checkout completes

cancel_url

Optional

User is redirected here if they cancel the checkout

Important: Your web application only interacts with your own backend — it never calls the payment service provider directly.


Implementation Requirements

Opening the Checkout Page

You have several options for opening the checkout page:

Option 1: Full Page Redirect (Simplest)

window.location.href = checkout_url;

  • Simplest implementation

  • User leaves your site, completes payment, then returns via redirect_url

  • Recommended for most use cases

Option 2: New Tab / Window

window.open(checkout_url, '_blank');

  • User opens checkout in a new tab

  • Your site remains open in the original tab

  • User must manually close the checkout tab after payment

  • Less seamless UX, but keeps your site visible

Option 3: Popup Window

window.open(checkout_url, 'checkout', 'width=600,height=700');

  • Opens checkout in a sized popup

  • Requires handling popup blockers

  • User can complete payment without leaving your site

  • Must handle popup close detection to check order status

Handling Callback URLs

After the user completes or cancels the checkout, the browser redirects to your redirect_url or cancel_url.

Callback URL Structure:

URL

Meaning

What to Do

redirect_url (with query params)

Checkout finished

Query order status → refresh balance

cancel_url

User cancelled

Show cancellation message → allow retry

Important: The redirect_url callback carries extra query parameters (e.g., ?transactionId=...). Use same host + path prefix match to detect the callback, not full-string equality.

Order Status Polling

Important: Callback URLs are navigation signals only, not the source of truth. redirect_url is triggered when checkout finishes, whether the payment succeeded, failed, or is still pending.

After receiving redirect_url, query the order status:

  • COMPLETED → Payment succeeded; refresh wallet balance

  • FAILED → Show failure message and allow retry

  • NEW / DEBITED → Still processing; keep polling with backoff


Browser-Specific Notes

Safari (Apple Pay)

Do

Do Not

Test on macOS or iOS with Safari

Expect Apple Pay to work in Chrome/Firefox

Ensure user has eligible debit card in Apple Wallet

Try to detect Apple Pay availability via JavaScript (not reliable)

Use HTTPS (required for Payment Request API)

Use insecure HTTP connections

Allow all intermediate redirects (3DS, risk checks)

Block or intercept cross-domain redirects

Chrome / Chromium (Google Pay)

Do

Do Not

Test on Chrome with Google Pay configured

Expect Google Pay to work in Safari/Firefox

Ensure user has eligible card in Google Pay

Disable third-party cookies (breaks payment flow)

Use HTTPS (required for Payment Request API)

Block cross-domain redirects

Allow popup windows if using popup approach

Block popups without user consent


Why No Payment SDK Is Needed

The checkout page leverages the standard W3C Payment Request API:

✅ What the web application needs:

  • A standard web browser that supports Payment Request API

  • HTTPS connection (required for payment APIs)

❌ What the web application does NOT need:

  • Native payment SDK

  • Its own Merchant ID

  • Payment certificates, CSR, or token decryption

  • Special browser configuration

Merchant validation and payment token processing are handled server-side by the payment service provider.


Troubleshooting

Symptom

Likely Cause

Solution

Apple Pay option not shown

Not using Safari / no eligible debit card in wallet / not HTTPS

Use Safari browser; add eligible debit card to Apple Wallet; ensure HTTPS

Google Pay option not shown

Not using Chrome / Google Pay not configured / cookies disabled

Use Chrome browser; add eligible card to Google Pay; enable third-party cookies

Payment sheet appears but fails

Merchant validation failed / network error

Check network connection; contact support if issue persists

User not redirected back after payment

redirect_url not configured / incorrect URL format

Ensure backend provides redirect_url; verify URL format matches your domain

Popup blocked

Browser popup blocker enabled

Use full-page redirect instead of popup; or request user to allow popups

Error after payment sheet appears

Merchant validation failed

Server-side configuration issue; contact support

Token expired

JWT is short-lived; user lingered too long

Re-run the flow to obtain a fresh checkout URL

Payment option grayed out

User has no eligible cards in wallet

Add eligible debit card to Apple Wallet or Google Pay first


Integration Checklist

All Browsers

  • Backend provides checkout_url (and optionally redirect_url, cancel_url)

  • Your application uses HTTPS (required for Payment Request API)

  • Test payment flow on real devices (not just emulators)

  • Test with eligible debit cards in device wallet

  • Handle redirect_url callback to detect payment completion

  • Query order status after receiving callback (not before)

  • Refresh wallet balance only when order status is COMPLETED

  • Allow all intermediate redirects (3DS, risk checks) — do not block cross-domain navigation

Safari (Apple Pay)

  • Test on macOS or iOS with Safari

  • Test device has Apple Wallet configured with eligible debit card

  • Verify HTTPS connection

Chrome / Chromium (Google Pay)

  • Test on Chrome with Google Pay configured

  • Test device has Google Pay configured with eligible card

  • Verify HTTPS connection

  • Ensure third-party cookies are enabled


Support Information

When reporting an integration issue, provide:

  • Browser and version: Safari / Chrome / etc.

  • OS and version: macOS / iOS / Windows / Android

  • Device model: (if mobile)

  • Environment: staging or production

  • Screenshot, screen recording, or browser console logs

  • If popup/new tab: whether popup was blocked

  • Checkout URL provided by backend: (redact sensitive params)

Contact the integration support team for hosted checkout or merchant-validation related issues.

Did this answer your question?