Cómo manejar información de pago opcional con un service worker

Cómo adaptar tu app de pagos web a los pagos web y brindar una mejor experiencia del usuario a los clientes

Una vez que una app de pagos basada en la Web recibe una solicitud de pago y, luego, inicia una transacción de pago, el trabajador de servicio actúa como el centro de comunicación entre el comercio y la app de pagos. En esta publicación, se explica cómo una app de pagos puede pasar información sobre la forma de pago, la dirección de envío o la información de contacto al comercio mediante un trabajador de servicio.

Cómo controlar la información de pago opcional con un service worker
Cómo controlar la información de pago opcional con un trabajador de servicio

Informa al comercio sobre un cambio de forma de pago

Las apps de pago pueden admitir varios instrumentos de pago con diferentes formas de pago.

Cliente Forma de pago Instrumento de pago
A Emisor de la tarjeta de crédito 1 ****1234
Emisor de la tarjeta de crédito 1 ****4242
Banco X ******123
B Emisor de la tarjeta de crédito 2 ****5678
Banco X ******456

Por ejemplo, en la tabla anterior, la billetera web del cliente A tiene dos tarjetas de crédito y una cuenta bancaria registradas. En este caso, la app controla tres instrumentos de pago (****1234, ****4242 y ******123) y dos formas de pago (emisor de la tarjeta de crédito 1 y el banco X). En una transacción de pago, la app de pagos puede permitir que el cliente elija uno de los instrumentos de pago y lo use para pagarle al comercio.

IU del selector de forma de pago
IU del selector de forma de pago

La app de pagos puede informarle al comercio qué forma de pago eligió el cliente antes de enviar la respuesta de pago completa. Esto es útil, por ejemplo, cuando el comercio desea publicar una campaña de descuento para una marca de forma de pago específica.

Con la API de Payment Handler, la app de pagos puede enviar un evento de "cambio de forma de pago" al comercio a través de un trabajador de servicio para notificar el nuevo identificador de forma de pago. El trabajador de servicio debe invocar a PaymentRequestEvent.changePaymentMethod() con la información de la nueva forma de pago.

Informa al comercio sobre un cambio de forma de pago
Informa al comercio sobre un cambio de forma de pago

Las apps de pago pueden pasar un objeto methodDetails como el segundo argumento opcional para PaymentRequestEvent.changePaymentMethod(). Este objeto puede contener detalles arbitrarios de la forma de pago necesarios para que el comercio procese el evento de cambio.

[payment handler] service-worker.js

…
// Received a message from the frontend
self.addEventListener('message', async e => {
  let details;
  try {
    switch (e.data.type) {
      …
      case 'PAYMENT_METHOD_CHANGED':
        const newMethod = e.data.paymentMethod;
        const newDetails = e.data.methodDetails;
        // Redact or check that no sensitive information is passed in
        // `newDetails`.
        // Notify the merchant of the payment method change
        details =
          await payment_request_event.changePaymentMethod(newMethod, newDetails);
      …

Cuando el comercio recibe un evento paymentmethodchange de la API de Payment Request, puede actualizar los detalles del pago y responder con un objeto PaymentDetailsUpdate.

[merchant]

request.addEventListener('paymentmethodchange', e => {
  if (e.methodName === 'another-pay') {
    // Apply $10 discount for example.
    const discount = {
      label: 'special discount',
      amount: {
        currency: 'USD',
        // The value being string complies the spec
        value: '-10.00'
      }
    };
    let total = 0;
    details.displayItems.push(discount);
    for (let item of details.displayItems) {
     total += parseFloat(item.amount.value);
    }
    // Convert the number back to string
    details.total.amount.value = total.toString();
  }
  // Pass a promise to `updateWith()` and send updated payment details
  e.updateWith(details);
});

Cuando el comercio responda, la promesa que mostró PaymentRequestEvent.changePaymentMethod() se resolverá con un objeto PaymentRequestDetailsUpdate.

[payment handler] service-worker.js

…
        // Notify the merchant of the payment method change
        details = await payment_request_event.changePaymentMethod(newMethod, newDetails);
        // Provided the new payment details,
        // send a message back to the frontend to update the UI
        postMessage('UPDATE_REQUEST', details);
        break;
…

Usa el objeto para actualizar la IU en el frontend. Consulta Cómo reflejar los detalles de pago actualizados.

Informa al comercio sobre un cambio de dirección de envío

Las apps de pagos pueden proporcionar la dirección de envío de un cliente al comercio como parte de una transacción de pago.

Esto es útil para los comercios, ya que pueden delegar la recopilación de direcciones a las apps de pago. Además, como los datos de la dirección se proporcionarán en el formato de datos estándar, el comercio puede recibir direcciones de envío en una estructura coherente.

Además, los clientes pueden registrar la información de su dirección con su app de pagos preferida y reutilizarla para diferentes comercios.

IU del selector de direcciones de envío
IU del selector de dirección de envío

Las apps de pagos pueden proporcionar una IU para editar una dirección de envío o seleccionar información de dirección registrada previamente para el cliente en una transacción de pago. Cuando se determina una dirección de envío de forma temporal, la app de pagos puede informar al comercio sobre la información de la dirección oculta. Esto les brinda a los comercios los siguientes beneficios:

  • Un comercio puede determinar si el cliente cumple con la restricción regional para enviar el artículo (por ejemplo, solo envíos nacionales).
  • Un comercio puede cambiar la lista de opciones de envío según la región de la dirección de envío (por ejemplo, internacional estándar o exprés).
  • Un comercio puede aplicar el nuevo costo de envío según la dirección y actualizar el precio total.

Con la API de Payment Handler, la app de pagos puede enviar un evento de "cambio de dirección de envío" al comercio desde el trabajador del servicio para notificar la nueva dirección de envío. El trabajador de servicio debe invocar a PaymentRequestEvent.changeShippingAddress() con el objeto de dirección nueva.

Informa al comercio sobre un cambio de dirección de envío
Informa al comercio sobre un cambio de dirección de envío

[payment handler] service-worker.js

...
// Received a message from the frontend
self.addEventListener('message', async e => {
  let details;
  try {
    switch (e.data.type) {
      …
      case 'SHIPPING_ADDRESS_CHANGED':
        const newAddress = e.data.shippingAddress;
        details =
          await payment_request_event.changeShippingAddress(newAddress);
      …

El comercio recibirá un evento shippingaddresschange de la API de Payment Request para que pueda responder con el PaymentDetailsUpdate actualizado.

[merchant]

request.addEventListener('shippingaddresschange', e => {
  // Read the updated shipping address and update the request.
  const addr = request.shippingAddress;
  const details = getPaymentDetailsFromShippingAddress(addr);
  // `updateWith()` sends back updated payment details
  e.updateWith(details);
});

Cuando el comercio responda, la promesa PaymentRequestEvent.changeShippingAddress() que se devuelva se resolverá con un objeto PaymentRequestDetailsUpdate.

[payment handler] service-worker.js

…
        // Notify the merchant of the shipping address change
        details = await payment_request_event.changeShippingAddress(newAddress);
        // Provided the new payment details,
        // send a message back to the frontend to update the UI
        postMessage('UPDATE_REQUEST', details);
        break;
…

Usa el objeto para actualizar la IU en el frontend. Consulta Cómo reflejar los detalles de pago actualizados.

Informa al comercio sobre un cambio en la opción de envío

Las opciones de envío son los métodos de entrega que los comercios utilizan para enviar los artículos comprados a un cliente. Estas son algunas de las opciones de envío típicas:

  • Envío gratis
  • Envío exprés
  • envíos internacionales
  • Envío internacional premium

Cada uno tiene su propio costo. Por lo general, los métodos o las opciones más rápidos son más costosos.

Los comercios que usan la Payment Request API pueden delegar esta selección a una app de pago. La app de pago puede usar la información para crear una IU y permitir que el cliente elija una opción de envío.

IU del selector de opciones de envío
IU del selector de opciones de envío

La lista de opciones de envío especificadas en la API de Payment Request del comerciante se propaga al trabajador de servicio de la app de pagos como una propiedad de PaymentRequestEvent.

[merchant]

const request = new PaymentRequest([{
  supportedMethods: 'https://bobbucks.dev/pay',
  data: { transactionId: '****' }
}], {
  displayItems: [{
    label: 'Anvil L/S Crew Neck - Grey M x1',
    amount: { currency: 'USD', value: '22.15' }
  }],
  shippingOptions: [{
    id: 'standard',
    label: 'Standard',
    amount: { value: '0.00', currency: 'USD' },
    selected: true
  }, {
    id: 'express',
    label: 'Express',
    amount: { value: '5.00', currency: 'USD' }
  }],
  total: {
    label: 'Total due',
    amount: { currency: 'USD', value : '22.15' }
  }
}, {  requestShipping: true });

La app de pagos puede informarle al comercio qué opción de envío eligió el cliente. Esto es importante tanto para el comercio como para el cliente, ya que, si se cambia la opción de envío, también se cambia el precio total. El comercio debe informar el precio más reciente para la verificación del pago más adelante, y el cliente también debe estar al tanto del cambio.

Con la API de Payment Handler, la app de pagos puede enviar un evento "cambio de opción de envío" al comercio desde el trabajador de servicio. El trabajador de servicio debe invocar a PaymentRequestEvent.changeShippingOption() con el nuevo ID de opción de envío.

Informa al comercio sobre un cambio en la opción de envío
Informa al comercio sobre un cambio en la opción de envío

[payment handler] service-worker.js

…
// Received a message from the frontend
self.addEventListener('message', async e => {
  let details;
  try {
    switch (e.data.type) {
      …
      case 'SHIPPING_OPTION_CHANGED':
        const newOption = e.data.shippingOptionId;
        details =
          await payment_request_event.changeShippingOption(newOption);
      …

El comercio recibirá un evento shippingoptionchange de la API de PaymentRequest. El comercio debe usar la información para actualizar el precio total y, luego, responder con el PaymentDetailsUpdate actualizado.

[merchant]

request.addEventListener('shippingoptionchange', e => {
  // selected shipping option
  const shippingOption = request.shippingOption;
  const newTotal = {
    currency: 'USD',
    label: 'Total due',
    value: calculateNewTotal(shippingOption),
  };
  // `updateWith()` sends back updated payment details
  e.updateWith({ total: newTotal });
});

Cuando el comercio responda, la promesa que mostró PaymentRequestEvent.changeShippingOption() se resolverá con un objeto PaymentRequestDetailsUpdate.

[payment handler] service-worker.js

…
        // Notify the merchant of the shipping option change
        details = await payment_request_event.changeShippingOption(newOption);
        // Provided the new payment details,
        // send a message back to the frontend to update the UI
        postMessage('UPDATE_REQUEST', details);
        break;
…

Usa el objeto para actualizar la IU en el frontend. Consulta Cómo reflejar los detalles de pago actualizados.

Refleja los detalles de pago actualizados

Una vez que el comercio termine de actualizar los detalles del pago, las promesas que se devuelven de .changePaymentMethod(), .changeShippingAddress() y .changeShippingOption() se resolverán con un objeto PaymentRequestDetailsUpdate común. El controlador de pagos puede usar el resultado para reflejar el precio total y las opciones de envío actualizados en la IU.

Los comercios pueden mostrar errores por los siguientes motivos:

  • No se acepta la forma de pago.
  • La dirección de envío está fuera de las regiones admitidas.
  • La dirección de envío contiene información no válida.
  • La opción de envío no se puede seleccionar para la dirección de envío proporcionada o por algún otro motivo.

Usa las siguientes propiedades para reflejar el estado del error:

  • error: Es una cadena de error legible por humanos. Esta es la mejor cadena para mostrar a los clientes.
  • shippingAddressErrors: Es un objeto AddressErrors que contiene una cadena de error detallada por propiedad de dirección. Esto es útil si quieres abrir un formulario que le permita al cliente editar su dirección y necesitas dirigirlo directamente a los campos no válidos.
  • paymentMethodErrors: Es un objeto de error específico de la forma de pago. Puedes pedirles a los comercios que proporcionen un error estructurado, pero los autores de las especificaciones de pagos web recomiendan que sea una cadena simple.

Código de muestra

La mayoría de los códigos de muestra que viste en este documento fueron extractos de la siguiente app de ejemplo que funciona:

https://paymenthandler-demo.glitch.me

[payment handler] service worker

[payment handler] frontend

Para probarlo, haz lo siguiente:

  1. Ve a https://paymentrequest-demo.glitch.me/.
  2. Ve a la parte inferior de la página.
  3. Presiona el botón para agregar una forma de pago.
  4. Ingresa https://paymenthandler-demo.glitch.me en el campo Identificador de forma de pago.
  5. Presiona el botón Pay junto al campo.