Cómo adaptar tu app de pagos basada en la Web a los pagos en la 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 service worker actuará como 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 a través de un service worker.

Informa al comercio
Es importante informar al comercio sobre los siguientes cambios.
Cambio de forma de pago
Las apps de pagos pueden admitir varios instrumentos de pago con diferentes formas de pago.
Cliente | Forma de pago | Instrumento de pago |
---|---|---|
A | Entidad emisora de la tarjeta de crédito 1 | ****1234 |
Entidad emisora de la tarjeta de crédito 1 | ****4242 |
|
Banco X | ******123 |
|
B | Entidad emisora de la tarjeta de crédito 2 | ****5678 |
Banco X | ******456 |
Por ejemplo, en la tabla anterior, la billetera basada en la Web del cliente A tiene registradas dos tarjetas de crédito y una cuenta bancaria. En este caso, la app controla tres instrumentos de pago (****1234
, ****4242
, ******123
) y dos formas de pago (Emisor de tarjeta de crédito 1 y 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.

La app de pagos puede informar al comercio qué forma de pago eligió el cliente antes de enviar la respuesta de pago completa. Esto es útil cuando el comercio desea ejecutar una campaña de descuentos para una marca de forma de pago específica, por ejemplo.
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 service worker para notificar el nuevo identificador de la forma de pago. El trabajador de servicio debe invocar PaymentRequestEvent.changePaymentMethod()
con la información de la nueva forma de pago.

Las apps de pagos pueden pasar un objeto methodDetails
como el segundo argumento opcional para PaymentRequestEvent.changePaymentMethod()
. Este objeto puede contener detalles arbitrarios de la forma de pago que el comercio necesita para procesar el evento de cambio.
[controlador de pagos] 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 de 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 devolvió PaymentRequestEvent.changePaymentMethod()
se resolverá con un objeto PaymentRequestDetailsUpdate
.
[controlador de pagos] 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 Refleja los detalles de pago actualizados.
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 esperar recibir direcciones de envío con una estructura coherente.
Además, los clientes pueden registrar la información de su dirección en su app de pagos preferida y reutilizarla para diferentes comercios.

Las apps de pagos pueden proporcionar una IU para editar una dirección de envío o seleccionar información de dirección pre registrada 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 que se ocultó. Esto proporciona a los comercios múltiples beneficios:
- El comercio puede determinar si el cliente cumple con la restricción regional para enviar el artículo (por ejemplo, solo a nivel nacional).
- 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, envío 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 service worker para notificar la nueva dirección de envío. El trabajador de servicio debe invocar PaymentRequestEvent.changeShippingAddress()
con el objeto de dirección nuevo.

[controlador de pagos] 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);
…
Término clave: Dirección redactada. En este caso, no es necesario informar al comercio la dirección de envío completa, lo que pone en riesgo la privacidad de los clientes. El comercio solo recibe las partes de la dirección que necesita para determinar el costo de envío. Específicamente, el navegador borrará los campos organization
, phone
, recipient
y addressLine
de la dirección proporcionada por la app de pagos antes de generar el evento shippingaddresschange
en el DOM del comercio.
El comercio recibirá un evento shippingaddresschange
de la API de Payment Request para que pueda responder con el objeto 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 responde, la promesa PaymentRequestEvent.changeShippingAddress()
que se devolvió se resolverá con un objeto PaymentRequestDetailsUpdate
.
[controlador de pagos] 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 Refleja 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 usan los comercios 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 una tiene su propio costo. Por lo general, los métodos y las opciones más rápidos son más costosos.
Los comercios que usan la API de Payment Request pueden delegar esta selección en una app de pagos. La app de pagos puede usar la información para crear una IU y permitir que el cliente elija una opción de envío.

La lista de opciones de envío especificadas en la API de Payment Request del comercio se propaga al Service Worker 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 cambiar la opción de envío también cambia el precio total. El comercio debe conocer el precio más reciente para la verificación del pago posterior, 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 de "cambio de opción de envío" al comercio desde el service worker. El trabajador de servicio debe invocar PaymentRequestEvent.changeShippingOption()
con el nuevo ID de opción de envío.

[controlador de pagos] 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 Payment Request. 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 devolvió PaymentRequestEvent.changeShippingOption()
se resolverá con un objeto PaymentRequestDetailsUpdate
.
[controlador de pagos] 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 Refleja los detalles de pago actualizados.
Reflejar los detalles de pago actualizados
Una vez que el comercio termina de actualizar los detalles de pago, las promesas que se muestran desde .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 actualizado y las opciones de envío en la IU.
Los comercios pueden devolver errores por varios 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 de error:
error
: Es una cadena de error legible. Es la mejor cadena para mostrar a los clientes.shippingAddressErrors
: ObjetoAddressErrors
que contiene una cadena de error detallada por propiedad de dirección. Esto es útil si deseas 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 la especificación de Web Payments recomiendan mantenerlo como una cadena simple.
Código de muestra
La mayoría de las muestras de código que viste en este documento eran fragmentos de una aplicación de ejemplo.
Para probarla, haz lo siguiente:
- Ve a https://paymentrequest-demo.glitch.me/.
- Ve a la parte inferior de la página.
- Presiona Agregar un botón de pago.
- Ingresa
https://paymenthandler-demo.glitch.me
en el campo Identificador de la forma de pago. - Presiona el botón Pagar junto al campo.