Skip to main content
Google Pay enables merchants to accept fast payments in using PayPal’s Javascript SDK v6. This integration supports setup in test and production environments and provides a streamlined checkout experience for customers.

Prerequisites

Before beginning your integration, meet these requirements:
Note: You’ll use your sandbox credentials to create a .env file during the Development setup.

Development setup

Configure your local development environment with the required dependencies and credentials.
  1. Install project dependencies:
cd client/components/googlePayPayments/oneTimePayment/html
npm install
  1. Create environment configuration:
# .env file
PAYPAL_SANDBOX_CLIENT_ID=your_client_id
PAYPAL_SANDBOX_CLIENT_SECRET=your_client_secret
  1. Start the development server:
npm start
To load the application, see http://localhost:3000.

Implementation steps

Implement Google Pay by following the detailed steps.

Step 1: HTML structure setup

Create your basic HTML page and include the Google Pay and PayPal SDK scripts.
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>One-Time Payment - Google Pay - PayPal JavaScript SDK</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body>
    <h1>One-Time Payment Google Pay Integration</h1>
    
    <div class="buttons-container">
      <div id="googlepay-button-container"></div>
    </div>

    <!-- Load Google Pay SDK -->
    <script src="https://pay.google.com/gp/p/js/pay.js"></script>
    <script src="app.js"></script>

    <!-- Load PayPal SDK -->
    <script
      async
      src="https://www.sandbox.paypal.com/web-sdk/v6/core"
      onload="onPayPalWebSdkLoaded()"
    ></script>
  </body>
</html>

Step 2: Initialize PayPal SDK

Set up the PayPal SDK with Google Pay components once it loads.
async function onPayPalWebSdkLoaded() {
  try {
    // Get client token for authentication
    const clientToken = await getBrowserSafeClientToken();
    
    // Create PayPal SDK instance with Google Pay component
    const sdkInstance = await window.paypal.createInstance({
      clientToken,
      components: ["googlepay-payments"],
      pageType: "checkout",
    });

    setupGooglePayButton(sdkInstance);
  } catch (error) {
    console.error(error);
  }
}

Step 3: Configure Google Pay button

Create the Google Pay session and set up the payment button.
async function setupGooglePayButton(sdkInstance) {
  // Create Google Pay session
  const googlePaySession = sdkInstance.createGooglePayOneTimePaymentSession();
  const purchaseAmount = "10.00";

  try {
    // Initialize Google Pay client
    const paymentsClient = new google.payments.api.PaymentsClient({
      environment: "TEST", // Use "PRODUCTION" for live transactions
      paymentDataCallbacks: {
        onPaymentAuthorized: (paymentData) =>
          onPaymentAuthorized(purchaseAmount, paymentData, googlePaySession),
      },
    });

    // Get Google Pay configuration from PayPal
    const googlePayConfig = await googlePaySession.getGooglePayConfig();

    // Check if Google Pay is available
    const isReadyToPay = await paymentsClient.isReadyToPay({
      allowedPaymentMethods: googlePayConfig.allowedPaymentMethods,
      apiVersion: googlePayConfig.apiVersion,
      apiVersionMinor: googlePayConfig.apiVersionMinor,
    });

    if (isReadyToPay.result) {
      // Create and append Google Pay button
      const button = paymentsClient.createButton({
        onClick: () =>
          onGooglePayButtonClick(
            purchaseAmount,
            paymentsClient,
            googlePayConfig,
          ),
      });

      document.getElementById("googlepay-button-container").appendChild(button);
    }
  } catch (error) {
    console.error("Setup error:", error);
  }
}

Step 4: Configure payment data request

Set up the Google Pay payment data request with transaction details.
async function getGooglePaymentDataRequest(purchaseAmount, googlePayConfig) {
  const {
    allowedPaymentMethods,
    merchantInfo,
    apiVersion,
    apiVersionMinor,
    countryCode,
  } = googlePayConfig;

  const baseRequest = {
    apiVersion,
    apiVersionMinor,
  };

  const paymentDataRequest = Object.assign({}, baseRequest);
  paymentDataRequest.allowedPaymentMethods = allowedPaymentMethods;
  paymentDataRequest.transactionInfo = getGoogleTransactionInfo(
    purchaseAmount,
    countryCode,
  );
  paymentDataRequest.merchantInfo = merchantInfo;
  paymentDataRequest.callbackIntents = ["PAYMENT_AUTHORIZATION"];

  return paymentDataRequest;
}

Step 5: Set up transaction information

Define the transaction details and pricing breakdown for the Google Pay request.
function getGoogleTransactionInfo(purchaseAmount, countryCode) {
  const totalAmount = parseFloat(purchaseAmount);
  const subtotal = (totalAmount * 0.9).toFixed(2);
  const tax = (totalAmount * 0.1).toFixed(2);

  return {
    displayItems: [
      {
        label: "Subtotal",
        type: "SUBTOTAL",
        price: subtotal,
      },
      {
        label: "Tax",
        type: "TAX",
        price: tax,
      },
    ],
    countryCode: countryCode,
    currencyCode: "USD",
    totalPriceStatus: "FINAL",
    totalPrice: purchaseAmount,
    totalPriceLabel: "Total",
  };
}

Step 6: Handle payment authorization

Process the payment authorization and complete the transaction.
async function onPaymentAuthorized(
  purchaseAmount,
  paymentData,
  googlePaySession,
) {
  try {
    // Create PayPal order payload
    const orderPayload = getPayPalOrderPayload(purchaseAmount);
    const id = await createOrder(orderPayload);

    // Confirm order with Google Pay payment data
    const { status } = await googlePaySession.confirmOrder({
      orderId: id,
      paymentMethodData: paymentData.paymentMethodData,
    });

    if (status !== "PAYER_ACTION_REQUIRED") {
      // Capture the order
      const orderData = await captureOrder({ orderId: id });
      console.log(JSON.stringify(orderData, null, 2));
    }

    return { transactionState: "SUCCESS" };
  } catch (err) {
    console.error("Payment authorization error:", err);
    return {
      transactionState: "ERROR",
      error: {
        message: err.message,
      },
    };
  }
}

Step 7: PayPal order configuration

Configure a PayPal order with the Google Pay payment source.
function getPayPalOrderPayload(purchaseAmount) {
  return {
    intent: "CAPTURE",
    purchaseUnits: [
      {
        amount: {
          currencyCode: "USD",
          value: purchaseAmount,
          breakdown: {
            itemTotal: {
              currencyCode: "USD",
              value: purchaseAmount,
            },
          },
        },
      },
    ],
    paymentSource: {
      googlePay: {
        attributes: {
          verification: {
            method: "SCA_WHEN_REQUIRED",
          },
        },
      },
    },
  };
}

API endpoints

The integration requires these server-side endpoints.

Client token endpoint

// GET /paypal-api/auth/browser-safe-client-token
async function getBrowserSafeClientToken() {
  const response = await fetch("/paypal-api/auth/browser-safe-client-token", {
    method: "GET",
    headers: {
      "Content-Type": "application/json",
    },
  });
  const { accessToken } = await response.json();
  return accessToken;
}

Create order endpoint

// POST /paypal-api/checkout/orders/create
async function createOrder(orderPayload) {
  const response = await fetch("/paypal-api/checkout/orders/create", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(orderPayload),
  });
  const { id } = await response.json();
  return id;
}

Capture order endpoint

// POST /paypal-api/checkout/orders/{orderId}/capture
async function captureOrder({ orderId }) {
  const response = await fetch(
    `/paypal-api/checkout/orders/${orderId}/capture`,
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
    },
  );
  const data = await response.json();
  return data;
}

Key components

Key componentPurposeDetails
PayPal SDK instanceMain entry point for PayPal functionality
  • Includes googlepay-payments component
  • Requires client token from server
Google Pay sessionManages Google Pay payment flow
  • Provides Google Pay–specific settings
  • Handles order confirmation and capture
Google Pay clientInterface with Google Pay API
  • Set to TEST for sandbox
  • Set to PRODUCTION for live
  • Handles payment authorization callbacks

Security considerations

  • Request client tokens from your server only.
  • Never expose client secrets in frontend code.
  • Always process payments through PayPal’s servers.
  • Use HTTPS in production.

Error handling

  • Catch and log errors in both client and server code.
  • Avoid logging sensitive data.
  • Show clear, user-friendly error messages.

Testing

  • Run transactions with different payment amounts.
  • Verify order creation and capture flows.
  • Simulate error scenarios and edge cases.

Next steps

  1. Configure your production credentials and endpoints.
  2. Add 3D Secure (3DS) support if required.
  3. Extend your integration to support multiple currencies.
  4. Strengthen error handling and customer messaging.
  5. Build a complete automated test suite.

Resources

I