Google Pay Integration
Google Pay enables fast, simple checkout with payment information stored in customers' Google accounts. By integrating Google Pay through Onerway, you can offer a seamless payment experience to hundreds of millions of Google users worldwide.
Quick Start (TL;DR)
Follow these 4 steps to complete the fastest path (complete one payment first, then gradually improve error handling and security):
- Get Google Pay configuration: call
POST /v1/txn/consultPaymentMethod, find the record wherepaymentMethod = "GooglePay", extractgatewayName,gatewayMerchantId,subCardTypes(needed for frontend initialization). - Frontend payment: load Google Pay JS SDK, build
tokenizationSpecificationusing the config above, callloadPaymentData(), and extractpaymentTokenfrompaymentData.paymentMethodData.tokenizationData.token. - Backend order: call
POST /v1/txn/doTransactionto complete the charge.- Onerway decrypt mode: send
tokenInfo.provider = "GooglePay",tokenInfo.tokenId = <paymentToken>. - Merchant decrypt mode: don't send
tokenInfo, instead send decrypted fields incardInfo(see example below).
- Onerway decrypt mode: send
- Handle result and callbacks:
data.status = "S": success.data.status = "R": redirect required (common forPAN_ONLY/ CVV supplemental info).- Final status confirmed via webhook notification.
Integration Overview
Google Pay integration with Onerway involves three main phases:
- Configuration Retrieval → Query Onerway API for Google Pay settings
- Google Pay Initialization → Set up SDK and display payment button
- Payment Processing → Handle payment tokens and process through Onerway
Prerequisites
Before implementing Google Pay integration, ensure you have:
- HTTPS Website: Google Pay requires secure HTTPS connection
- Supported Browser: Chrome, Firefox, Safari, Edge, Opera, or UC Browser
- Onerway Merchant Account: Active account with Google Pay enabled
- Google Account: For testing, add a payment method to your Google account
- Backend Integration: Server capability to call Onerway APIs
Integration Flow
Frontend Page Preparation
Before diving into the detailed integration steps, complete the basic page setup (structure consistent with Apple Pay documentation, replacing with Google Pay logic).
1. Add Google Pay Button
Dynamically create button via Google Pay SDK, reserve container:
<div id="container"></div> <!-- Google Pay button container -->
<div id="status"></div> <!-- Status message area -->2
2. Check Device Support and Display Button
const paymentsClient = new google.payments.api.PaymentsClient({ environment: 'TEST' })
paymentsClient.isReadyToPay(getGoogleIsReadyToPayRequest())
.then((response) => {
if (response.result) {
const button = paymentsClient.createButton({ onClick: onGooglePaymentButtonClicked })
document.getElementById('container').appendChild(button)
} else {
document.getElementById('status').textContent = 'Google Pay not available on this device or account'
}
})2
3
4
5
6
7
8
9
10
11
3. Create Payment Request
Construct PaymentDataRequest and initiate loadPaymentData() when button is clicked:
function onGooglePaymentButtonClicked() {
const request = getGooglePaymentDataRequest() // Contains gateway/gatewayMerchantId/allowedCardNetworks
paymentsClient.loadPaymentData(request)
.then((paymentData) => processPayment(paymentData)) // Extract token and submit to backend
.catch(() => { document.getElementById('status').textContent = 'User cancelled or payment failed' })
}2
3
4
5
6
Complete runnable example: Frontend Complete Example (HTML).
Official Examples & Button Customization
- Interactive Demo: Google provides an official demo page to test different scenarios.
- Button Styling: For complete button properties and customization, see Google Pay button documentation.
1. Get Onerway Configuration
Before initializing Google Pay, call the Payment Methods Query API to get gateway, gatewayMerchantId, and allowedCardNetworks.
Query API Request
{
"appId": "1727880846378401792", // Application ID
"country": "US", // Customer country
"merchantNo": "800209", // Merchant number
"orderAmount": "29.99",
"orderCurrency": "USD",
"paymentMode": "WEB", // WEB, APP, or WAP
"sign": "<SIGN>" // Request signature
}2
3
4
5
6
7
8
9
{
"respCode": "20000",
"respMsg": "Success",
"data": [
{
"productType": "LPMS",
"paymentMethod": "GooglePay",
"countryCode": "US",
"gatewayName": "ronghan", // Use as gateway
"gatewayMerchantId": "BCR2DN6TY7DM5TDU", // Use as gatewayMerchantId
"merchantId": "800096",
"subCardTypes": ["MASTERCARD", "VISA"] // Use as allowedCardNetworks
}
]
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
See Payment Methods Query API for complete documentation.
Backend Implementation
Call the Payment Methods Query API, filter Google Pay configuration and return to frontend:
// Merchant backend → Onerway: POST /v1/txn/consultPaymentMethod
config = consultPaymentMethod({ /* ... */ })
googlePay = config.find(paymentMethod == "GooglePay")
// Return to frontend
return {
gateway: googlePay.gatewayName, // Gateway identifier for tokenizationSpecification
gatewayMerchantId: googlePay.gatewayMerchantId, // Gateway merchant ID
allowedCardNetworks: googlePay.subCardTypes // Supported card networks
}2
3
4
5
6
7
8
9
10
Frontend Usage
- Get the config from your backend.
- Place
gateway/gatewayMerchantIdintokenizationSpecification.parameters. - Place
allowedCardNetworksinallowedPaymentMethods.parameters.allowedCardNetworks. - Fill in other payment amount, currency, merchant info according to your business.
2. Payment Authorization
Frontend Implementation
After loadPaymentData() succeeds, get the Google Pay token and send to backend for processing:
function processPayment(paymentData) {
// 1. Extract payment token from Google Pay event
const paymentToken = paymentData.paymentMethodData.tokenizationData.token
// 2. Send to your backend for payment processing
await fetch('/api/google-pay/process-payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ paymentToken })
})
}2
3
4
5
6
7
8
9
10
11
Backend Implementation
// Merchant backend → Onerway: POST /v1/txn/doTransaction
result = processPayment({
tokenInfo: {
provider: "GooglePay",
tokenId: paymentToken // From frontend
},
/* ... */
})
// Return to frontend
if (result.respCode != "20000") {
return { status: "F" } // Request failed
} else if (result.data.status == "S") {
return { status: "S", transactionId: result.data.transactionId } // Success
} else if (result.data.status == "R") {
return { status: "R", redirectUrl: result.data.redirectUrl } // PAN_ONLY redirect required
} else {
return { status: "P" } // Processing (wait for webhook)
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
View Complete API Parameters and Response Definition
Request Parameters
| Parameter | Type | Length | Required | Signed | Description |
|---|---|---|---|---|---|
billingInformation | String | / | Yes | Yes | Transaction billing information in JSON string format. See TransactionAddressfor complete structure. |
cardInfo | String | / | Conditional | Yes | Card information for wallet payments in JSON string format (merchant decrypt mode). See TxnCardInfoWalletfor complete structure. |
merchantCustId | String | 50 | Conditional | Yes | Unique customer identifier in merchant system. |
merchantNo | String | 20 | Yes | Yes | Merchant number assigned by |
merchantTxnId | String | 64 | Yes | Yes | Unique transaction identifier for each customer payment, generated by the merchant system. |
merchantTxnOriginalId | String | 128 | No | Yes | Master transaction ID generated by merchant for grouping related transactions. |
merchantTxnTime | String | / | No | Yes | Transaction timestamp when the merchant initiated the transaction. |
merchantTxnTimeZone | String | 64 | No | Yes | Transaction timezone offset for the merchant transaction time. |
orderAmount | String | 19 | Yes | Yes | Transaction amount in the specified currency, formatted as a decimal string. |
orderCurrency | String | 8 | Yes | Yes | |
productType | String | 16 | Yes | Yes | Payment method category that determines which payment options are available to customers. See ProductTypeEnumfor all available options. |
shippingInformation | String | / | Yes | Yes | Transaction shipping information in JSON string format. See TransactionAddressfor complete structure. |
sign | String | / | Yes | No | Digital signature string for request verification and security. Please refer to Signature for signature generation method. |
subProductType | String | 16 | Yes | Yes | Specific implementation method within the selected product type, defining how the payment is processed. See SubProductTypeEnumfor all available options. |
tokenInfo | String | / | Conditional | Yes | Wallet token information in JSON string format (Onerway decrypt mode). See WalletTokenInfofor the wallet token structure. |
txnOrderMsg | String | / | Yes | Yes | Transaction business information in JSON string format. See TxnOrderMsgfor complete structure. |
txnType | String | 16 | Yes | Yes | Transaction type that defines the payment operation to be performed. See TxnTypeEnumfor all available options and detailed usage scenarios. |
Token Decryption Mode (Choose One)
Pick exactly one mode per transaction:
- Onerway decrypt mode (recommended): Put the original Google Pay wallet token in
tokenInfo, Onerway will verify/decrypt it (provider="GooglePay",tokenId=<paymentToken>). - Merchant decrypt mode: Verify/decrypt the Google Pay token yourself, then put decrypted fields in
cardInfo(e.g.,cryptogram,eci,wallet.*). In this mode, do not sendtokenInfo.
Security & Compliance
Merchant decrypt mode means your backend directly handles decrypted sensitive data and 3DS-related fields. Ensure you meet PCI DSS and internal security requirements.
Merchant Decrypt Mode: Decrypted Token Examples
The following examples (from Google Pay documentation) show how authMethod differs between PAN_ONLY and CRYPTOGRAM_3DS after decryption:
// PAN_ONLY
{
"paymentMethod": "CARD",
"paymentMethodDetails": {
"authMethod": "PAN_ONLY",
"pan": "1111222233334444",
"expirationMonth": 10,
"expirationYear": 2025
},
"gatewayMerchantId": "some-merchant-id",
"messageId": "some-message-id",
"messageExpiration": "1759309000000"
}
// CRYPTOGRAM_3DS
{
"paymentMethod": "CARD",
"paymentMethodDetails": {
"authMethod": "CRYPTOGRAM_3DS",
"pan": "1111222233334444",
"expirationMonth": 10,
"expirationYear": 2025,
"cryptogram": "AAAAAA...",
"eciIndicator": "eci indicator"
},
"messageId": "some-message-id",
"messageExpiration": "1759309000000"
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Response
| Name | Type | Description |
|---|---|---|
respCode | String | Response code from |
respMsg | String | Response message from |
data | Object | Response data. Refer to object data |
data
| Name | Type | Description |
|---|---|---|
transactionId | String | Transaction order number created by |
paymentId | String | Payment intent ID |
responseTime | String | Interface response time Format: |
txnTime | String | Transaction completion time Format: |
txnTimeZone | String | Transaction time zone Format: |
orderAmount | String | Order amount |
orderCurrency | String | |
txnAmount | String | Order amount after conversion to settlement currency |
txnCurrency | String | |
status | String | Transaction processing result Refer to TxnStatusEnum |
paymentStatus | String | Payment intent status Refer to PaymentStatusEnum |
redirectUrl | String | Redirection URL for 3D Secure verification |
contractId | String | Subscription contract number |
tokenId | String | Payment token |
eci | String | Electronic Commerce Indicator |
periodValue | String | Installment payment number of periods |
codeForm | String | Code form for specific payment methods See CodeFormEnum |
presentContext | String | Context information for presentation layer |
actionType | String | Action type for the transaction See ActionTypeEnum |
subscriptionManageUrl | String | Subscription management URL |
sign | String |
PAN_ONLY Redirect Handling
When Google Pay uses PAN_ONLY authentication, Onerway may return status=R with a redirectUrl for additional CVV collection.
Frontend Redirect Logic
// 1. Submit Google Pay token to your backend
const result = await fetch('/api/google-pay/process-payment', {
method: 'POST',
body: JSON.stringify({ paymentToken, orderAmount, orderCurrency })
})
const data = await result.json()
// 2. If Onerway requires redirect (PAN_ONLY), redirect immediately
if (data.redirectUrl) {
window.location.href = data.redirectUrl
// Final status confirmed via webhook
} else {
// Show success/pending based on backend result
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
PAN_ONLY Flow
When receiving redirectUrl:
- Immediately: Redirect user to Onerway's CVV collection page
- User Action: Customer enters CVV on Onerway page
- Redirect Back: Onerway redirects user back to your
returnUrl - Async Notification: Onerway sends final status via webhook
- Display Result: Show final status based on webhook data or query transaction status
Authentication Methods
- CRYPTOGRAM_3DS (Recommended): Immediate authorization with device token and cryptogram
- PAN_ONLY: Requires CVV collection via redirect, adding an extra step for customers
Merchant-Collected CVV (Optional)
If you want to provide a smoother user experience, you can choose to collect CVV yourself instead of using Onerway's redirect page.
Use Cases:
- Provide seamless payment experience without page redirects
- Need full control over CVV input UI customization
- Have higher technical development capabilities
Implementation Requirements:
- Use the PAN_ONLY Check API to determine if CVV is needed
- Design and implement a CVV input UI on your frontend
- Pass
cvvin thecardInfofield of the payment request - Follow CVV security handling guidelines (no storage, no logging, HTTPS only)
For complete API documentation and integration guidelines, see: Google Pay PAN_ONLY Check and Custom CVV Collection
3. Webhook Notifications
You must treat webhooks as the final source of truth:
- Verify signature
- Handle idempotency (dedupe by
merchantTxnId) - Acknowledge: only return
transactionId
API Usage Examples
The following examples demonstrate a complete Google Pay payment flow, including request, responses for different scenarios, and webhook notification.
{
"merchantNo": "800209", // Merchant number
"merchantTxnId": "TXN-2025-000001", // Unique merchant transaction ID
"merchantTxnTime": "2025-06-25 20:18:57", // Merchant transaction time
"orderAmount": "1.00", // Order amount
"orderCurrency": "USD", // Order currency
"productType": "CARD", // Product type
"subProductType": "DIRECT", // Sub-product type
"txnType": "SALE", // Transaction type
"tokenInfo": "{\"provider\":\"GooglePay\",\"tokenId\":\"<GOOGLE_PAY_TOKEN>\"}", // Google Pay token
"txnOrderMsg": "{\"returnUrl\":\"https://merchant.example.com/return\",\"notifyUrl\":\"https://merchant.example.com/webhook\"}", // URLs
"billingInformation": "{\"country\":\"US\"}", // Required
"shippingInformation": "{\"country\":\"US\"}", // Required
"sign": "<SIGN>" // Request signature
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"merchantNo": "800209", // Merchant number
"merchantTxnId": "TXN-2025-000001", // Unique merchant transaction ID
"merchantTxnTime": "2025-06-25 20:18:57", // Merchant transaction time
"orderAmount": "1.00", // Order amount
"orderCurrency": "USD", // Order currency
"productType": "CARD", // Product type
"subProductType": "DIRECT", // Sub-product type
"txnType": "SALE", // Transaction type
"txnOrderMsg": "{\"returnUrl\":\"https://merchant.example.com/return\",\"notifyUrl\":\"https://merchant.example.com/webhook\"}", // URLs
"cardInfo": "{\"cardNumber\":\"1111222233334444\",\"month\":\"10\",\"year\":\"2025\",\"cryptogram\":\"AAAAAA...\",\"eci\":\"05\",\"wallet\":{\"type\":\"GooglePay\",\"googlePay\":{\"authMethod\":\"CRYPTOGRAM_3DS\"}}}", // Merchant decrypt mode (no tokenInfo)
"billingInformation": "{\"country\":\"US\"}", // Required
"shippingInformation": "{\"country\":\"US\"}", // Required
"sign": "<SIGN>" // Request signature
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"respCode": "20000", // Success
"respMsg": "Success",
"data": {
"status": "R", // Redirect required
"actionType": "RedirectURL",
"redirectUrl": "<REDIRECT_URL>", // Redirect to CVV page
"orderAmount": "1.00",
"orderCurrency": "USD",
"transactionId": null,
"sign": "<SIGN>" // Response signature
}
}2
3
4
5
6
7
8
9
10
11
12
13
{
"respCode": "20000", // Success
"respMsg": "Success",
"data": {
"status": "S", // Success
"transactionId": "<TRANSACTION_ID>", // Onerway transaction ID
"orderAmount": "1.00",
"orderCurrency": "USD",
"redirectUrl": null,
"sign": "<SIGN>" // Response signature
}
}2
3
4
5
6
7
8
9
10
11
12
{
"notifyType": "TXN",
"transactionId": "<TRANSACTION_ID>",
"merchantNo": "800209",
"merchantTxnId": "TXN-2025-000001",
"txnType": "SALE",
"orderAmount": "1.00",
"orderCurrency": "USD",
"status": "S", // Final status
"reason": "{\"respCode\":\"20000\",\"respMsg\":\"Success\"}",
"sign": "<SIGN>" // Webhook signature
}2
3
4
5
6
7
8
9
10
11
12
Frontend Complete Example (HTML)
HTML Complete Implementation
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Google Pay Integration (Demo)</title>
<style>
body { font-family: system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial; }
#container { max-width: 520px; margin: 24px auto; }
#status { margin-top: 12px; font-size: 14px; white-space: pre-wrap; }
</style>
</head>
<body>
<div id="container"></div>
<div id="status"></div>
<script>
const statusEl = document.getElementById('status')
/**
* Define the version of the Google Pay API referenced when creating your configuration.
*
* @see {@link https://developers.google.com/pay/api/web/reference/request-objects#PaymentDataRequest|apiVersion in PaymentDataRequest}
*/
const baseRequest = { apiVersion: 2, apiVersionMinor: 0 }
/**
* Card authentication methods supported by your site and your gateway.
*
* @see {@link https://developers.google.com/pay/api/web/reference/request-objects#CardParameters|CardParameters}
*/
const allowedCardAuthMethods = ['PAN_ONLY', 'CRYPTOGRAM_3DS']
function getTokenizationSpecification() {
return {
type: 'PAYMENT_GATEWAY',
parameters: {
// TODO: Replace with actual Onerway configuration
gateway: '<GATEWAY_FROM_ONERWAY>',
gatewayMerchantId: '<GATEWAY_MERCHANT_ID_FROM_ONERWAY>'
}
}
}
/**
* Card networks supported by your site and your gateway.
* TODO: Replace with `subCardTypes` returned by Onerway consultPaymentMethod.
*/
const allowedCardNetworks = ['AMEX', 'DISCOVER', 'JCB', 'MASTERCARD', 'VISA']
function getBaseCardPaymentMethod() {
return {
type: 'CARD',
parameters: {
allowedAuthMethods: allowedCardAuthMethods,
allowedCardNetworks: allowedCardNetworks
}
}
}
function getCardPaymentMethod() {
return Object.assign({}, getBaseCardPaymentMethod(), {
tokenizationSpecification: getTokenizationSpecification()
})
}
function getGoogleIsReadyToPayRequest() {
return Object.assign({}, baseRequest, {
allowedPaymentMethods: [getBaseCardPaymentMethod()]
})
}
let paymentsClient = null
let paymentToken = null
function setStatus(message) {
statusEl.textContent = message
}
function getGooglePaymentsClient() {
if (paymentsClient === null) {
paymentsClient = new google.payments.api.PaymentsClient({ environment: 'TEST' })
}
return paymentsClient
}
function getGoogleTransactionInfo() {
return {
countryCode: 'US',
currencyCode: 'USD',
totalPriceStatus: 'FINAL',
totalPrice: '1.00'
}
}
function getGooglePaymentDataRequest() {
const paymentDataRequest = Object.assign({}, baseRequest)
paymentDataRequest.allowedPaymentMethods = [getCardPaymentMethod()]
paymentDataRequest.transactionInfo = getGoogleTransactionInfo()
paymentDataRequest.merchantInfo = {
merchantName: 'Example Merchant'
}
// Optional: let Google Pay UI collect email/shipping info (for your checkout UX).
paymentDataRequest.emailRequired = true
paymentDataRequest.shippingAddressRequired = true
paymentDataRequest.shippingAddressParameters = {
phoneNumberRequired: true
}
return paymentDataRequest
}
function onGooglePayLoaded() {
const paymentsClient = getGooglePaymentsClient()
paymentsClient
.isReadyToPay(getGoogleIsReadyToPayRequest())
.then(function (response) {
if (response.result) {
addGooglePayButton()
setStatus('Ready for Google Pay')
} else {
setStatus('Google Pay is not available for this customer/device.')
}
})
.catch(function (err) {
console.error(err)
setStatus('Initialization failed. See console for details.')
})
}
function addGooglePayButton() {
const paymentsClient = getGooglePaymentsClient()
const button = paymentsClient.createButton({
onClick: onGooglePaymentButtonClicked,
allowedPaymentMethods: [getBaseCardPaymentMethod()]
})
document.getElementById('container').appendChild(button)
}
function onGooglePaymentButtonClicked() {
const paymentDataRequest = getGooglePaymentDataRequest()
paymentDataRequest.transactionInfo = getGoogleTransactionInfo()
const paymentsClient = getGooglePaymentsClient()
paymentsClient
.loadPaymentData(paymentDataRequest)
.then(function (paymentData) {
processPayment(paymentData)
})
.catch(function (err) {
console.error(err)
setStatus('Google Pay cancelled or failed. See console for details.')
})
}
function processPayment(paymentData) {
// DO NOT log or store `paymentToken` in production.
paymentToken = paymentData.paymentMethodData.tokenizationData.token
setStatus(
'TODO: send token to your backend to call Onerway /v1/txn/doTransaction.\n' +
'paymentToken=<hidden>'
)
// TODO: Replace with actual backend API call
// See the "Token Decryption Mode" + "API Usage Examples" sections for request structure.
}
</script>
<script async
src="https://pay.google.com/gp/p/js/pay.js"
onload="onGooglePayLoaded()"></script>
</body>
</html>2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
After frontend receives `paymentToken`:
1) Build and call `POST /v1/txn/doTransaction`
- Onerway decrypt mode: `tokenInfo.provider="GooglePay"`, `tokenInfo.tokenId=<paymentToken>`
- Merchant decrypt mode: do NOT send `tokenInfo`; send decrypted fields via `cardInfo` (see TxnCardInfoWallet)
- `billingInformation` and `shippingInformation` are required (preferably from your checkout data)
2) Handle the response
- `respCode != "20000"`: failure
- `data.status = "S"`: success
- `data.status = "R"` with `redirectUrl`: PAN_ONLY redirect; final status from webhook2
3
4
5
6
7
8
9
10
11
Error Handling
Common Errors
- Button not displaying:
pay.jsnot loaded / non-HTTPS / account has no available cards → CheckisReadyToPay()result - Configuration retrieval failed: Backend didn't return
gateway/gatewayMerchantId/allowedCardNetworks→ CheckconsultPaymentMethodcall - PAN_ONLY not handled:
doTransactionreturnsredirectUrlbut no redirect → Frontend should redirect immediately when receivingredirectUrl
Security Best Practices
- Don't decrypt tokens on client-side (server-only).
- Don't log or store Google Pay payment tokens.
- Webhooks must verify signatures and be idempotent.
- Verify order number/amount/currency match merchant records.
Implementation Best Practices
- Cache Onerway configuration for faster button response (refresh when config changes).
- Webhooks are the final source of truth.
- Test both PAN_ONLY redirect and CRYPTOGRAM_3DS direct success flows end-to-end.
Integration Checklist
- Backend config endpoint returns
gateway/gatewayMerchantId/allowedCardNetworks - Implemented
loadPaymentData()and extractpaymentToken - Backend calls
doTransactionwith correcttokenInfostructure (provider="GooglePay",tokenId=<paymentToken>) - Frontend redirects immediately when PAN_ONLY returns
redirectUrl - Webhook signature verification + idempotency implemented
Related Documentation
Onerway Documentation
- Payment Methods Query API - Get Google Pay configuration
- Transaction Notification - Handle webhook notifications
- Google Pay PAN_ONLY Check and Custom CVV Collection - Custom option: Merchant-collected CVV
Official Google Pay Resources
- Complete Documentation - Google's full web integration guide
- Interactive Demos - Test Google Pay in different scenarios
- Button Customization - Button styling and properties reference
- Brand Guidelines - Logo and brand usage guidelines
Need Help?
For technical support or questions about Google Pay integration, contact Onerway support.