Accept Google Pay™ with OneGate
Add Google Pay to your checkout through OneGate, a supported Google Pay API payment processor. Three integration paths, one payment key, PCI scope kept to a minimum.
01Overview
OneGate offers Google Pay™ as a payment method through three integration approaches, letting you choose the best fit for your architecture and PCI compliance posture. The OneGate platform securely decrypts the Google Pay token and processes the payment; you manage only the checkout experience.
Every Google Pay integration on OneGate:
- Uses a server-generated payment key as the session identifier.
- Requires HTTPS on your domain.
- Supports the
PAN_ONLYandCRYPTOGRAM_3DSauthorization methods. - Supports Visa, Mastercard, American Express and Discover.
- Is PCI DSS Level 1 compliant via the OneGate platform.
Acceptable use and terms. When you use OneGate to accept Google Pay, you act as a merchant of the Google Pay API. You must adhere to the Google Pay and Wallet APIs Acceptable Use Policy and accept the Google Pay API Terms of Service. Enabling Google Pay on your OneGate organisation confirms acceptance of both.
02Integration methods
Pick the path that matches how much of the checkout you want to own.
Hosted redirect
Redirect the customer to a OneGate-hosted page that renders the Google Pay button.
Wallet Pay SDK
Render a native Google Pay button directly on your site with our JavaScript SDK. No redirect, no iframe.
Checkout widget
An iframe-based modal that shows the Google Pay button on your page without leaving the site.
03Requirements
- A OneGate merchant account with Google Pay enabled.
- A unique payment key, generated server-side, for each transaction.
- HTTPS and a valid SSL certificate on your domain.
- For SDK and widget integrations: a browser or device that supports Google Pay. Google Pay works in Chrome, Edge, Safari, Firefox, Opera and other modern browsers, and on Android with the Google Wallet app.
- For the Wallet Pay SDK and the Checkout Widget: register your production and staging domains with OneGate so they are added to the Google Pay Business Console. Google validates the top-level (parent) domain where the button renders, so register the parent domain your checkout runs on. Only the hosted redirect flow is exempt, since it runs on OneGate's own registered domain.
04Authentication
API calls are authenticated with three HTTP headers on every request. There is no token in the request body. Base URL: https://payments.onegate.co.za/api/v2/.
| Header | Value |
|---|---|
Auth-Token | SHA-256 (hex) of {api_salt}_{org_id}_{timestamp} |
Org-Id | Your OneGate organisation id |
Timestamp | The current Unix timestamp, in seconds. The Auth-Token is valid for 15 minutes from this value, so compute it per request and keep your server clock in sync (NTP). |
Your api_salt is a secret issued by OneGate and kept server-side. Compute the Auth-Token per request:
const crypto = require('crypto');
const timestamp = Math.floor(Date.now() / 1000);
const authToken = crypto.createHash('sha256')
.update(`${apiSalt}_${orgId}_${timestamp}`)
.digest('hex');
// send as headers: Auth-Token, Org-Id, Timestamp
Never expose your api_salt in client-side code. Always generate the Auth-Token on your server, for each request.
05Create a payment key
The payment key is the setup identifier for every transaction. Generate it server-side; all three integration methods use it. It expires 10 minutes after creation.
curl -X POST https://payments.onegate.co.za/api/v2/payment-key \
-H "Auth-Token: {sha256_hex of api_salt_org_id_timestamp}" \
-H "Org-Id: {your-org-id}" \
-H "Timestamp: {unix-timestamp}" \
-d "amount=150.00" \
-d "merchant_reference=ORDER-12345" \
-d "success_url=https://merchant.com/success" \
-d "error_url=https://merchant.com/error" \
-d "notify_url=https://merchant.com/webhook" \
-d "payment_type=credit_card" \
-d "wallet_payment=google_pay"
Use payment_type=all to show Google Pay alongside your other payment methods. The response returns the key and a hosted url:
{
"key": "0cd95fd9adabdc00275fdf6eef675950",
"url": "https://payments.onegate.co.za/pay/hosted?payment_key=...&payment_type=google_pay",
"origin": "https://payments.onegate.co.za"
}
Shared parameters
| Parameter | Req | Description |
|---|---|---|
amount | Yes | Transaction amount, e.g. 150.00. |
merchant_reference | Yes | Your transaction reference. |
payment_type | Yes | One of credit_card, all. Use all to show Google Pay with other methods. |
wallet_payment | No | google_pay or apple_pay to show only that wallet. |
success_url / error_url / cancel_url | No | Redirect targets after the payment sheet closes. |
notify_url | No | Webhook URL for the authoritative payment result. |
currency_code | No | ISO code, defaults to your organisation default (ZAR). |
06Hosted redirect
The simplest method. After creating a payment key, redirect the customer to the url in the response. OneGate hosts the page, renders the Google Pay button using the standard Google Pay API, and handles the full flow.
https://payments.onegate.co.za/pay/hosted?payment_key={key}&payment_type=google_pay
The hosted page detects device support on load: if Google Pay is available the button renders, otherwise an in-page message points the customer to alternative methods. You can redirect safely without doing your own OS or browser checks.
Merchant setup steps
- Contact OneGate support to enable Google Pay on your organisation and register your production domain.
- In your OneGate dashboard, confirm Google Pay is enabled under Organisation Settings, Wallet Payments.
- If you load the hosted URL inside an iframe, allow
frame-src https://payments.onegate.co.zaandconnect-src https://payments.onegate.co.zain yourContent-Security-Policy. The default top-level redirect needs no CSP change. - Configure your
success_url,error_url,cancel_urlandnotify_urlbefore going live.
07Wallet Pay SDK
The SDK renders a native Google Pay button directly on your site. It loads the official Google Pay API script, handles isReadyToPay() detection, presents the payment sheet, extracts the token and submits it to OneGate, with no redirect or iframe.
Direct integration terms. Because the SDK renders Google Pay on your own website, you integrate as a direct merchant of the Google Pay API. You must follow the Acceptable Use Policy, accept the Terms of Service, and display the button per the Google Pay Web Brand Guidelines.
<script src="https://payments.onegate.co.za/ext/wallet-pay/v1/google-pay.js"></script>
<div id="google-pay-button"></div>
var gpay = new CallpayGooglePay({
serviceUrl: 'https://payments.onegate.co.za',
paymentKey: '{{your-payment-key}}',
containerId: 'google-pay-button',
onSuccess: function(result){ window.location.href = '/success'; },
onError: function(error){ alert(error.message); }
});
gpay.init().catch(function(){
// Google Pay unavailable on this device: hide the button
document.getElementById('google-pay-button').style.display = 'none';
});
Button appearance
You can customise the button. The SDK passes every appearance option straight to the Google Pay API's own createButton(), so what you set is limited to the options Google publishes in ButtonOptions, and the rendered asset stays an approved one.
| Option | Default | Values |
|---|---|---|
buttonType | pay | book, buy, checkout, donate, order, pay, plain, subscribe. Pick the one that matches your call to action. |
buttonColor | black | black, white, default. Use white on a dark background so the button keeps its contrast. |
buttonOptions | {} | Any other published ButtonOptions field, currently buttonSizeMode, buttonLocale and buttonRadius. |
var gpay = new CallpayGooglePay({
serviceUrl: 'https://payments.onegate.co.za',
paymentKey: '{{your-payment-key}}',
containerId: 'google-pay-button',
buttonType: 'checkout',
buttonColor: 'white',
buttonOptions: { buttonSizeMode: 'fill', buttonRadius: 4 },
onSuccess: function(result){ window.location.href = '/success'; }
});
Stay within the button API. Customise through these options only. Restyling the rendered button with your own CSS, rebuilding it from your own markup or an image, resizing it past the published limits, or covering any part of it, all breach the Google Pay Web Brand Guidelines and can fail your production review. The SDK does not let you override onClick or allowedPaymentMethods, so the sheet always opens from the button's own gesture.
Domain registration
Google Pay requires the domain that renders the button to be registered against a Google Pay Business Console merchant ID. This applies to both the Wallet Pay SDK and the Checkout Widget: even though the widget renders in an iframe, Google validates the top-level (parent) domain of the page, which is your site. Send OneGate support the parent domains where your checkout runs (for example checkout.yoursite.com) and we register each one. Approval is usually immediate. Only the hosted redirect flow is exempt.
08Checkout widget
The widget shows Google Pay in an iframe-based modal on your page without leaving the site, keeping you fully descoped from PCI.
Direct integration terms. The widget embeds Google Pay on your own site, so the same obligations apply: the Acceptable Use Policy, the Terms of Service, and the Google Pay Web Brand Guidelines.
<script src="https://payments.onegate.co.za/ext/checkout/v4/checkout.js"></script>
<button id="pay-button">Pay with Google Pay</button>
document.getElementById('pay-button').addEventListener('click', async () => {
const checkout = new EftSecureCheckout({
serviceUrl: 'https://payments.onegate.co.za/rpp-transaction/create-from-key',
paymentKey: '{{your-payment-key}}',
paymentType: 'credit_card',
walletPayment: 'google_pay',
onComplete: (data) => { window.location.href = data.success ? '/success' : '/error'; }
});
await checkout.init();
});
Pass paymentType and walletPayment explicitly. To show Google Pay alongside other methods use paymentType: 'all' and omit walletPayment.
09Webhooks
Implement webhooks (notify_url) for reliable payment confirmation rather than relying on client-side callbacks alone. The webhook is delivered asynchronously once the gateway confirms the status, and retried on failure with exponential backoff.
- Customer completes payment via Google Pay (any method).
- Show a "thank you" page from the client-side callback or redirect.
- Trust the webhook: use its payload to update order status and fulfil.
- As a fallback, query the View Transaction API to confirm status and amount before fulfilment.
Transaction statuses
| Status | Meaning |
|---|---|
complete | Completed and settled successfully. |
failed | The transaction failed. |
refunded | Fully refunded. |
partially-refunded | Partially refunded. |
103D Secure and authorization methods
Google Pay returns credentials under one of two authMethod values. Both are supported, and 3DS handling differs by method. OneGate can restrict the methods enabled for your organisation.
| authMethod | Contents | 3DS behaviour |
|---|---|---|
CRYPTOGRAM_3DS | A device-bound network token (DPAN) plus a Google cryptogram and ECI. Returned only on Android with the card saved in the Google Wallet app. | Already authenticated. The cryptogram carries liability shift end to end, so no separate 3DS challenge is invoked. |
PAN_ONLY | The funding-instrument PAN (FPAN), with no cryptogram. Returned in all other contexts (Chrome, Safari, Firefox on desktop or iOS, and non-tokenised Android). | No wallet-side authentication. For merchants provisioned for OneGate decryption, stepped up through standard card 3D Secure before authorisation. |
Choosing which methods you accept
Two separate things are easily confused here. You do not choose what Google returns for a given shopper: that follows from the device and the card. A shopper on desktop Chrome paying with a card saved to their Google account yields PAN_ONLY; the same card provisioned in the Google Wallet app on Android yields CRYPTOGRAM_3DS. You do choose which of the two you accept.
Acceptance is the allowedAuthMethods field of the Google Pay CardParameters object. OneGate sets it for you from a per-organisation setting, so you never send it by hand, but the value is yours to decide:
| Accepted methods | What it means for you |
|---|---|
| Both recommended | Widest reach. PAN_ONLY is stepped up through 3D Secure before authorisation, CRYPTOGRAM_3DS arrives already authenticated. |
CRYPTOGRAM_3DS only | Device-bound tokens only. Every payment you accept arrives pre-authenticated and carries liability shift, with no step-up. The trade is reach: this credential exists only on Android with the card saved in the Google Wallet app, so shoppers on desktop, on iOS, or with a non-tokenised Android card cannot pay this way. |
PAN_ONLY only | Rarely useful. It refuses the stronger credential while keeping the one that needs a 3DS step-up. |
| Neither | Google Pay is not offered at all. |
Restricting to CRYPTOGRAM_3DS is a legitimate choice for a merchant who wants every wallet payment to carry liability shift, and it is how a higher-risk merchant can guarantee that. Treat it as a reach decision rather than a purely technical one: the narrower the setting, the fewer shoppers can complete a Google Pay payment. Contact OneGate support to change it for your organisation.
Assurance details
OneGate sets assuranceDetailsRequired: true on every request, so Google returns an assuranceDetails object alongside the credential, describing the validation it performed through the accountVerified and cardHolderAuthenticated flags.
This reports on the credential you were given; it does not control which credential you receive, and it cannot be used to require an authenticated one. allowedAuthMethods is the setting for that. OneGate records both flags against the transaction for verification, and does not treat cardHolderAuthenticated: true as a reason to skip the 3D Secure step-up on a PAN_ONLY credential.
Enabling 3DS for PAN_ONLY credentials
A PAN_ONLY payload decrypts to a normal card PAN with no Google Pay cryptogram, so it carries no wallet-side authentication. For merchants provisioned for OneGate decryption, PAN_ONLY credentials are automatically stepped up through 3D Secure before authorisation, using the same 3DS 2.x authentication (frictionless or challenge, as the issuer determines) that OneGate applies to a standard card payment.
This is handled by OneGate. You do not add any parameter, SDK option or code to enable it:
- OneGate decrypts the
PAN_ONLYpayload and detects that no cryptogram is present. - The transaction is stepped up through OneGate's standard card 3D Secure flow.
- 3DS on Google Pay
PAN_ONLYis enabled by OneGate provisioning it on your organisation. If you require it, contact OneGate support to confirm your organisation is provisioned for OneGate decryption.
11API configuration
OneGate's SDK and hosted pages build the Google Pay PaymentDataRequest for you using the PAYMENT_GATEWAY tokenization type. In all three integration paths, OneGate sets both gateway and gatewayMerchantId; you never set them by hand.
| Parameter | Value |
|---|---|
gateway | onegate, the gateway integrator ID OneGate registered with Google. OneGate sets this for you per organisation, so you never have to track it: an organisation settled through a processing partner is set to that partner's registered ID instead, with no change on your side. |
gatewayMerchantId | Your OneGate organisation id, zero-padded to 8 digits (for example 00021414). In Google's TEST environment the value is the literal googletest. |
The standard configuration OneGate generates, shown for reference:
const baseCardPaymentMethod = {
type: 'CARD',
parameters: {
allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
allowedCardNetworks: ['VISA', 'MASTERCARD', 'AMEX', 'DISCOVER']
},
tokenizationSpecification: {
type: 'PAYMENT_GATEWAY',
parameters: {
gateway: 'onegate',
gatewayMerchantId: '00021414' // your org id, 8 digits ('googletest' in TEST)
}
}
};
const paymentDataRequest = {
apiVersion: 2, apiVersionMinor: 0,
allowedPaymentMethods: [baseCardPaymentMethod],
merchantInfo: {
merchantId: 'BCR2DN6D3L72TUDX', // OneGate Google Pay & Wallet Console merchant ID
merchantName: 'OneGate'
},
transactionInfo: {
totalPriceStatus: 'FINAL', totalPrice: '150.00',
currencyCode: 'ZAR', countryCode: 'ZA'
}
};
Card networks
Define the networks you accept in allowedCardNetworks. OneGate supports VISA, MASTERCARD, AMEX and DISCOVER; the SDK sends all four by default. If your acquiring agreement covers a subset, OneGate can restrict the list for your organisation. All OneGate Google Pay transactions settle in South Africa.
Billing address
By default OneGate's Google Pay integration does not require a billing address: billingAddressRequired is not set, so the sheet does not collect address data. If your risk profile needs address verification, OneGate can enable BillingAddressParameters (format: 'FULL' or 'MIN') on your organisation; contact support.
Submitting encrypted data
You never handle the encrypted token directly. The SDK submits the token and payment session to POST /api/v2/google-pay; OneGate decrypts and processes it. For hosted and widget flows this happens entirely on OneGate's servers.
12Testing
- A test environment is available on request. Contact OneGate support for test credentials; test transactions use the same
/api/v2/payment-keyendpoint. - For the SDK, use Google Pay test cards in Chrome and set
debug: truefor verbose logging. - In the TEST environment,
gatewayMerchantIdis the literalgoogletest. - Verify
isReadyToPay()behaviour on supported and unsupported devices.
13Going live
Before Google Pay works in production on your own site (SDK or widget), the integration must be approved for production in the Google Pay & Wallet Console. This is Google's "Publish your integration" step.
- Hosted redirect: no production access needed on your side. The hosted page runs on OneGate's already-published domain.
- SDK & widget: send OneGate your production and staging domains. OneGate registers each and submits the integration through "Publish your integration" under its registered merchant profile (
BCR2DN6D3L72TUDX). Once approved, Google Pay renders in production on your domains.
14Brand and UX compliance
OneGate's Google Pay™ integrations follow Google's published brand and user experience guidelines. On the hosted redirect the button and payment flow are rendered by OneGate, so these hold automatically. On the SDK and the widget the button is rendered by our code on your page, and the surrounding layout is yours.
How the button is rendered
- Buttons are produced by the Google Pay API's own
createButton()on all three paths. Where you customise the button, the SDK passes your choices through Google's published ButtonOptions, so the asset rendered is always one of Google's own. No hand-built button is used anywhere. isReadyToPay()runs before the button is rendered, so it only appears on a device and browser that can complete the payment.- The payment sheet opens from the button's own click handler, so it is always a response to a user gesture.
- Loading, success and error states are surfaced through the SDK callbacks (
onReady,onSuccess,onError,onCancel) so the customer is told what happened.
What stays with you
- Place the Google Pay™ button prominently among your payment options. You can change its type, colour, size mode, locale and corner radius through the SDK's button appearance options, which go through Google's own ButtonOptions. Do not restyle the rendered button with CSS, rebuild it yourself, or cover any part of it.
- Serve your checkout over HTTPS. It is required by Google Pay and by OneGate.
- Register the domains the button renders on, so Google approves them (see Going live).
Where decryption happens. The encrypted payment token is decrypted by OneGate, or by the processing partner that settles the organisation, and never by you. Google encrypts it to whichever of those holds the key, and OneGate sets the matching gateway value on the request automatically. On all three integration paths you never handle or decrypt the token, and no card data reaches your servers.
15Resources & support
Merchants using the SDK or widget integrate Google Pay directly on their own site and must follow Google's official web resources, including approved button assets from the brand guidelines.
OneGate support
For integration help, contact support@onegate.co.za or call 087 550 6850. For Google Pay onboarding queries, reach out to Louis Germishuys at louis@onegate.co.za.