Instant Account Funding - Google Pay
Overview
In addition to Instant Account Funding (PULL
from card) with an external card-on-file or with Apple Pay, Synctera offers Instant Account Funding with Google Pay using an external card that the user has added to their Google Wallet. Through this method, transactions are are securely processed with Google Pay’s encryption and authentication features, such as Face ID or Touch ID.
While this guide focuses on web implementation, the conceptual framework applies similarly to Android.
Prerequisites
To perform Instant Account Funding with Google Pay, you must first:
- Create a Customer
- Create an Account for the customer
- Have External Cards enabled with the help of your Synctera implementation representative
- Perform the necessary steps to enable payments through Google Pay:
- Setup your Google Pay environment
- Integrate with Google Pay to generate payment token:
- Present the Google Pay button in your app
- Present the payment sheet to the customer
- Receive payment token
Payment Flow
- User selects the Google Pay button
- Google Pay UI is displayed and user confirms payment
- Google Pay returns a payment token
- Your application sends the token to your server
- Your server requests a transaction with Synctera using the token
- Synctera’s payment gateway processes the transaction
- A response containing the transaction outcome is returned
See:
Set up your Google Pay environment
1. Set up a Google Pay merchant account
To enable account funding through Google Pay, you need to set up Google Pay for Business. Please follow these instructions.
A Google Pay merchant account is not required for
TEST
environment
Integrate with Google Pay to generate payment token
1. Include the Google Pay API JavaScript
<script src="<https://pay.google.com/gp/p/js/pay.js>"></script>
2. Define payment configuration
const baseRequest = {
apiVersion: 2,
apiVersionMinor: 0
};
const allowedCardNetworks = [
"MASTERCARD",
"VISA"
];
const allowedCardAuthMethods = ["PAN_ONLY", "CRYPTOGRAM_3DS"];
const tokenizationSpecification = {
type: 'PAYMENT_GATEWAY',
parameters: {
'gateway': 'tabapay',
'gatewayMerchantId': '{{gateway merchant ID}}'
}
};
const baseCardPaymentMethod = {
type: 'CARD',
parameters: {
allowedAuthMethods: allowedCardAuthMethods,
allowedCardNetworks: allowedCardNetworks
}
};
const cardPaymentMethod = Object.assign(
{tokenizationSpecification: tokenizationSpecification},
baseCardPaymentMethod
);
const paymentRequest = Object.assign({}, baseRequest);
paymentRequest.allowedPaymentMethods = [cardPaymentMethod];
paymentRequest.transactionInfo = {
totalPriceStatus: 'FINAL',
totalPrice: '123.45',
currencyCode: 'USD',
countryCode: 'US'
};
paymentRequest.merchantInfo = {
merchantName: 'Example Merchant', // your merchant Name
merchantId: '12345678901234567890' // your Google merchant ID
};
allowedCardNetworks
: Specify VISA
and MASTERCARD
allowedCardAuthMethods
: Specify both PAN_ONLY
and CRYPTOGRAM_3DS
tokenizationSpecification
:
gateway
: Specifytabapay
gatewayMerchantID
: Obtain from your Synctera Implementation representative
3. Display the Google Pay button
const paymentsClient = new google.payments.api.PaymentsClient({
environment: 'TEST' // Use 'PRODUCTION' when going live
});
function checkGooglePayAvailability() {
const isReadyToPayRequest = Object.assign({}, baseRequest);
isReadyToPayRequest.allowedPaymentMethods = [baseCardPaymentMethod];
paymentsClient.isReadyToPay(isReadyToPayRequest)
.then(function(response) {
if (response.result) {
// Google Pay is available - display the button
createAndAddButton();
}
})
.catch(function(err) {
console.error("Google Pay availability check error:", err);
});
}
function createAndAddButton() {
const button = paymentsClient.createButton({
onClick: onGooglePayButtonClicked,
buttonColor: 'black', // 'black' or 'white'
buttonType: 'buy'
});
document.getElementById('googlePayButtonContainer').appendChild(button);
}
function onGooglePayButtonClicked() {
paymentsClient.loadPaymentData(paymentRequest)
.then(function(paymentData) {
// Process payment data
processPayment(paymentData);
})
.catch(function(err) {
console.error("Payment processing error:", err);
});
}
4. Process the Payment
function processPayment(paymentData) {
// Send the payment token to your server
// The payment token is in paymentData.paymentMethodData.tokenizationData.token
fetch('/your-payment-endpoint', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
paymentToken: paymentData.paymentMethodData.tokenizationData.token
})
})
.then(response => response.json())
.then(data => {
// Handle successful payment
console.log('Payment successful:', data);
displayPaymentSuccess();
})
.catch(error => {
// Handle payment errors
console.error('Payment failed:', error);
displayPaymentError();
});
}
When a user confirms payment through the Google Pay interface, your application receives an encrypted payment token containing the user's payment credentials. Your client-side code must transmit this token to your server, which then communicates to Synctera’s payment gateway. See next step.
Use the Google Pay payment token to initiate payment
Now that you have generated an Google Pay payment token through your app, your server may request an instant PULL
payment using the token. Synctera’s payment gateway will then process the payment, and return the outcome to your app.
Call Create Google Pay External Card Transfer
Example request:
curl \\
$baseurl/v1/external_cards/transfers/googlepay \\
-H "Authorization: Bearer $apikey" \\
-H 'Content-Type: application/json' \\
-d '
{
"type": "GOOGLE_PAY_PULL",
"originating_account_id": "{{account_id}}",
"customer_id": "{{customer_id}}",
"amount": 100,
"google_pay_payment_data": {
"api_version": 2,
"api_version_minor": 0,
"payment_method_data": {
"payment_type": "CARD",
"description": "Visa **** 1234",
"info": {
"card_details": "1234",
"assurance_details": {
"account_verified": true,
"cardholder_authenticated": true
},
"card_network": "VISA",
"billing_address": {
"name": "Name",
"postal_code": "12345",
"country_code": "US",
"phone_number": "555-555-5555",
"address_1": "123 Main St",
"address_2": "Apt 4B",
"address_3": "",
"locality": "Anytown",
"administrative_area": "CA",
"sorting_code": "12345"
}
},
"tokenization_data": {
"tokenization_type": "PAYMENT_GATEWAY",
"token": "{\\"signature\\":\\"MEUCIExS6cx4CagjV......"
}
}
}
}'
google_pay_payment_data
is populated from paymentData
received from Google. Note that the encrypted payment token (paymentData.paymentMethodData.tokenizationData.token
) must not be altered and passed exactly as is.
Example response:
{
"account_id": "41762865-46a8-4b02-a6c4-40f909ae5847",
"amount": 11,
"creation_time": "2025-02-26T21:41:21.163735Z",
"currency": "USD",
"customer_id": "453101fc-2f42-4aa6-bb84-2acdba064e5c",
"id": "16980c03-022b-4cf9-90f6-742271132a2a",
"last_updated_time": "2025-02-26T21:41:22.612429Z",
"merchant": {
"address": {
"address_line_1": "123 Elm St",
"city": "San Diego",
"country_code": "US",
"postal_code": "92101",
"state": "CA"
},
"email": "[email protected]",
"name": "My Fintech",
"phone_number": "+18582281234"
},
"status": "SUCCEEDED",
"tenant": "lxpzvp_doyjzy",
"transaction_id": "0edc0511-ed8d-4bef-83dd-aea8901aa51f",
"card_details": {
"address_verification_result": "VERIFIED",
"cvv2_result": "NOT_SUPPORTED",
"name_verification_result": "NOT_VERIFIED",
"pull_details": {
"country": "US",
"currency": "USD",
"network": "Visa",
"product_type": "CREDIT",
"regulated": true
},
"pull_enabled": true,
"push_details": {
"country": "US",
"currency": "USD",
"funds_availability": "NOW",
"network": "Visa",
"product_type": "CREDIT",
"regulated": true
},
"push_enabled": true,
"bin": "411111",
"issuer": "FORD Instiution",
"last_four": "1111",
"payment_account_reference": "V0010013022073812195104907179"
},
"type": "GOOGLE_PAY_PULL"
}
The status
field of the response indicates the outcome of the transaction:
SUCCEEDED
: The transaction was successful and funds are available - terminal statusDECLINED
: The transaction could not be completed due to a specific rule (e.g. low balance or velocity control) - terminal statusCANCELED
: The transaction could not be completed due to error (e.g. upstream processing error) - terminal statusUNKNOWN
: The transaction status is indeterminate - non-terminal statusPENDING
: The transaction has been initialized - non-terminal status
Sandbox Testing
- Use the
TEST
environment for development - Google provides test cards for different scenarios
Updated about 16 hours ago