Este tutorial es la segunda parte de la siguiente serie de tutoriales que explica el funcionamiento práctico de la nueva API llamada Payment Request para hacer pagos en Internet:
- Primera parte: introducción general y cómo definir las formas de pago disponibles.
- Segunda parte: cómo mostrar los detalles del pago y solicitar información al usuario.
- Tercera parte: cómo completar (o cancelar) el proceso de pago.
- Cuarta parte: cómo solicitar la dirección y forma de envío.
Definiendo los detalles del pago
El segundo argumento obligatorio del constructor del objeto PaymentRequest
es
un objeto con los detalles del pago. Este objeto contiene obligatoriamente el
total a pagar y, opcionalmente, un array con el detalle del pago
(subtotal, impuestos, descuentos, etc.)
Total a pagar
El total a pagar se define con una etiqueta o título y una cantidad de dinero (que incluye la divisa). Por ejemplo:
const paymentDetails = {
total: {
label: 'Total',
amount: {
currency: 'USD',
value: '0',
},
},
};
new PaymentRequest(supportedPaymentMethods, paymentDetails, options);
Esta información se muestra en la sección "Order Summary" de la pantalla que se muestra al usuario:
El título o etiqueta es una cadena de texto elegida libremente, pero la divisa debe ser un código válido de acuerdo con el estándar ISO 4217. Este otro ejemplo modifica alguno de estos valores:
const paymentDetails = {
total: {
label: 'Purchase Amount',
amount: {
currency: 'GBP',
value: '24.99',
},
},
};
Y así se mostraría este ejemplo al usuario:
Detalles del pago
Esta opción se puede usar para detallar cómo se ha obtenido el total a pagar. Normalmente estos detalles incluyen el subtotal, los impuestos, los descuentos, los gastos de envío, etc.
Este objeto debe ser un array de elementos y cada uno de ellos debe usar el
mismo formato que el total
(título o etiqueta y cantidad con divisa).
const allDisplayItems = [
{
label: 'Subtotal',
amount: {
currency: 'USD',
value: 10,
},
}, {
label: 'Discount (10%)',
amount: {
currency: 'USD',
value: -1,
},
}, {
label: 'Tax',
amount: {
currency: 'USD',
value: 0.68,
},
},
];
const paymentDetails = {
total: {
label: 'Total',
amount: {
currency: 'USD',
value: 0,
},
},
displayItems: allDisplayItems,
};
Y así se vería este ejemplo en el navegador:
Cosas que debes tener en cuenta:
- El orden en el que defines los contenidos de
displayItems
es importante porque es el mismo orden en el que se muestran al usuario. - El objeto
displayItems
no está pensado para mostrar un listado largo con todos los objetos o servicios comprados. Utilízalo solamente para mostrar el resumen general del pedido (subtotal, impuestos, descuentos, etc.) - La API "Payment Request" no suma los contenidos del detalle del pago para
comprobar que el
total
sea correcto. El navegador solamente muestra la información que le pasas.
Si algún detalle del pago no está definido todavía (por ejemplo, el coste de
envío no se sabe porque el usuario todavía no ha indicado la dirección) utiliza
el parámetro pending
para indicar que está pendiente.
const transactionDisplayItems = [
{
label: 'Total cost of goods',
amount: {
currency: 'USD',
value: 10,
},
}, {
label: 'Tax',
pending: true,
amount: {
currency: 'USD',
value: 0.75,
},
},
];
Los gastos pendientes se muestran con un tipo de letra más pequeño y más claro:
Posibles errores
Títulos demasiado largos
Actualmente los navegadores no recortan el título de total
, por lo que debes
tener cuidado con su longitud. Los títulos de los detalles de pago sí que se
recortan automáticamente.
Total no indicado
El parámetro total
es obligatorio, por lo que si no lo indicas, verás el
siguiente error:
TypeError: Failed to construct 'PaymentRequest': Must specify total
No incluir el título, cantidad o divisa
Si no incluyes alguna de estas propiedades en el total
o en los detalles del
pago, verás los siguientes errores:
// Si no indicas el título 'PaymentRequest': required member label is undefined. // Si no indicas la cantidad 'PaymentRequest': required member amount is undefined. // Si no indicas la divisa 'PaymentRequest': required member currency is undefined. // Si no indicas el valor 'PaymentRequest': required member value is undefined.
Totales negativos (devoluciones)
La API "Payment Request" no soporta cantidades totales negativas (que normalmente se utilizan para hacer devoluciones). Si indicas un valor negativo, verás el siguiente error:
'PaymentRequest': Total amount value should be non-negative
Divisas no válidas
La divisa se debe indicar como un código válido de tres letras en mayúscula. Si no lo haces así, verás el siguiente error.
'PaymentRequest': '...' is not a valid ISO 4217 currency code, should be 3 upper case letters [A-Z]
De hecho, puedes pasar cualquier valor de tres letras mayúsculas y se
considerará una divisa válida. Esto se ha hecho así para soportar divisas
definidas en el futuro, como por ejemlo las criptomonedas. Así que si aceptas
pagos en Bitcoins, deberías usar XBT
como código.
Cuando se utilizan divisas válidas, el navegador muestra su símbolo junto a la cantidad. Para el resto de divisas, solamente se muestra su código:
Múltiples divisas
Actualmente los navegadores no soportan los pagos en múltiples divisas, por lo que si intentas hacerlo, verás este error:
DOMException: Request cancelled
Formato de la cantidad a pagar
El parámetro value
puede ser una cadena de texto además de un número. Si
utilizas una cadena, solo puede contener números y un solo punto para indicar
los decimales. Si no, verás el siguiente error:
'PaymentRequest': '...' is not a valid amount format
Por ejemplo, 1,000.00
no es válido por la coma que separa los miles, pero
1000.00
sí que es válido.
Escritura de derecha a izquierda
Si indicas los títulos en algún idioma que escribe de derecha a izquierda (árabe, hebreo, etc.) se mostrarán correctamente. El resto de contenidos de la página se mostrarán de acuerdo a las opciones del navegador y del sistema operativo.
Definiendo opciones adicionales
El tercer argumento opcional del constructor de PaymentRequest
es un objeto
que define qué información adicional quieres solicitar al usuario, tales como
su nombre, email, teléfono, etc. Se recomienda pedir solo lo que realmente
necesitas, ya que si no, se alarga el proceso de compra innecesariamente.
Para solicitar solamente el nombre, teléfono y email, define lo siguiente:
const options = {
requestPayerName: true,
requestPayerPhone: true,
requestPayerEmail: true,
};
Por defecto todas estas opciones valen false
. Si devuelves true
para alguna
de ellas, el navegador mostrará un paso adicional durante la compra:
Si el navegador ya dispone de la información solicitada, se muestra directamente y el usuario puede cambiarla si quiere:
Cosas a tener en cuenta:
- El valor de los parámetros
requestPayerName
,requestPayerPhone
yrequestPayerEmail
debe ser booleano. Si pasas otro tipo de valor, se harán las conversiones automáticas de JavaScript (null
,undefined
y0
se consideranfalse
, mientras que los demás valores, incluyendo{}
y[]
, se considerantrue
).