This guide explains how to integrate Google Pay on your custom web pay page using the N-Genius platform.
It covers two scenarios:
- Non-PCI DSS merchants using the
/google-pay/accept
endpoint (Network International handles token decryption). - PCI DSS-certified merchants using the
/google-pay/direct
endpoint (merchant decrypts the Google Pay token).
See also:
- Enable Google Pay – request enablement on your account.
- Google Pay Direct API Integration – backend order creation and configuration details.
Prerequisites
- Google Pay enabled on your merchant account.
- Access to your N-Genius Business Profile ID.
- For PCI DSS merchants: an ECv2 key pair (public/private) registered with Google.
- Access Token Guide for obtaining merchant access tokens.
Option 1 – Non-PCI DSS Merchants
For merchants who use a custom pay page but are not PCI DSS certified, Network International handles the decryption. You will integrate with the /google-pay/accept
endpoint.
1. Add Google Pay SDK to your web page
<script async src="https://pay.google.com/gp/p/js/pay.js" onload="onGooglePayScriptLoaded()"></script>
<div id="gpay-container"></div>
<script>
function onGooglePayScriptLoaded() {
const paymentsClient = new google.payments.api.PaymentsClient({ environment: 'TEST' }); // Switch to 'PRODUCTION' when live
const baseRequest = { apiVersion: 2, apiVersionMinor: 0 };
const allowedCardNetworks = ["VISA", "MASTERCARD"];
const allowedCardAuthMethods = ["PAN_ONLY", "CRYPTOGRAM_3DS"];
const tokenizationSpecification = {
type: "PAYMENT_GATEWAY",
parameters: {
gateway: "networkintl",
gatewayMerchantId: "<YOUR_NGENIUS_BUSINESS_PROFILE_ID>"
}
};
const cardPaymentMethod = {
type: "CARD",
parameters: {
allowedAuthMethods: allowedCardAuthMethods,
allowedCardNetworks: allowedCardNetworks
},
tokenizationSpecification
};
paymentsClient.isReadyToPay({
...baseRequest,
allowedPaymentMethods: [cardPaymentMethod]
}).then(res => {
if (!res.result) return;
const button = paymentsClient.createButton({
onClick: () => onPayClicked(paymentsClient, cardPaymentMethod)
});
document.getElementById("gpay-container").appendChild(button);
});
}
function onPayClicked(paymentsClient, cardPaymentMethod) {
const request = {
apiVersion: 2,
apiVersionMinor: 0,
allowedPaymentMethods: [cardPaymentMethod],
transactionInfo: {
totalPriceStatus: "FINAL",
totalPrice: "10.00", // Example
currencyCode: "AED"
},
merchantInfo: { merchantName: "Your Store" }
};
paymentsClient.loadPaymentData(request).then(paymentData => {
const gpayToken = paymentData.paymentMethodData.tokenizationData.token;
// Send token to your backend
fetch("/gpay/accept", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token: gpayToken })
});
}).catch(console.error);
}
</script>
2. Create an Order
curl --request POST \
'https://api-gateway.sandbox.ngenius-payments.com/transactions/outlets/<OUTLET_ID>/orders' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--header 'Content-Type: application/vnd.ni-payment.v2+json' \
--data '{
"action": "PURCHASE",
"amount": { "currencyCode": "AED", "value": 1000 },
"merchantAttributes": { "redirectUrl": "https://your-site.test/return" }
}'
3. Call the /google-pay/accept
endpoint
/google-pay/accept
endpointUse the gpayToken
from your frontend:
curl --location 'https://api-gateway.sandbox.ngenius-payments.com/transactions/outlets/<OUTLET_ID>/orders/<ORDER_ID>/payments/<PAYMENT_ID>/google-pay/accept?isWebPayment=true' \
--header 'Accept: application/vnd.ni-payment.v2+json' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--data '{
"token": "<stringified gpayToken>"
}'
The
isWebPayment=true
query parameter must be included.
Option 2 – PCI DSS Merchants
For PCI DSS-certified merchants who wish to control token decryption, use the /google-pay/direct
endpoint. Google will encrypt tokens to your ECv2 public key, and you must decrypt them with your ECv2 private key.
1. Add Google Pay SDK with Direct tokenization
<script async src="https://pay.google.com/gp/p/js/pay.js" onload="onGooglePayScriptLoaded()"></script>
<div id="gpay-container"></div>
<script>
function onGooglePayScriptLoaded() {
const paymentsClient = new google.payments.api.PaymentsClient({ environment: 'TEST' });
const baseRequest = { apiVersion: 2, apiVersionMinor: 0 };
const allowedCardNetworks = ["VISA", "MASTERCARD"];
const allowedCardAuthMethods = ["PAN_ONLY", "CRYPTOGRAM_3DS"];
const tokenizationSpecification = {
type: "DIRECT",
parameters: {
protocolVersion: "ECv2",
publicKey: "<YOUR_ECv2_PUBLIC_KEY>"
}
};
const cardPaymentMethod = {
type: "CARD",
parameters: {
allowedAuthMethods: allowedCardAuthMethods,
allowedCardNetworks: allowedCardNetworks
},
tokenizationSpecification
};
paymentsClient.isReadyToPay({ ...baseRequest, allowedPaymentMethods: [cardPaymentMethod] })
.then(res => {
if (!res.result) return;
const button = paymentsClient.createButton({
onClick: () => onPayClicked(paymentsClient, cardPaymentMethod)
});
document.getElementById("gpay-container").appendChild(button);
}).catch(console.error);
}
</script>
2. Decrypt the Token
Use Google Tink to decrypt the token with your ECv2 private key:
PaymentMethodTokenRecipient recipient = new PaymentMethodTokenRecipient.Builder()
.fetchSenderVerifyingKeysWith(GooglePaymentsPublicKeysManager.INSTANCE_TEST) // or INSTANCE_PRODUCTION
.recipientId("<YOUR_GOOGLE_MERCHANT_ID>")
.protocolVersion("ECv2")
.addRecipientPrivateKey("<YOUR_ECv2_PRIVATE_KEY>")
.build();
String plaintext = recipient.unseal(gpayToken);
3. Call the /google-pay/direct
endpoint
/google-pay/direct
endpointAfter decryption, send the card details to Network International:
curl --location 'https://api-gateway.sandbox.ngenius-payments.com/transactions/outlets/<OUTLET_ID>/orders/<ORDER_ID>/payments/<PAYMENT_ID>/google-pay/direct' \
--header 'Authorization: Bearer <ACCESS_TOKEN>' \
--data '{
"pan": "1234123412341234",
"expiry": "2030/12",
"eci": "05",
"cryptogram": "AAAA="
}'
Notes
- Non-PCI DSS merchants must use
/google-pay/accept
. - PCI DSS merchants may use
/google-pay/direct
but must manage decryption securely. - Always test in Sandbox before going live.