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 una transacción de pago en el sitio web de un comercio y se te ayuda a comprender cómo funciona la integración de la app 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 app de pagos.

    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 que reflejan el cambio.

    Un diagrama que muestra al cliente eligiendo una opción de envío diferente en el cuadro modal de la app de BobPay. Un segundo diagrama que muestra al comercio actualizando 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, el correo electrónico y el número de teléfono del pagador.
  • 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'
});

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 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 pago 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 Configura 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 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 disponible la app de pagos?

El método canMakePayment() de PaymentRequest muestra true si hay una app de pagos 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 inicio 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 aplazar 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 se especifica una promesa 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 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).

En su mayor parte, la forma de compilar la app de pagos depende del desarrollador, pero los eventos emitidos desde y hacia el comercio, así como la estructura de los datos que se pasan junto con ellos, 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 los 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 pago puede proporcionar la dirección de envío del cliente. Esto es conveniente para los clientes, ya que 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 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 haya iniciado 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 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 pagos. El diseño del mecanismo de validación depende de la app de pagos, pero el evento de validación del comercio sirve para informar al comercio de la URL que puede usar para validarse.

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 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 muestra la app de pagos. El comercio puede usar la credencial para procesar o validar el pago. El funcionamiento de este proceso crítico depende del controlador de pago.

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