Skip to main content

Set Up 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. To charge the collected Google Pay payment method, see Accept Google Pay.

Before you start​

Credova account
Sign up or sign in to the Credova Portal.
Publishable Key
Loads Credova Elements in the browser. It is safe to put in frontend code.
Secret Key
Authenticates requests from your server. Never send it to the browser.

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, use the TEST environment in the Google Pay button configuration. Pair it with your Test API keys from your Account.

See Testing for test cards, test hostnames and simulated declines.

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​

You saved a customer's Google Pay payment method. To use it, follow these guides: