Skip to main content

Collect Google Pay

In this guide, we will set up Credova Elements SDKs to capture Google Pay in a frontend application and securely authorize and store the Google Pay data while avoiding PCI requirements.

Getting Started

To get started, you will need a Credova Account.

Get your Publishable Key

Next you will need your Publishable Key. Go to your Developers section and click Reveal for your Publishable Key and copy the value.

Save the Publishable Key as it will be used in the next steps of this guide.

Configuring Credova Elements

Credova Elements are available for the following technologies. Click below for detailed instructions on how to install and configure them.

Javascript
React

Google Pay Setup

To start, we want to ensure that you're able to connect to Google's APIs. Make sure you've met all the pre-requisites in Google's setup guide.

Configure Google Pay

First, let's add the Google Pay button.

index.html
<div ref={buttonContainerRef}></div>
index.js
import { PublicSquare } from "@publicsquare/elements-js";

let publicsquare;
let buttonContainerRef;
let googlePayButtonRef;

async function init() {
publicsquare = await new PublicSquare().init('<PUBLISHABLE_API_KEY>');

// Render the Google Pay button
googlePayButtonRef = publicsquare.googlePay.renderButton(buttonContainerRef.current!, {
id: 'google-pay-btn',
environment: 'TEST',
merchantName: 'Merchant Name',
allowedCardAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
allowedCardNetworks=['AMEX', 'DISCOVER', 'INTERAC', 'JCB', 'MASTERCARD', 'VISA']
style: {
width: '160px',
height: '40px',
borderRadius: 4,
borderType: 'default_border'
},
transactionInfo: {
totalPriceStatus: 'FINAL',
totalPrice: '1.00',
currencyCode: 'USD',
countryCode: 'US'
},
disabled: loading,
onClick: async () => {
// Handle button click (optional)
},
onPaymentDataLoaded: async (paymentData) => {
onPaymentAuthorized(paymentData)
}
});
}

await init();

Adding the code above will render a Google Pay button on your site with a onPaymentDataLoaded event which will be called when the user successfully authorizes a payment.

Billing and Shipping Addresses

This behavior requires Credova Elements SDKs v1.15.1 or later.

The Google Pay sheet always collects a billing address from the customer — this is not configurable. The billing address is returned in onPaymentDataLoaded as paymentData.paymentMethodData.info.billingAddress, and is automatically stored as the payment method's billing_details when you create the payment method. There's nothing you need to configure to collect billing.

Google Pay collects the billing address in its FULL format, meaning customers see and enter a complete street address (not just a postal code), along with a billing phone number. As of Credova Elements v1.15.1 the phone number is always requested with the billing address on the Google Pay sheet, and is stored on the payment method.

Shipping address collection is optional and off by default. Enable it with the shippingAddressRequired option, and optionally restrict which countries are allowed or require a phone number with shippingAddressParameters:

OptionTypeDefaultDescription
shippingAddressRequiredbooleanfalseWhen true, the Google Pay sheet also collects a shipping address.
shippingAddressParameters{ allowedCountryCodes?: string[], phoneNumberRequired?: boolean }undefinedRestricts the shipping address collected to the given country codes, and/or requires a phone number. Only used when shippingAddressRequired is true.
index.js
googlePayButtonRef = publicsquare.googlePay.renderButton(buttonContainerRef.current!, {
id: 'google-pay-btn',
environment: 'TEST',
merchantName: 'Merchant Name',
transactionInfo: {
totalPriceStatus: 'FINAL',
totalPrice: '1.00',
currencyCode: 'USD',
countryCode: 'US'
},
shippingAddressRequired: true,
shippingAddressParameters: {
allowedCountryCodes: ['US', 'CA'],
phoneNumberRequired: true
},
onPaymentDataLoaded: async (paymentData) => {
onPaymentAuthorized(paymentData)
}
});

When shippingAddressRequired is enabled, the shipping address is returned at the root of the onPaymentDataLoaded payload as paymentData.shippingAddress. We don't store the shipping address on the payment method — pass it along as shipping_address when you create the payment. The billing address is already stored on the payment method from the earlier tokenization step, so you don't need to read it again here.

index.js
async function onPaymentAuthorized(paymentData) {
const shippingAddress = paymentData.shippingAddress;

const paymentMethod = await createGooglePayPaymentMethod(paymentData);

const shippingAddressPayload = shippingAddress && {
address_line_1: shippingAddress.address1,
address_line_2: shippingAddress.address2,
city: shippingAddress.locality,
state: shippingAddress.administrativeArea,
postal_code: shippingAddress.postalCode,
country: shippingAddress.countryCode
};

await chargePayment(paymentMethod.id, {
shipping_address: shippingAddressPayload
});
}

Tokenization and Storing Google Pay

After the customer has authorized the payment, your application will need to call our create method from the SDK with the Google Pay payment method data to create a Google Pay payment method in your account.

To do this, we will handle the onPaymentDataLoaded event to call Public Square, passing the Google Pay payment data:

index.js
import { PublicSquare } from "@publicsquare/elements-js";

let publicsquare;
let buttonContainerRef;
let googlePayButtonRef;

async function init() {
publicsquare = await new PublicSquare().init('<PUBLISHABLE_API_KEY>');

googlePayButtonRef = publicsquare.googlePay.renderButton(
...
onPaymentDataLoaded: async (paymentData) => {
onPaymentAuthorized(paymentData)
}
);

async function onPaymentAuthorized(event: any) {
// Disable the Google Pay button
googlePayButtonRef.current?.setDisabled(true);

try {
// Create a Google Pay payment method from the payment method data
const paymentMethod = await createGooglePayPaymentMethod(event)

// Send the payment method to the backend for payment processing
await chargePayment(paymentMethod.id);
} catch (e) {
console.error(e);
}

// Re-enable the Google Pay button
googlePayButtonRef.current?.setDisabled(false);
}

async function createGooglePayPaymentMethod(event: any) {
if (publicsquare) {
try {
const response = await publicsquare.googlePay.create({
google_payment_method_data: event.paymentMethodData
})
if (response) {
return response
}
} catch (error) {
console.log(error)
}
}
}
}

await init();

The created Google Pay object contains the non-sensitive information about the Google Pay:

{
"id": "ggl_Aw3U2eESBnq6DoYEFn8qaSMrA",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"customer_id": "cus_7Ay5mcUXAxwrN6wQEQUVEHBCJ",
"token_type": "card",
"last4": "4242",
"exp_month": "12",
"exp_year": "2025",
"fingerprint": "6Bh4Dnq4jrTte3Rp4k9u6HheqSXvhTEDi4qv5M4bNrbH",
"brand": "visa",
"billing_details": {
"address_line_1": "111 Colorado Ave.",
"address_line_2": "Apt 403",
"city": "Des Moines",
"state": "IA",
"postal_code": "51111",
"country": "US"
},
"expires_at": "2024-06-31T01:02:29.212Z",
"created_at": "2024-06-30T01:02:29.212Z",
"modified_at": "2024-06-30T01:02:29.212Z"
}

You can safely store the Google Pay payment method id value in your database to use it to process a payment or associate it with a customer.

You can optionally pass in a customer_id to associate with an existing Created Customer. The billing_details shown above always comes from the Google Pay sheet (see Billing and Shipping Addresses) — there's no need to pass them yourself, and doing so has no effect.

Testing

If you don't have a Google Pay merchantId yet from Google's setup guide, you can use the TEST environment in the Google Pay button configuration. Also retrieve your Test API Keys from your Account in Test mode to simulate production. This environment allows you to test your integration.

For more information about testing, refer to the Testing documentation.

Preparing for Production

Once you're ready for production, you'll want to publish your integration with Google Pay by following the official guide. When you have your official merchantId, you can set your merchantId in the Google Pay button configuration, and change the environment to PRODUCTION.

index.js
publicsquare.googlePay.renderButton(buttonContainerRef.current!, {
id: 'google-pay-btn',
environment: 'PRODUCTION',
merchantId: 'ABC123256PR',
merchantName: 'Merchant Name',
allowedCardAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
allowedCardNetworks=['AMEX', 'DISCOVER', 'INTERAC', 'JCB', 'MASTERCARD', 'VISA']
style: {
width: '160px',
height: '40px',
borderRadius: 4,
borderType: 'default_border'
},
transactionInfo: {
totalPriceStatus: 'FINAL',
totalPrice: '1.00',
currencyCode: 'USD',
countryCode: 'US'
},
disabled: loading,
onPaymentDataLoaded: async (paymentData) => {
onPaymentAuthorized(paymentData)
}
});

Conclusion

Following this guide, you have successfully collected a customer's Google Pay. To use this Google Pay payment method, proceed with the Process Google Pay Payments guide.