Skip to main content

Google Pay

Google Pay integration enables customers to pay using cards stored on their Google account. The payment is processed natively in the browser or app, without the need to enter card details.

Flow diagram

Step 1: Register the payment

Register the transaction using the standard method:

curl -X POST https://api-payments.dpay.pl/api/v1_0/payments/register \
-H "Content-Type: application/json" \
-d '{
"transactionType": "transfers",
"service": "abc123",
"value": "49.99",
"url_success": "https://myshop.com/success",
"url_fail": "https://myshop.com/error",
"url_ipn": "https://myshop.com/api/ipn",
"checksum": "..."
}'

Save the transactionId from the response.

Step 2: Configure the Google Pay button

Add the Google Pay API script and configure the button on your page:

<script src="https://pay.google.com/gp/p/js/pay.js"></script>
<div id="google-pay-button"></div>

JavaScript configuration

// Google Pay configuration
const googlePayConfig = {
apiVersion: 2,
apiVersionMinor: 0,
allowedPaymentMethods: [
{
type: 'CARD',
parameters: {
allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
allowedCardNetworks: ['VISA', 'MASTERCARD'],
},
tokenizationSpecification: {
type: 'PAYMENT_GATEWAY',
parameters: {
gateway: 'aciworldwide',
gatewayMerchantId: 'YOUR_MERCHANT_ID', // ID provided by dpay support
},
},
},
],
};

// Payment request configuration
const paymentDataRequest = {
...googlePayConfig,
transactionInfo: {
totalPriceStatus: 'FINAL',
totalPrice: '49.99',
currencyCode: 'PLN',
countryCode: 'PL',
},
merchantInfo: {
merchantName: 'My Shop',
merchantId: 'BCR2DN4T...', // Your Google Merchant ID
},
};

Initialization and button display

let paymentsClient;

async function initGooglePay() {
paymentsClient = new google.payments.api.PaymentsClient({
environment: 'PRODUCTION', // or 'TEST' for testing
});

// Check if Google Pay is available
const isReadyToPay = await paymentsClient.isReadyToPay(googlePayConfig);

if (isReadyToPay.result) {
const button = paymentsClient.createButton({
onClick: onGooglePayClicked,
buttonColor: 'black',
buttonType: 'pay',
buttonLocale: 'pl',
});
document.getElementById('google-pay-button').appendChild(button);
}
}

async function onGooglePayClicked() {
try {
const paymentData = await paymentsClient.loadPaymentData(paymentDataRequest);
await processGooglePayPayment(paymentData);
} catch (error) {
console.error('Google Pay error:', error);
}
}

// Initialize after page load
google.payments.api.PaymentsClient && initGooglePay();

Step 3: Send the token to dpay.pl

After the customer approves the payment in Google Pay, send the received token to dpay.pl. Encode the paymentMethodData.tokenizationData.token value from the Google Pay response in Base64 and pass it as xPayToken.

POST https://api-payments.dpay.pl/api/v1_0/cards/payment/{transactionId}/pay/google-pay
Content-Type: application/json

Request parameters

{
"email": "customer@example.com",
"channelId": 31,
"xPayType": "GOOGLE_PAY",
"xPayToken": "<Base64(token from paymentMethodData.tokenizationData.token)>",
"deviceInfo": {
"browserAcceptHeader": "application/json,text/plain,*/*",
"browserJavaEnabled": "false",
"browserLanguage": "pl-PL",
"browserColorDepth": 24,
"browserScreenHeight": 1080,
"browserScreenWidth": 1920,
"browserTZ": -60,
"browserUserAgent": "Mozilla/5.0 ...",
"systemFamily": "Win32",
"deviceID": "device-unique-id",
"applicationName": "Netscape"
}
}

Required fields: channelId, xPayType, xPayToken, deviceInfo. The channelId is the card channel identifier provided by dpay support. See the full deviceInfo specification in the API reference.

JavaScript - payment processing

async function processGooglePayPayment(paymentData) {
const transactionId = '...'; // From Step 1

const deviceInfo = {
browserAcceptHeader: 'application/json,text/plain,*/*',
browserJavaEnabled: navigator.javaEnabled?.() ? 'true' : 'false',
browserLanguage: navigator.language || 'pl-PL',
browserColorDepth: screen.colorDepth,
browserScreenHeight: screen.height,
browserScreenWidth: screen.width,
browserTZ: new Date().getTimezoneOffset(),
browserUserAgent: navigator.userAgent,
systemFamily: navigator.platform || 'Unknown',
deviceID: 'device-unique-id',
applicationName: navigator.appName || 'Netscape',
};

// The Google Pay token must be Base64-encoded
const xPayToken = btoa(paymentData.paymentMethodData.tokenizationData.token);

const response = await fetch(`/api/pay/google-pay`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
transactionId,
email: paymentData.email,
xPayToken,
deviceInfo,
}),
});

const result = await response.json();

if (!result.success) {
alert('Payment error: ' + result.message);
return;
}

// For Google Pay the response is always redirectType: 'SUCCESS' on success, or an error.
// Authorization (including 3DS) happens inside the Google Pay wallet on the client side.
window.location.href = '/success';
}

Server (Node.js) - proxy to dpay.pl

app.post('/api/pay/google-pay', async (req, res) => {
const { transactionId, email, xPayToken, deviceInfo } = req.body;

const response = await axios.post(
`https://api-payments.dpay.pl/api/v1_0/cards/payment/${transactionId}/pay/google-pay`,
{
email,
channelId: process.env.DPAY_CARD_CHANNEL_ID,
xPayType: 'GOOGLE_PAY',
xPayToken,
deviceInfo,
}
);

res.json(response.data);
});

API response

Every response includes success, status, and message fields. For success, message is an object {redirectText, redirectType}; for errors it is a string.

3D Secure

For Google Pay, authorization (including any 3DS challenge) happens inside the Google wallet on the client side, before the token is sent to dpay. The dpay endpoint always returns redirectType: "SUCCESS" on a successful transaction, or an error - it never returns FORM or an additional 3DS challenge.

Success - payment completed

{
"success": true,
"status": "success",
"message": {
"redirectText": "",
"redirectType": "SUCCESS"
}
}

Error

{
"success": false,
"status": "error",
"message": "Error during payment creation"
}

Test environment

For testing, use the TEST environment in the Google Pay configuration:

const paymentsClient = new google.payments.api.PaymentsClient({
environment: 'TEST',
});

In the test environment, Google Pay returns fictitious tokens that can be used to test the integration.

Requirements
  • Your website must be accessible via HTTPS
  • You must have a verified Google Merchant ID (for production)
  • Your domain must be registered in the Google Pay & Wallet Console