Google Pay
Last updated: Jul 30th, 4:03pm
Overview
This integration enables merchants to accept Google Pay payments through PayPal's infrastructure, combining Google Pay's streamlined UX with PayPal's robust payment processing. The implementation uses PayPal's v6 Web SDK to create a seamless checkout experience.
PayPal Developer Account Setup
1. Create PayPal Developer Account
- Navigate to PayPal Developer Dashboard
- Create a new sandbox application - Note your Client ID and Client Secret.
2. Enable Google Pay in Sandbox
⚠️ Critical Step: Google Pay must be explicitly enabled in your PayPal sandbox account before integration.
Follow the PayPal Google Pay setup documentation to configure your sandbox account.
1. HTML foundation
1. HTML foundation
1<!DOCTYPE html>2<html lang="en">3<head>4 <meta charset="UTF-8">5 <meta name="viewport" content="width=device-width, initial-scale=1.0">6 <title>Google Pay Integration - PayPal</title>7</head>8<body>9 <div class="checkout-container">10 <h1>Secure Checkout</h1>11 <div id="googlepay-button-container"></div>12 </div>1314 <!-- Load Google Pay SDK first -->15 <script src="https://pay.google.com/gp/p/js/pay.js"></script>1617 <!-- Load PayPal SDK with onload callback -->18 <script19 async20 src="https://www.sandbox.paypal.com/web-sdk/v6/core"21 onload="initializePayPalSDK()">22 </script>2324 <script src="app.js"></script>25</body>26</html>
2. PayPal SDK Initialization
2. PayPal SDK Initialization
1async function initializePayPalSDK() {2 try {3 // Obtain secure client token from your server4 const clientToken = await fetchClientToken();56 // Create PayPal SDK instance with Google Pay support7 const paypalSDK = await window.paypal.createInstance({8 clientToken: clientToken,9 components: ["googlepay-payments"],10 pageType: "checkout"11 });1213 await setupGooglePayButton(paypalSDK);14 } catch (error) {15 console.error("PayPal SDK initialization failed:", error);16 handleInitializationError(error);17 }18}
5. Payment Flow Initiation
Payment Flow Initiation
1async function initiateGooglePayFlow(googlePayClient, googlePayConfig, purchaseAmount) {2 try {3 const paymentDataRequest = buildPaymentDataRequest(purchaseAmount, googlePayConfig);4 await googlePayClient.loadPaymentData(paymentDataRequest);5 } catch (error) {6 if (error.statusCode === 'CANCELED') {7 console.log('User canceled Google Pay');8 } else {9 console.error('Google Pay error:', error);10 }11 }12}
6. Payment Data Request Structure
6. Payment Data Request Structure
1function buildPaymentDataRequest(purchaseAmount, googlePayConfig) {2 const {3 allowedPaymentMethods,4 merchantInfo,5 apiVersion,6 apiVersionMinor,7 countryCode8 } = googlePayConfig;910 return {11 apiVersion,12 apiVersionMinor,13 allowedPaymentMethods,14 merchantInfo,15 transactionInfo: buildTransactionInfo(purchaseAmount, countryCode),16 callbackIntents: ["PAYMENT_AUTHORIZATION"]17 };18}1920function buildTransactionInfo(purchaseAmount, countryCode) {21 const total = parseFloat(purchaseAmount);22 const subtotal = (total * 0.9).toFixed(2);23 const tax = (total * 0.1).toFixed(2);2425 return {26 displayItems: [27 {28 label: "Subtotal",29 type: "SUBTOTAL",30 price: subtotal31 },32 {33 label: "Tax",34 type: "TAX",35 price: tax36 }37 ],38 countryCode,39 currencyCode: "USD",40 totalPriceStatus: "FINAL",41 totalPrice: purchaseAmount,42 totalPriceLabel: "Total"43 };44}
8. PayPal Order Configuration
8. PayPal Order Configuration
1function buildPayPalOrder(purchaseAmount) {2 return {3 intent: "CAPTURE",4 purchase_units: [{5 amount: {6 currency_code: "USD",7 value: purchaseAmount,8 breakdown: {9 item_total: {10 currency_code: "USD",11 value: purchaseAmount12 }13 }14 }15 }],16 payment_source: {17 google_pay: {18 attributes: {19 verification: {20 method: "SCA_WHEN_REQUIRED"21 }22 }23 }24 }25 };26}
Server-side integration
Server-side integration
1. Client Token Endpoint
1. Client Token Endpoint
1app.get('/api/paypal/client-token', async (req, res) => {2 try {3 const accessToken = await getPayPalAccessToken();45 const response = await fetch(`${PAYPAL_API_BASE}/v1/oauth2/token`, {6 method: 'POST',7 headers: {8 'Authorization': `Bearer ${accessToken}`,9 'Content-Type': 'application/json'10 }11 });1213 const data = await response.json();14 res.json({ clientToken: data.access_token });15 } catch (error) {16 res.status(500).json({ error: 'Failed to generate client token' });17 }18});
2. Order Creation Endpoint
2. Order Creation Endpoint
1app.post('/api/paypal/orders', async (req, res) => {2 try {3 const accessToken = await getPayPalAccessToken();45 const response = await fetch(`${PAYPAL_API_BASE}/v2/checkout/orders`, {6 method: 'POST',7 headers: {8 'Authorization': `Bearer ${accessToken}`,9 'Content-Type': 'application/json'10 },11 body: JSON.stringify(req.body)12 });1314 const orderData = await response.json();15 res.json({ id: orderData.id });16 } catch (error) {17 res.status(500).json({ error: 'Order creation failed' });18 }19});
3. Order Capture Endpoint
3. Order Capture Endpoint
1app.post('/api/paypal/orders/:orderId/capture', async (req, res) => {2 try {3 const { orderId } = req.params;4 const accessToken = await getPayPalAccessToken();56 const response = await fetch(`${PAYPAL_API_BASE}/v2/checkout/orders/${orderId}/capture`, {7 method: 'POST',8 headers: {9 'Authorization': `Bearer ${accessToken}`,10 'Content-Type': 'application/json'11 }12 });1314 const captureData = await response.json();15 res.json(captureData);16 } catch (error) {17 res.status(500).json({ error: 'Order capture failed' });18 }19});