Learn how to accept Google Pay in your website or Android app.
Still have questions? Check out our FAQs.
Google Pay™ is a simple, secure payment experience allowing shoppers to make first-time and recurring purchases with major credit and debit cards (such as Mastercard, Visa, American Express, and Discover) saved to their Google Account, including ones from Google Play, YouTube, Chrome, or an Android device.
As a BlueSnap merchant, you don't need BlueSnap to set up your activation with Google Pay; all you have to do is sign up for a Google Pay developer account and start using it.
This guide covers the following topics:
- Benefits
- Supported Markets
- Implementing Google Pay in your Website
- Implementing Google Pay in your Android App
- Testing in Sandbox
- Processing Transactions
Important Notes
- Before you get begin development, review the following as applicable:
- By integrating Google Pay, you are agreeing to Google’s terms & conditions. Find more details here.
Benefits
- A better way to pay: Google Pay is a faster, more secure way to pay on sites and in apps by using payment methods saved to a Google Account.
- Availability: Google Pay is accepted in millions of places around the world. It's available on Android, iOS, and desktop, and you can use it on multiple browsers, including Chrome, Firefox, and Safari.
- Increased conversions: Google Pay delivers frictionless checkout by eliminating the need to type billing and shipping details, and increasing conversions by giving shoppers a better way to pay.
- Increased security: Google Pay protects your payment information with multiple layers of security, including card network tokenization.
Apple Pay and Google Pay
If you want to integrate to both Apple Pay and Google Pay, check out our Payment Request Button solution.
Supported Markets
Supported Merchant Countries
Merchants domiciled in the following regions will be able to accept Google Pay.
Issuers Supporting Google Pay
Shoppers whose issuing banks are located in these regions will be eligible to purchase with Google Pay. However, shoppers using tokenized cards (cards stored on their Android device) can only use them in a subset of countries and on compatible Android devices.
Implementing Google Pay in your website
When shoppers use Google Pay on your website, all they have to do is select an item(s) to purchase, select Google Pay as their payment method, and complete the transaction.
The shopper experience with Google Pay on the web
The shopper clicks the Google Pay button on your checkout page.
The Google Pay payment page opens on top of the checkout page.
Here, the shopper can select their payment method, or add or change any of their billing and shipping information.
After the shopper reviews and confirms the order, the checkout page provides a confirmation message.
Note
Refer to the Google Pay brand guidelines and their integration checklist when referencing their brand within your website.
Website Implementation Overview
Follow the implementation instructions under the Tutorial section, which includes creating a Google account and obtaining production access.
Before you Begin
- When following Google’s tutorial, you must specify BlueSnap as your payment gateway and supply your BlueSnap merchant ID under “Choose a payment tokenization method”, as shown in the example below.
- Your
gatewayMerchantId
is different for BlueSnap Sandbox and Production.
Be sure to use the correct merchant ID to avoid processing errors. - Keep in mind, your
gatewayMerchantId
is different from your Google merchant identifier (merchantId
), which is issued by Google after registering with Google Pay and Wallet Console. ThismerchantId
is used in themerchantInfo
section of thepaymentDataRequest
object. - Only payment methods supported by BlueSnap can be processed. In order to ensure you are passing supported card brands, use the code snippet below labeled Supported card brands.
const tokenizationSpecification = {
type: 'PAYMENT_GATEWAY',
parameters: {
'gateway': 'bluesnap',
'gatewayMerchantId': '<yourBlueSnapMerchantId>'
}
};
const allowedCardAuthMethods = ["PAN_ONLY", "CRYPTOGRAM_3DS"];
const allowedCardNetworks = ["AMEX", "DISCOVER", "JCB", "MASTERCARD", "VISA"];
const baseCardPaymentMethod = {
type: 'CARD',
parameters: {
allowedAuthMethods: allowedCardAuthMethods,
allowedCardNetworks: allowedCardNetworks,
billingAddressRequired: true,
billingAddressParameters: {
"format": "FULL",
"phoneNumberRequired": true
}
}
};
Step 1: Add the Google Pay payment button
Follow the instructions here to add a Google Pay payment button.
Note: BlueSnap requires at least basic billing address information in the token.
Step 2: Create a Google Pay wallet token
You must package the response you received from Google Pay as a base-64 encrypted string by performing the following task.
In your onActivityResult
method, the result from the Google Pay popup displays similar to the following:
const paymentsClient = getGooglePaymentsClient();
paymentsClient.loadPaymentData(paymentDataRequest)
.then(function(paymentData) {
// handle the response
processPayment(paymentData);
})
.catch(function(err) {
// show error in developer console for debugging
console.error(err);
});
Your processPayment
function is called, if your shopper successfully completed the Google Pay flow. Make sure you encrypt the Google Pay payment data into a payment token that you will use in the BlueSnap API calls. It should look similar to the following:
function processPayment(paymentData) {
var paymentToken = b64EncodeUnicode(JSON.stringify(paymentData));
// @todo pass paymentToken to your gateway to process payment
}
function b64EncodeUnicode(str) {
// first we use encodeURIComponent to get percent-encoded UTF-8,
// then we convert the percent encodings into raw bytes which
// can be fed into btoa.
return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
function toSolidBytes(match, p1) {
return String.fromCharCode('0x' + p1);
}));
}
Your final JSON result
object (before base64 encoding) should look as follows:
{
"paymentMethodData": {
"description": "Visa •••• 1111",
"tokenizationData": {
"type": 1,
"token": "{\"signature\":\"MEYCIQCHjVVouweiNXb1IRbV6wdl+kPIaq+vuAnydlXb51BymwIhAJx+K5lYNTwKzrADTLH\/irbO44miaOpkH7SCmCiDMnW0\",\"protocolVersion\":\"ECv1\",\"signedMessage\":\"{\\\"encryptedMessage\\\":\\\"eNAo5QEw1hAqwLioNnI8d1afowQ\/HOXtLoAqplzcFZ3zb6OSAA+mjTjH0ceiGX5copnMc\/L8r4ZTgh5kn+vHo0Lt18pyyCEfUEJrKD5lepCPufLoOaayC2aBWh3KwfqsiClh70VirxSoiWnUEME+heXcG1dwEo2KNw7BGBBgf7+GtqsDx8BD0SA0jPWIBhs7V1SMIjooS70gPygXjErddNIpGSKiTL3Mg0EdZWEoL89GjEajjPGJuSuFv8w5KtetdtFuAGzqryvoFuAxXpLCOZ54mEriIBm6SF2QkDIftGuf0\/vjQFNzq4Ri26kEI2crbSa+NDiLFhremmV8nzDRKb5x1JNgjhmHKi9os2VT2UYh97eLdTiwX82EVQD2WcdgFINRSwyb3MNP\/AMYxWCK6T6CQjtXZEijM\/Jei4ZFbASIuazP2tcHOWquZgz6I3\/1RnwNvcyOm5b8aKfT+BxZQjiiOA\/dMKKBJSrrnJSw+F0Cl5AixUfwtMRyxKe29sJzwfi1OXsLzeahgRygqmis1gwzzTn5Z+FREfx2IOV8SGrHYLea9rJmPMFn4dnFYOEngHEohBc+6e6Z\\\",\\\"ephemeralPublicKey\\\":\\\"BJfG4lyyZgfTsSBd15HIxSNr2pCvjkGfSAFgXZxoAUWoMlAhrcbiRmUhRgaLhLRbjViVWWmdyvci5X+Hcvyi+3M\\\\u003d\\\",\\\"tag\\\":\\\"1j\/WSZWsdzp417KGW+fR+\/vd70WWsptpxbwVXZ6NWqk\\\\u003d\\\"}\"}"
},
"info": {
"cardNetwork": "VISA",
"cardDetails": "1111",
"cardClass": "CREDIT",
"billingAddress": {
"name": "aaa bbb",
"postalCode": "11111",
"countryCode": "US",
"phoneNumber": "11111111111",
"companyName": "",
"emailAddress": "[email protected]",
"address1": "11 aa Street",
"administrativeArea": "MA",
"locality": "aa",
"sortingCode": ""
}
}
},
"email": "[email protected]",
"googleTransactionId": "ac5837bf-a8ec-48f6-95ba-2f534e0475d8.PROD",
"shippingAddress": {
"name": "aaa bbb",
"postalCode": "11111",
"countryCode": "US",
"phoneNumber": "11111111",
"companyName": "",
"emailAddress": "[email protected]",
"address1": "11 aa Street",
"administrativeArea": "MA",
"locality": "Milton",
"sortingCode": ""
}
}
Note
This
paymentToken
should be sent to the BlueSnap API, as detailed in the Processing Transactions section.
Implementing Google Pay in your Android App
Implement Google Pay in your Android app using BlueSnap's Android SDK to let shoppers purchase physical items (such as groceries and clothing) or services (such as gym memberships and hotel reservations).
Note
Your Android app must be approved by Google before it’s available in the Google Play store.
If you use BlueSnap’s Android SDK for your checkout, you don’t need to do any coding — just register with Google and enable this payment method in the Merchant Portal!
If you prefer not to use BlueSnap's Android SDK, you can implement Google Pay in your Android app by following Google's instructions.
The shopper experience with Google Pay in your app
The shopper clicks the Google Pay button on your checkout page.
The Google Pay pop-up opens on top of the checkout page.
Here, the shopper can select their payment method, or add or change any of their billing and shipping information.
After the shopper reviews and confirms the order, the checkout page provides a confirmation message.
Note
Refer to the Google Pay brand guidelines and their integration checklist when referencing their brand within your Android app.
Android App Implementation Overview
If you decide to implement Google Pay in your Android app on your own (without using BlueSnap's Android SDK), follow the implementation instructions under the Tutorial section, which include creating a Google account and obtaining production access.
Step 1: Add the Google Pay payment button
Follow the instructions here to add a Google Pay payment button to your app.
Note: BlueSnap requires at least basic billing address information in the token.
Step 2: Supply your BlueSnap merchant ID
Use the following code to provide your merchant ID.
private static JSONObject getTokenizationSpecification() {
JSONObject tokenizationSpecification = new JSONObject();
tokenizationSpecification.put("type", "PAYMENT_GATEWAY");
tokenizationSpecification.put(
"parameters",
new JSONObject()
.put("gateway", "bluesnap")
.put("gatewayMerchantId", "yourBlueSnapMerchantId"));
return tokenizationSpecification;
}
Note
Your
gatewayMerchantId
is specific for BlueSnap Sandbox and Production. Be sure to use the correct merchant ID to avoid processing errors.
Step 3: Create a Google Pay wallet token
You must package the response you received from Google Pay as a base-64 encrypted string by performing the following task.
In your onActivityResult
method where you get the result from the Google-Pay popup, which displays similar to the following:
switch (requestCode) {
case GOOGLE_PAY_PAYMENT_DATA_REQUEST_CODE: {
switch (resultCode) {
case Activity.RESULT_OK:
PaymentData paymentData = PaymentData.getFromIntent(data);
handleGooglePaySuccess(paymentData);
break;
case Activity.RESULT_CANCELED:
// Nothing to here normally - the user simply cancelled without selecting a
// payment method.
break;
case AutoResolveHelper.RESULT_ERROR:
Status status = AutoResolveHelper.getStatusFromIntent(data);
handleGooglePayError(status.getStatusCode());
break;
}
…
Your handleGooglePaySuccess
function will be called, if your shopper successfully completed the Google Pay flow. Make sure you encrypt the Google Pay payment data into a payment token, which you will use in BlueSnap API calls. It should look similar to the following:
String paymentToken = createBlsTokenFromGooglePayPaymentData(paymentData);
/**
* Creates a base64 encoded token with the PaymentData
*/
public String createBlsTokenFromGooglePayPaymentData(PaymentData paymentData) throws Exception {
final CardInfo cardInfo = paymentData.getCardInfo();
JSONObject result = new JSONObject();
// paymentMethodData
JSONObject paymentMethodData = new JSONObject();
// paymentMethodData -> description: A payment method and method identifier suitable for communication to a shopper in a confirmation screen or purchase receipt.
final String description = cardInfo.getCardDescription();
if (description != null) {
paymentMethodData.put("description", description);
}
// paymentMethodData -> tokenizationData
final PaymentMethodToken paymentMethodToken = paymentData.getPaymentMethodToken();
JSONObject tokenizationData = new JSONObject();
tokenizationData.put("type", paymentMethodToken.getPaymentMethodTokenizationType());
tokenizationData.put("token", paymentMethodToken.getToken());
paymentMethodData.put("tokenizationData", tokenizationData);
// paymentMethodData -> info
JSONObject info = new JSONObject();
paymentMethodData.put("info", info);
// paymentMethodData -> info -> cardNetwork
final String cardNetwork = cardInfo.getCardNetwork();
if (cardNetwork != null) {
info.put("cardNetwork", cardNetwork);
}
// paymentMethodData -> info -> cardDetails
final String cardDetails = cardInfo.getCardDetails();
if (cardDetails != null) {
info.put("cardDetails", cardDetails);
}
// paymentMethodData -> info -> cardClass (1-3 or 0, should somehow translate to DEBIT/CREDIT)
final int cardClassCode = cardInfo.getCardClass();
String cardClass = null;
if (cardClassCode == WalletConstants.CARD_CLASS_CREDIT) {
cardClass = "CREDIT";
} else if (cardClassCode == WalletConstants.CARD_CLASS_DEBIT) {
cardClass = "DEBIT";
} else if (cardClassCode == WalletConstants.CARD_CLASS_PREPAID) {
cardClass = "PREPAID";
}
if (cardClass != null) {
info.put("cardClass", cardClass);
}
// paymentMethodData -> info -> billingAddress
final JSONObject billingAddressJson = getUserAddressAsJson(cardInfo.getBillingAddress());
if (billingAddressJson != null) {
info.put("billingAddress", billingAddressJson);
}
result.put("paymentMethodData", paymentMethodData);
// email
final String email = paymentData.getEmail();
if (email != null) {
result.put("email", email);
}
// googleTransactionId
final String googleTransactionId = paymentData.getGoogleTransactionId();
if (googleTransactionId != null) {
result.put("googleTransactionId", googleTransactionId);
}
// shippingAddress
final JSONObject shippingAddressJson = getUserAddressAsJson(paymentData.getShippingAddress());
if (shippingAddressJson != null) {
result.put("shippingAddress", shippingAddressJson);
}
String tokenForBls = result.toString();
String encodedToken = Base64.encodeToString(tokenForBls.getBytes(), Base64.NO_WRAP | Base64.URL_SAFE);
return encodedToken;
}
Your final JSON result
object (before base64 encoding) should look as follows:
{
"paymentMethodData": {
"description": "Visa •••• 7971",
"tokenizationData": {
"type": 1,
"token": "{\"signature\":\"MEUCIC+ewMPpwUxb6trZ/Xjy6CyEEzAF+8NHhHAW8XNXCjy0IiEAugWTqUrj4z+lvwydZLLF3RjW5R3Om7P+38epcgz91z0\\u003d\",\"protocolVersion\":\"ECv1\",\"signedMessage\":\"{\\\"encryptedMessage\\\":\\\"oBAUIqpOq5q22WAFnxcTfkm4PuyQDxJS2RjyAu6Ey5UhRhXFhxSZUaWZAiZZ8CiLDEcZemNxwFDsPeVApbhTxFMsrVJ3lEg1Ihlevk9Nd+tWGSCR2StztvmvX031p4USfw44oL187FrXa4O0mfjfwDie3UnjDKRb9tyGSXmi+KfzEVwotu8oJBGeaYF/LGzWXTcyWxT65ae3w5twInJ2DnWq6umBQOfn0BUhGEFhppuWoxfsesNN06N239rCnHfkMoODUWBqbY26C3Ol0tVVE882HSJ6t9Pa7klTzB2hm9wTO0oyt1dffhe49eS8kAPuQVZYiBDawC5wNTa+Vv7uzpCaS1E7WnQqzSbTqLUHEs9vNalWSUg5/a2slkKPlW5F6uXYQAJeo3Qp0Kf7Q5huugUfgxKGpuGDBfjuBVOZzoVsqAOTbPemhmwidhcVQttN7cl+qzgjGnfrre4wRKBddTex9czb4JdUZzqh5FUREsBX8xS/TNkMOmHhgbWKTtmAMrQQg0Ow45vyWoRQkhBoFZWYXsazxvj1lefLEDjEJ6Vp5344PqU5kdjEMXgKBj44lor9KkX/xLnD\\\",\\\"ephemeralPublicKey\\\":\\\"BOXV41QR66gVpchvo6AuCVKSpMSDvbZ81HsuosmRCub7swGnYWS1H9xsyjtsiEYUKH65dCKgeS8IWE+0Mervkmk\\\\u003d\\\",\\\"tag\\\":\\\"Dh4NKt7Megxi+NYy+iumFxxxCLoTfFZTG4qAOjwKADI\\\\u003d\\\"}\"}"
},
"info": {
"cardNetwork": "VISA",
"cardDetails": "7971",
"cardClass": "CREDIT",
"billingAddress": {
"name": "John Doe",
"postalCode": "02186",
"countryCode": "US",
"phoneNumber": "+1 617-555-1234",
"companyName": "",
"emailAddress": "[email protected]",
"address1": "123 Main Street",
"administrativeArea": "MA",
"locality": "Waltham",
"sortingCode": ""
}
}
},
"email": "[email protected]",
"googleTransactionId": "a06be4b5-888b-4988-a848-84b9b492e150.PROD",
"shippingAddress": {
"name": "John Doe",
"postalCode": "02186",
"countryCode": "US",
"phoneNumber": "+1 617-555-1234",
"companyName": "",
"emailAddress": "[email protected]",
"address1": "123 Main St",
"administrativeArea": "MA",
"locality": "Waltham",
"sortingCode": ""
}
}
Note
This
paymentToken
should be sent to the BlueSnap API, which is detailed in the Processing Transactions section.
Testing in Sandbox
Google Pay does not provide test cards; however, you can use a “live” card within Google’s test environment. In the test environment, Google Pay returns a dummy token that can't be charged.
Notes
- Sandbox supports Google Pay tokens produced by either setting (TEST or PRODUCTION), but BlueSnap's Production environment only supports PRODUCTION Google tokens.
- While the Google Pay API is available in many markets, tokenized cards are only available in a subset of countries and only on compatible Android devices. Refer to Google’s integration guide before testing tokenized cards.
Processing Transactions
This section covers how to send the payment token data to BlueSnap to process the transaction using the Payment API (either JSON or XML).
Processing transactions with the Payment API
Step 1: Validate that the Google Pay payment method is activated
You can validate if the Google Pay payment method is activated by viewing the setting in the BlueSnap Merchant Portal (Google Pay is activated by default).
In the Merchant Portal, access the Methods of payment settings box and check if the Google Pay option is set to Show:
Step 2: Process transactions with the Payment API
The payment token data is sent with the encodedPaymentToken
property in the request.
Note
The Google Pay token might result in a regular Credit Card or a Tokenized Card (when the card is added to the Google Pay app and shoppers complete the purchase). The API requests are the same in either case, but the responses might vary.
Scenario 1: Shopper is new
For sales involving new shoppers, you must include the encodedPaymentToken
property in an Auth Only, Auth Capture, or Create Subscription request.
encodedPaymentToken
for JSONencoded-payment-token
for XML
curl -v -X POST https://sandbox.bluesnap.com/services/2/transactions \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=' \
-d '
{
"cardTransactionType": "AUTH_CAPTURE",
"softDescriptor": "DescTest",
"amount": 11.00,
"currency": "USD",
"wallet": {
"walletType": "GOOGLE_PAY",
"encodedPaymentToken": "ImRhdGEiOiJuY1AvRitIUy8zeG5bXhCMFd"
}
}
curl -v -X POST https://sandbox.bluesnap.com/services/2/transactions \
-H 'Content-Type: application/xml' \
-H 'Accept: application/xml' \
-H 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=' \
-d '
<card-transaction xmlns="http://ws.plimus.com">
<card-transaction-type>AUTH_CAPTURE</card-transaction-type>
<soft-descriptor>DescTest</soft-descriptor>
<amount>11.00</amount>
<currency>USD</currency>
<wallet>
<wallet-type>GOOGLE_PAY</wallet-type>
<encoded-payment-token>ImRhdGEiOiJuY1AvRitIUy8zeG5bXhCMFd</encoded-payment-token>
</wallet>
</card-transaction>
Scenario 2: Shopper is returning
For sales involving returning shoppers, you must include the shopper's vaultedShopperId
and encodedPaymentToken
property in an Auth Only, Auth Capture, or Create Subscription request.
curl -v -X POST https://sandbox.bluesnap.com/services/2/transactions \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=' \
-d '
{
"cardTransactionType": "AUTH_CAPTURE",
"softDescriptor": "DescTest",
"amount": 11.00,
"currency": "USD",
"vaultedShopperId": 1234,
"wallet": {
"walletType": "GOOGLE_PAY",
"encodedPaymentToken": "ImRhdGEiOiJuY1AvRitIUy8zeG5bXhCMFd"
}
}
curl -v -X POST https://sandbox.bluesnap.com/services/2/transactions \
-H 'Content-Type: application/xml' \
-H 'Accept: application/xml' \
-H 'Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=' \
-d '
<card-transaction xmlns="http://ws.plimus.com">
<card-transaction-type>AUTH_CAPTURE</card-transaction-type>
<soft-descriptor>DescTest</soft-descriptor>
<amount>11.00</amount>
<currency>USD</currency>
<vaulted-shopper-id>1234</vaulted-shopper-id>
<wallet>
<wallet-type>GOOGLE_PAY</wallet-type>
<encoded-payment-token>ImRhdGEiOiJuY1AvRitIUy8zeG5bXhCMFd</encoded-payment-token>
</wallet>
</card-transaction>
For more information on these, refer to the following:
Working with subscriptions?