Usare Google Pay come metodo di pagamento

Google Pay è un metodo per effettuare pagamenti sui siti web e nei negozi che utilizzano questo sistema di salvataggio di diverse carte di credito in un unico account.

Si tratta di un sistema che fornisce sicurezza durante le transazioni online e che permette di salvare biglietti di eventi convenzionati e ricevere premi sponsorizzati Google.

Carte e metodi di pagamento accettati

A livello di compatibilità e partner Google Pay ne conta abbastanza da poter considerare questo sistema come accettato a livello Italiano. Esiste anche un elenco di carte supportate da poter consultare in una comoda pagina.

E’ chiaro che i metodi accettati sono inerenti al mondo delle carte di credito e non alle carte di debito, come la Postepay.

Pagamenti in negozio

Esiste la possibilità di utilizzare la carta in tutti i negozi che espongono il logo Google Pay, all’interno dei quali sarà possibile avvicinare il terminale al proprio cellulare e dopo aver aperto la app sarà effettuato la transazione automaticamente, senza bisogno di compiere nessuna operazione.

Il principale vantaggio di questo strumento è che la mancanza di un database online accessibile da un sito migliora la sicurezza del metodo di pagamento.

Come utilizzare la app

Si tratta di uno strumento molto semplice, realizzato come un contenitore (che mette in sicurezza) delle carte di credito o dei conti bancari che si connettono. Bisogna dunque registrare la carta all’interno del tool per poterla operare tranquillamente.

Al termine della registrazione verrà verificata l’identità dell’utilizzatore, tramite il numero di telefono associato alle sue operazioni.

Per maggiori informazioni basta visitare la pagina delle informazioni riguardanti l’utilizzo di Google Pay.

Implementare Google Play sul web e sulle app

Quale che sia la piattaforma su cui applicare Google Pay il suo funzionamento si basa su questo schema:

  1. L’utente clicca sul pulsante per il pagamento e viene visualizzata una pagina nel browser che contiene tutti i metodi di pagamento utilizzabili.
  2. Si seleziona un metodo di pagamento e Google Pay restituisce un token di pagamento che garantisce la sicurezza dell’operazione.
  3. L’app invia il token di pagamento e i dettagli dell’acquisto, al backend di Google.
  4. Il pagamento viene eseguito tramite il backend, che verifica l’acquisto e invia il token di pagamento all’azienda / banca che ha fornito il servizio di pagamento (quello che è stato scelto dall’utente).

Il sistema viene supportato da diversi servizi di pagamento e richiede l’accesso alla produzione tramite il completamento di diverse operazioni da sviluppare nella Console di Google Pay.

Le operazione da compiere per implementare il codice passano da quattro step:

  • inserire la libreria Javascript di Google Pay sulla piattaforma che utilizzerà questa forma di pagamento;
  • implementare le API ReadyToPay() per comunicare con i browser su cui andremo a utilizzare lo strumento;
  • a questo punto sarà necessario rendere visibile il bottone di pagamento, tramite l’API createButton();
  • infine sarà necessario fornire tutte le informazioni sul pagamento da effettuare tramite l’oggetto loadPaymentData().

Implementare il codice sul sito

Le istruzioni per far funzionare il bottone con le informazioni sul pagamento presenti all’interno è semplice, basta eseguire due operazioni:

  • inserire uno script sulle pagine del sito per richiamare le funzioni del bottone di Google Pay;
  • configurare il file Javascript con le API connesso al codice del sito;

Lo script da inserire nelle pagine è molto semplice da inserire, si tratta di poche righe di codice da inserire nella pagina dove si preferisce;


Il prossimo passaggio è quello di generare, seguendo il tutorial e la checklist per le integrazioni, un file contenente le istruzioni per poter generare il pulsante contenente i metodi di pagamento accettato, eventuali costi di spedizioni e informazioni aggiuntive.

Il codice che trovi qui sotto è in Javascript, ma puoi trovare tutte le varianti qui.

/**
 * Define the version of the Google Pay API referenced when creating your
 * configuration
 *
 * @see {@link https://developers.google.com/pay/api/web/reference/request-objects#PaymentDataRequest|apiVersion in PaymentDataRequest}
 */
const baseRequest = {
  apiVersion: 2,
  apiVersionMinor: 0
};

/**
 * Card networks supported by your site and your gateway
 *
 * @see {@link https://developers.google.com/pay/api/web/reference/request-objects#CardParameters|CardParameters}
 * @todo confirm card networks supported by your site and gateway
 */
const allowedCardNetworks = ["MASTERCARD", "VISA"];

/**
 * Card authentication methods supported by your site and your gateway
 *
 * @see {@link https://developers.google.com/pay/api/web/reference/request-objects#CardParameters|CardParameters}
 * @todo confirm your processor supports Android device tokens for your
 * supported card networks
 */
const allowedCardAuthMethods = ["PAN_ONLY", "CRYPTOGRAM_3DS"];

/**
 * Identify your gateway and your site's gateway merchant identifier
 *
 * The Google Pay API response will return an encrypted payment method capable
 * of being charged by a supported gateway after payer authorization
 *
 * @todo check with your gateway on the parameters to pass
 * @see {@link https://developers.google.com/pay/api/web/reference/request-objects#gateway|PaymentMethodTokenizationSpecification}
 */
const tokenizationSpecification = {
  type: 'PAYMENT_GATEWAY',
  parameters: {
    'gateway': 'example',
    'gatewayMerchantId': 'exampleGatewayMerchantId'
  }
};

/**
 * Describe your site's support for the CARD payment method and its required
 * fields
 *
 * @see {@link https://developers.google.com/pay/api/web/reference/request-objects#CardParameters|CardParameters}
 */
const baseCardPaymentMethod = {
  type: 'CARD',
  parameters: {
    allowedAuthMethods: allowedCardAuthMethods,
    allowedCardNetworks: allowedCardNetworks
  }
};

/**
 * Describe your site's support for the CARD payment method including optional
 * fields
 *
 * @see {@link https://developers.google.com/pay/api/web/reference/request-objects#CardParameters|CardParameters}
 */
const cardPaymentMethod = Object.assign(
  {},
  baseCardPaymentMethod,
  {
    tokenizationSpecification: tokenizationSpecification
  }
);

/**
 * An initialized google.payments.api.PaymentsClient object or null if not yet set
 *
 * @see {@link getGooglePaymentsClient}
 */
let paymentsClient = null;

/**
 * Configure your site's support for payment methods supported by the Google Pay
 * API.
 *
 * Each member of allowedPaymentMethods should contain only the required fields,
 * allowing reuse of this base request when determining a viewer's ability
 * to pay and later requesting a supported payment method
 *
 * @returns {object} Google Pay API version, payment methods supported by the site
 */
function getGoogleIsReadyToPayRequest() {
  return Object.assign(
      {},
      baseRequest,
      {
        allowedPaymentMethods: [baseCardPaymentMethod]
      }
  );
}

/**
 * Configure support for the Google Pay API
 *
 * @see {@link https://developers.google.com/pay/api/web/reference/request-objects#PaymentDataRequest|PaymentDataRequest}
 * @returns {object} PaymentDataRequest fields
 */
function getGooglePaymentDataRequest() {
  const paymentDataRequest = Object.assign({}, baseRequest);
  paymentDataRequest.allowedPaymentMethods = [cardPaymentMethod];
  paymentDataRequest.transactionInfo = getGoogleTransactionInfo();
  paymentDataRequest.merchantInfo = {
    // @todo a merchant ID is available for a production environment after approval by Google
    // See {@link https://developers.google.com/pay/api/web/guides/test-and-deploy/integration-checklist|Integration checklist}
    // merchantId: '01234567890123456789',
    merchantName: 'Example Merchant'
  };

  paymentDataRequest.callbackIntents = ["PAYMENT_AUTHORIZATION"];

  return paymentDataRequest;
}

/**
 * Return an active PaymentsClient or initialize
 *
 * @see {@link https://developers.google.com/pay/api/web/reference/client#PaymentsClient|PaymentsClient constructor}
 * @returns {google.payments.api.PaymentsClient} Google Pay API client
 */
function getGooglePaymentsClient() {
  if ( paymentsClient === null ) {
    paymentsClient = new google.payments.api.PaymentsClient({
        environment: 'TEST',
      paymentDataCallbacks: {
        onPaymentAuthorized: onPaymentAuthorized
      }
    });
  }
  return paymentsClient;
}

/**
 * Handles authorize payments callback intents.
 *
 * @param {object} paymentData response from Google Pay API after a payer approves payment through user gesture.
 * @see {@link https://developers.google.com/pay/api/web/reference/response-objects#PaymentData object reference}
 *
 * @see {@link https://developers.google.com/pay/api/web/reference/response-objects#PaymentAuthorizationResult}
 * @returns Promise Promise of PaymentAuthorizationResult object to acknowledge the payment authorization status.
 */
function onPaymentAuthorized(paymentData) {
  return new Promise(function(resolve, reject){
    // handle the response
    processPayment(paymentData)
      .then(function() {
        resolve({transactionState: 'SUCCESS'});
      })
      .catch(function() {
        resolve({
          transactionState: 'ERROR',
          error: {
            intent: 'PAYMENT_AUTHORIZATION',
            message: 'Insufficient funds, try again. Next attempt should work.',
            reason: 'PAYMENT_DATA_INVALID'
          }
        });
            });
  });
}

/**
 * Initialize Google PaymentsClient after Google-hosted JavaScript has loaded
 *
 * Display a Google Pay payment button after confirmation of the viewer's
 * ability to pay.
 */
function onGooglePayLoaded() {
  const paymentsClient = getGooglePaymentsClient();
  paymentsClient.isReadyToPay(getGoogleIsReadyToPayRequest())
    .then(function(response) {
      if (response.result) {
        addGooglePayButton();
      }
    })
    .catch(function(err) {
      // show error in developer console for debugging
      console.error(err);
    });
}

/**
 * Add a Google Pay purchase button alongside an existing checkout button
 *
 * @see {@link https://developers.google.com/pay/api/web/reference/request-objects#ButtonOptions|Button options}
 * @see {@link https://developers.google.com/pay/api/web/guides/brand-guidelines|Google Pay brand guidelines}
 */
function addGooglePayButton() {
  const paymentsClient = getGooglePaymentsClient();
  const button =
      paymentsClient.createButton({onClick: onGooglePaymentButtonClicked});
  document.getElementById('container').appendChild(button);
}

/**
 * Provide Google Pay API with a payment amount, currency, and amount status
 *
 * @see {@link https://developers.google.com/pay/api/web/reference/request-objects#TransactionInfo|TransactionInfo}
 * @returns {object} transaction info, suitable for use as transactionInfo property of PaymentDataRequest
 */
function getGoogleTransactionInfo() {
  return {
        displayItems: [
        {
          label: "Subtotal",
          type: "SUBTOTAL",
          price: "1.00",
        },
      {
          label: "Tax",
          type: "TAX",
          price: "0.00",
        }
    ],
    countryCode: 'IT',
    currencyCode: "EUR",
    totalPriceStatus: "FINAL",
    totalPrice: "1.00",
    totalPriceLabel: "Total"
  };
}


/**
 * Show Google Pay payment sheet when Google Pay payment button is clicked
 */
function onGooglePaymentButtonClicked() {
  const paymentDataRequest = getGooglePaymentDataRequest();
  paymentDataRequest.transactionInfo = getGoogleTransactionInfo();

  const paymentsClient = getGooglePaymentsClient();
  paymentsClient.loadPaymentData(paymentDataRequest);
}

let attempts = 0;
/**
 * Process payment data returned by the Google Pay API
 *
 * @param {object} paymentData response from Google Pay API after user approves payment
 * @see {@link https://developers.google.com/pay/api/web/reference/response-objects#PaymentData|PaymentData object reference}
 */
function processPayment(paymentData) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      // @todo pass payment token to your gateway to process payment
      paymentToken = paymentData.paymentMethodData.tokenizationData.token;

                        if (attempts++ % 2 == 0) {
              reject(new Error('Every other attempt fails, next one should succeed'));      
      } else {
              resolve({});      
      }
    }, 500);
  });
}

Il codice presente è un esempio, come si nota dalla scelta di segnare environment: ‘TEST’, mentre nel caso si volesse rendere effettivo si dovrebbe modificare il campo inserendo PRODUCTION come voce sostitutiva.

Per effettuare l’integrazione all’interno del proprio sito o della propria app è necessario completare la registrazione nel pannello interno.