Ciclo de una transacción de pago

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

Las API de pagos web son funciones de pago dedicadas integradas en el navegador por primera vez. Con los pagos web, la integración de los comercios con las apps de pagos es más sencilla, a la vez que la experiencia del cliente se optimiza y es más segura.

Para obtener más información acerca de los beneficios de usar Web Payments, consulta Cómo mejorar las apps de pago con Web Payments.

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

El proceso consta de 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.

    Diagrama de un sitio web de una tienda de quesos con un botón de BobPay (aplicación de pago).

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

    Diagrama del sitio web de la tienda de quesos con la app de BobPay iniciada en un modal La ventana modal muestra 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 que elige una opción de envío diferente en el modal de la app de BobPay. Un segundo diagrama en el que se muestra al comercio que actualiza el costo total que se muestra en BobPay.

  6. Una vez 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 construyendo un objeto PaymentRequest. Este objeto incluye información importante sobre la transacción:

  • Formas de pago aceptables y sus datos para procesar la transacción
  • Detalles, como el precio total (obligatorio) y la información sobre los artículos
  • Opciones con 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 el 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'
});
Incluye 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 comunicación entre el servidor del comercio y el del controlador de pagos para reservar el precio total. De esta forma, se 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.

Cuando se proporciona la información de la transacción, el navegador pasa por un proceso de descubrimiento de apps de pago especificadas en el PaymentRequest en función de 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 una forma de pago.

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

Los comercios pueden admitir muchas formas de pago, pero solo deben presentar los botones de pago para aquellas que el cliente realmente puede 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 de resguardo o no mostrar ese botón.

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

¿El cliente tiene una app de pagos disponible?

El método canMakePayment() de PaymentRequest muestra true si hay una app de pagos disponible en el dispositivo del cliente. "Disponible" significa que se descubre una app de pagos que admite la forma de pago y que está instalada la app de pagos específica de la plataforma o que la app de pagos 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 configure de forma dinámica (por ejemplo, si se recupera de un servidor), el comercio puede diferir el inicio de la IU de pago hasta que se conozca el total.

Cómo postergar el lanzamiento de la IU de pagos

Consulta una demostración para 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 se resuelva la promesa 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á la IU de pago de inmediato.

Paso 4: El navegador inicia la app de pagos

El navegador puede iniciar una app de pagos 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).

La forma en que se compila la app de pagos depende del desarrollador 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, esta 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 puede un comercio 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.

Los comercios pueden recibir cuatro tipos de eventos:

  • 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 cubrir este caso de uso, el evento de cambio de forma de pago puede informar al comercio sobre la forma de pago nueva 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, ya que no tienen que ingresar ningún detalle de forma manual en un formulario y pueden almacenar su dirección de envío en sus apps de pago preferidas, en lugar de hacerlo 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 inicia la transacción, se enviará un evento 'shippingaddresschange' al comercio. Este evento ayuda al comercio a determinar el costo de envío en función de la nueva dirección, actualizar el precio total y devolverlo en 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 cuando agrega 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 opció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: gratuito
  • Envío exprés: USD 5

Cuando un cliente actualice la opción de envío en una app de pagos, se enviará un evento 'shippingoptionchange' al comercio. Luego, el comercio puede determinar el costo de envío, actualizar el precio total y devolverlo en 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 en función de la dirección de envío del cliente. Esto es útil cuando un comercio desea ofrecer diferentes conjuntos de opciones de envío para clientes internacionales y nacionales.

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 qué URL puede usar para validarse a sí mismo.

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 siga mostrando un indicador de carga, lo que significa que la transacción aún no se completó.

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

Procesa y valida el pago

El details de PaymentResponse es el objeto de credencial de pago que muestra la app de pagos. El comercio puede usar la credencial para procesar o validar el pago. La forma en que funciona este proceso crítico depende del controlador de pagos.

Completa o vuelve a intentar la transacción

Una vez que el comercio determine 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.
  • Llama al método retry() para permitir que el cliente vuelva a intentarlo.
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