Ciclo de una transacción de pago

Obtén información sobre cómo los comercios integran apps de pago y cómo funcionan las transacciones de pago con la API de Payment Request.

Las APIs de Web Payments son funciones de pago dedicadas integradas en el navegador por primera vez. Con los pagos web, la integración de comercios con las apps de pago se vuelve más simple, mientras que la experiencia del cliente se optimiza y se vuelve más segura.

Para obtener más información sobre los beneficios de usar los pagos web, consulta Cómo potenciar las apps de pagos con los pagos web.

En este artículo, se explica cómo realizar una transacción de pago en el sitio web de un comercio y se brinda ayuda para comprender cómo funciona la integración de apps de pagos.

El proceso incluye 6 pasos:

  1. El comercio inicia una transacción de pago.
  2. El comercio muestra un botón de pago.
  3. El cliente presiona el botón de pago.

    Un diagrama del sitio web de una tienda de quesos con un botón de BobPay (app de pagos).

  4. El navegador inicia la aplicación de pago.

    Un diagrama del sitio web de la tienda de quesos con la app de BobPay iniciada en un cuadro modal. En el cuadro modal, se muestran las opciones de envío y el costo total.

  5. Si el cliente cambia algún detalle (como las opciones de envío o su dirección), el comercio actualiza los detalles de la transacción para reflejar el cambio.

    Un diagrama que muestra al cliente eligiendo una opción de envío diferente en la ventana modal de la app de BobPay. Un segundo diagrama en el que se muestra cómo el comercio actualiza el costo total que se muestra en BobPay.

  6. Después de que el cliente confirma la compra, el comercio valida el pago y completa la transacción.

    Un diagrama que muestra al cliente presionando el

Paso 1: El comercio inicia una transacción de pago

Cuando un cliente decide realizar una compra, el comercio inicia la transacción de pago mediante la construcción de un objeto PaymentRequest. Este objeto incluye información importante sobre la transacción:

  • Las formas de pago aceptadas y sus datos para procesar la transacción
  • Detalles, como el precio total (obligatorio) y la información sobre los artículos
  • Son opciones en las que los comercios pueden solicitar información de envío, como una dirección y una opción de envío.
  • Los comercios también pueden solicitar la dirección de facturación, el nombre del pagador, el correo electrónico y el número de teléfono.
  • Los comercios también pueden incluir un tipo de envío opcional (shipping, delivery o pickup) en PaymentRequest. La app de pagos puede usar eso como una sugerencia para mostrar las etiquetas correctas en su IU.
const request = new PaymentRequest([{
  supportedMethods: 'https://bobpay.xyz/pay',
  data: {
    transactionId: '****'
  }
}], {
  displayItems: [{
    label: 'Anvil L/S Crew Neck - Grey M x1',
    amount: { currency: 'USD', value: '22.15' }
  }],
  total: {
    label: 'Total due',
    amount: { currency: 'USD', value : '22.15' }
  }
}, {
  requestShipping: true,
  requestBillingAddress: true,
  requestPayerEmail: true,
  requestPayerPhone: true,
  requestPayerName: true,
  shippingType: 'delivery'
});
Cómo incluir un ID de transacción

Algunos controladores de pago pueden requerir que el comercio proporcione el ID de transacción que emitió con anticipación como parte de la información de la transacción. Una integración típica incluye la comunicación entre el servidor del comercio y el servidor del controlador de pagos para reservar el precio total. Esto evita que los clientes maliciosos manipulen el precio y engañen al comercio con una validación al final de la transacción.

El comercio puede pasar un ID de transacción como parte de la propiedad data del objeto PaymentMethodData.

Si se proporciona la información de la transacción, el navegador pasa por un proceso de descubrimiento de apps de pago especificadas en PaymentRequest según los identificadores de forma de pago. De esta manera, el navegador puede determinar la app de pagos que se iniciará en cuanto el comercio esté listo para continuar con la transacción.

Para obtener información detallada sobre cómo funciona el proceso de descubrimiento, consulta Cómo configurar un método de pago.

Paso 2: El comercio muestra un botón de pago

Los comercios pueden admitir muchas formas de pago, pero solo deben mostrar los botones de pago para las que un cliente pueda usar. Mostrar un botón de pago que no se puede usar es una mala experiencia del usuario. Si un comercio puede predecir que una forma de pago especificada en el objeto PaymentRequest no funcionará para el cliente, puede proporcionar una solución alternativa o no mostrar ese botón en absoluto.

Con una instancia de PaymentRequest, un comercio puede consultar si un cliente tiene la app de pagos disponible.

¿El cliente tiene la app de pagos disponible?

El método canMakePayment() de PaymentRequest muestra true si hay una app de pago disponible en el dispositivo del cliente. "Disponible" significa que se detectó una app de pago que admite la forma de pago y que la app de pago específica de la plataforma está instalada, o que la app de pago basada en la Web está lista para registrarse.

const canMakePayment = await request.canMakePayment();
if (!canMakePayment) {
  // Fallback to other means of payment or hide the button.
}

Paso 3: El cliente presiona el botón de pago

Cuando el cliente presiona el botón de pago, el comercio llama al método show() de la instancia PaymentRequest, que activa de inmediato el inicio de la IU de pago.

En caso de que el precio total final se establezca de forma dinámica (por ejemplo, se recupere de un servidor), el comercio puede aplazar el lanzamiento de la IU de pago hasta que se conozca el total.

Aplaza el lanzamiento de la IU de pago

Mira una demostración de cómo aplazar la IU de pago hasta que se determine el precio total final.

Para diferir la IU de pago, el comercio pasa una promesa al método show(). El navegador mostrará un indicador de carga hasta que la promesa se resuelva y la transacción esté lista para comenzar.

const getTotalAmount = async () => {
  // Fetch the total amount from the server, etc.
};

try {
  const result = await request.show(getTotalAmount());
  // Process the result…
} catch(e) {
  handleError(e);
}

Si no hay ninguna promesa especificada como argumento para show(), el navegador iniciará de inmediato la IU de pago.

Paso 4: El navegador inicia la app de pagos

El navegador puede iniciar una app de pago específica de la plataforma o basada en la Web. (Obtén más información sobre cómo Chrome determina qué app de pago iniciar).

El desarrollador es quien decide cómo compilar la app de pagos en su mayor parte, pero los eventos emitidos desde y hacia el comercio, así como la estructura de los datos que se pasan junto con esos eventos, están estandarizados.

Cuando se inicia la app de pagos, recibe la información de la transacción que se pasa al objeto PaymentRequest en el paso 1, que incluye lo siguiente:

  • Datos de la forma de pago
  • Precio total
  • Opciones de pago

La app de pagos usa la información de la transacción para etiquetar su IU.

Paso 5: Cómo un comercio puede actualizar los detalles de la transacción según las acciones del cliente

Los clientes tienen la opción de cambiar los detalles de la transacción, como la forma de pago y la opción de envío, en la app de pagos. Mientras el cliente realiza cambios, el comercio recibe los eventos de cambio y actualiza los detalles de la transacción.

Existen cuatro tipos de eventos que puede recibir un comercio:

  • Evento de cambio de forma de pago
  • Evento de cambio de dirección de envío
  • Evento de cambio de opción de envío
  • Evento de validación del comercio

Evento de cambio de forma de pago

Una app de pagos puede admitir varias formas de pago, y un comercio puede ofrecer un descuento especial según la selección del cliente. Para abarcar este caso de uso, el evento de cambio de forma de pago puede informar al comercio sobre la nueva forma de pago para que pueda actualizar el precio total con el descuento y devolverlo a la app de pagos.

request.addEventListener('paymentmethodchange', e => {
  e.updateWith({
    // Add discount etc.
  });
});

Evento de cambio de dirección de envío

De manera opcional, una app de pagos puede proporcionar la dirección de envío del cliente. Esto es conveniente para los clientes porque no tienen que ingresar manualmente ningún detalle en un formulario y pueden almacenar su dirección de envío en sus apps de pago preferidas, en lugar de en varios sitios web de comercios diferentes.

Si un cliente actualiza su dirección de envío en una app de pagos después de que se inició la transacción, se enviará un evento 'shippingaddresschange' al comercio. Este evento ayuda al comercio a determinar el costo de envío según la dirección nueva, actualizar el precio total y devolverlo a la app de pagos.

request.addEventListener('shippingaddresschange', e => {
  e.updateWith({
    // Update the details
  });
});

Si el comercio no puede realizar envíos a la dirección actualizada, puede proporcionar un mensaje de error agregando un parámetro de error a los detalles de la transacción que se muestran a la app de pagos.

Evento de cambio de opción de envío

Un comercio puede ofrecer varias opciones de envío al cliente y delegar esa elección a la app de pagos. Las opciones de envío se muestran como una lista de precios y nombres de servicios que el cliente puede seleccionar. Por ejemplo:

  • Envío estándar gratis
  • Envío expreso: USD 5

Cuando un cliente actualiza la opción de envío en una app de pagos, se envía un evento 'shippingoptionchange' al comercio. Luego, el comercio puede determinar el costo de envío, actualizar el precio total y devolverlo a la app de pagos.

request.addEventListener('shippingoptionchange', e => {
  e.updateWith({
    // Update the details
  });
});

El comercio también puede modificar de forma dinámica las opciones de envío según la dirección de envío del cliente. Esto es útil cuando un comercio quiere ofrecer distintos conjuntos de opciones de envío para clientes nacionales e internacionales.

Evento de validación del comercio

Para mayor seguridad, una app de pagos puede realizar una validación del comercio antes de continuar con el flujo de pago. El diseño del mecanismo de validación depende de la app de pagos, pero el evento de validación del comercio sirve para informarle al comercio la URL que puede usar para validar su identidad.

request.addEventListener('merchantvalidation', e => {
  e.updateWith({
    // Use `e.validateURL` to validate
  });
});

Paso 6: El comercio valida el pago y completa la transacción

Cuando el cliente autoriza el pago de forma correcta, el método show() muestra una promesa que se resuelve en un PaymentResponse. El objeto PaymentResponse incluye la siguiente información:

  • Detalles del resultado del pago
  • Dirección de envío
  • Opción de envío
  • Información de contacto

En este punto, es posible que la IU del navegador aún muestre un indicador de carga, lo que significa que la transacción aún no se completó.

Si se cierra la app de pagos debido a una falla o un error de pago, se rechaza la promesa que se muestra desde show() y el navegador finaliza la transacción de pago.

Procesamiento y validación del pago

El details en PaymentResponse es el objeto de credencial de pago que se muestra desde la app de pagos. El comercio puede usar la credencial para procesar o validar el pago. El encargado del control de pagos determina cómo funciona este proceso fundamental.

Completar la transacción o volver a intentarla

Después de que el comercio determina si la transacción se realizó correctamente o no, puede hacer lo siguiente:

  • Llama al método .complete() para completar la transacción y descartar el indicador de carga.
  • Permite que el cliente vuelva a intentarlo llamando al método retry().
async function doPaymentRequest() {
  try {
    const request = new PaymentRequest(methodData, details, options);
    const response = await request.show();
    await validateResponse(response);
  } catch (err) {
    // AbortError, SecurityError
    console.error(err);
  }
}

async function validateResponse(response) {
  try {
    const errors = await checkAllValuesAreGood(response);
    if (errors.length) {
      await response.retry(errors);
      return validateResponse(response);
    }
    await response.complete("success");
  } catch (err) {
    // Something went wrong…
    await response.complete("fail");
  }
}
// Must be called as a result of a click
// or some explicit user action.
doPaymentRequest();

Próximos pasos