Payment Request API, el nuevo estándar para pagos en Internet (primera parte)

30 de agosto de 2018

Este tutorial es la primera 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.

Detectar si el navegador lo soporta

Los navegadores más modernos ya disponen de soporte para la API "Payment Request", pero puedes utilizar el siguiente código para detectar si los nevagadores de tus usuarios la soportan:

if (window.PaymentRequest) {
  // puedes usar la API "Payment Request"
} else {
  // usar el método tradicional
  window.location.href = '/compra/pagar';
}

Además, por motivos de seguridad, la API "Payment Request" solo está disponible cuando se utiliza HTTPS.

Información básica del pago

Cuando se realiza un pago, los navegadores muestran su información en una zona dedicada, como por ejemplo una ventana emergente. La parte superior de esta zona muestra la información básica sobre la solicitud de pago:

Información básica del pago

Esa información se genera automáticamente mediante la información disponible en la página. El icono de la izquierda es el icono de tipo <link rel="icon" ...> con el tamaño más apropiado que puede encontrar el navegador. Se recomienda definir un icono de 512px de tamaño mediante la siguiente etiqueta:

<link rel="icon" href="images/icon-512x512.png" sizes="512x512" type="image/png">

El texto en negrita es el contenido completo de la etiqueta <html> de la página donde se solicita el pago. En este ejemplo, la etiqueta sería <title>Payment Request Demo</title>. La URL es la dirección absoluta de la página donde se solicita el pago.

El constructor de PaymentRequest

Cuando quieras solicitar un pago al usuario, debes construir un objeto de tipo PaymentRequest:

const supportedPaymentMethods = [
  {
    supportedMethods: 'basic-card',
  }
];
const paymentDetails = {
  total: {
    label: 'Total',
    amount:{
      currency: 'USD',
      value: 0
    }
  }
};

const options = {};

new PaymentRequest(
  supportedPaymentMethods,
  paymentDetails,
  options
);

Al constructor se le pasan tres argumentos. El primero define qué formas de pago aceptas; el segundo incluye la suma total y los detalles de lo que el usuario va a comprar; el tercero es opcional y se emplea para solicitar información adicional al usuario (por ejemplo su email y teléfono de contacto).

Después de construir el objeto PaymentRequest, debes invocar el método show() para mostrar la solicitud de pago al usuario:

const request = new PaymentRequest(
  supportedPaymentMethods,
  paymentDetails,
  options
);

// llama a 'show()' para que el navegador muestre la solicitud de pago al usuario
request.show()
.then(...).catch(...);

Definiendo los métodos de pago soportados

La API "Payment Request" soporta tarjetas de crédito y de débito, además de servicios de pago como PayPal, Stripe, Apple Pay, Google Pay, etc.

Las formas de pago se indican como un array de objetos, donde cada uno de ellos incluye un parámetro supportedMethods que identifica esa forma de pago concreta.

const supportedPaymentMethods = [
  {
    supportedMethods: 'nombre-de-la-forma-de-pago',
    data: {
      // Información opcional para esta forma de pago
    }
  }
];

new PaymentRequest(supportedPaymentMethods, paymentDetails, options);

Tarjetas de crédito y débito

El tipo definido para cualquier tipo de tarjeta es basic-card:

const creditCardPaymentMethod = {
  supportedMethods: 'basic-card',
};

const supportedPaymentMethods = [creditCardPaymentMethod];

new PaymentRequest(supportedPaymentMethods, paymentDetails, options);

Si el usuario ha guardado en el navegador los datos de alguna tarjeta de crédito o débito, simplemente tendrá que seleccionar la tarjeta con la que quiere pagar. Si no, el navegador le solicitará los datos de la tarjeta.

Ejemplo de pago con cualquier tipo de tarjeta

Actualmente, navegadores como Chrome soportan las tarjetas de tipo amex, diners, discover, jcb, mastercard, unionpay, mir y visa, pero la lista aumentará en el futuro.

Si quieres limitar las tarjetas que aceptas, define el parámetro opcional supportedNetworks:

const creditCardPaymentMethod = {
  supportedMethods: 'basic-card',
  data: {
    supportedNetworks: ['visa', 'mastercard', 'amex'],
  },
};

Ahora la solicitud de pago solo muestra estos tres tipos de tarjeta:

Ejemplo de pago con ciertos tipos de tarjetas

La imagen anterior se corresponde a la de un usuario que no tiene los datos de ninguna tarjeta guardada en su navegador y por eso tiene que proporcionar esos datos para completar el pago. Sin embargo, si el navegador dispone de los datos de alguna de las tarjetas soportadas, se muestran los datos directamente y el usuario puede cambiarlos si quiere:

Ejemplo de pago con un tarjeta preseleccionada

El parámetro opcional supportedTypes permite filtrar las tarjetas que se muestran al usuario (por ejemplo, si indicas ['credit', 'debit'] no se muestran tarjetas de tipo pre-pago). No obstante, el usuario puede añadir una nueva tarjeta al pagar y puede ser de cualquier tipo, ya que supportedTypes no restringe lo que el usuario puede añadir. En otras palabras, siempre tienes que comprobar en el servidor el tipo de pago utilizado.

const creditCardPaymentMethod = {
  supportedMethods: 'basic-card',
  data: {
    supportedNetworks: ['visa', 'mastercard', 'amex'],
    supportedTypes: ['credit', 'debit'],
  },
};

Múltiple formas de pago

En el ejemplo anterior, el objeto creditCardPaymentMethod se pasa dentro de un array porque la API de "Payment Request" soporta el uso de varias formas de pago a la vez. Imagina que una tienda soporta tanto las tarjetas tradicionales como una pasarela de pago llamada "BobPay". Este es el código que debería usar:

const creditCardPaymentMethod = {
  supportedMethods: 'basic-card',
};

const bobPayPaymentMethod = {
  supportedMethods: "https://example.com/bobpay",
  data: {
    merchantIdentifier: "XXXX",
    bobPaySpecificField: true
  }
};

const supportedPaymentMethods = [
  creditCardPaymentMethod,
  bobPayPaymentMethod
];

new PaymentRequest(supportedPaymentMethods, paymentDetails, order);

Si el navegador soporta la forma de pago de "BobPay", se mostrará al usuario como una más de las formas de pago disponibles. Un ejemplo de esta opción es el uso de "Google Pay", que se soporta en navegadores como Chrome de Android:

const googlePayPaymentMethod = {
  supportedMethods: 'https://google.com/pay',
  data: {
    'environment': 'TEST',
    'apiVersion': 1,
    'allowedPaymentMethods': ['CARD', 'TOKENIZED_CARD'],
    'paymentMethodTokenizationParameters': {
      'tokenizationType': 'PAYMENT_GATEWAY',
      // los parámetros dependen del tipo de "gateway" utilizado
      'parameters': {}
    },
    'cardRequirements': {
      'allowedCardNetworks': ['AMEX', 'DISCOVER', 'MASTERCARD', 'VISA'],
      'billingAddressRequired': true,
      'billingAddressFormat': 'MIN'
    },
    'phoneNumberRequired': true,
    'emailRequired': true,
    'shippingAddressRequired': true
  },
};

Ejemplo de pago con Google Pay

Cosas a tener en cuenta

Formas de pago no soportadas

Si llamas a show() en un objeto PaymentRequest y el navegador no soporta ninguna de sus formas de pago, la promesa devuelve el siguiente error de manera inmediata:

DOMException: The payment method is not supported

Si añades basic-card como forma de pago, seguramente no verás este error nunca. Pero si solo aceptas como forma de pago servicios como Google Pay, es muy probable que el navegador no lo soporte.

Los detalles de la forma de pago no se muestran

En una de las imágenes anteriores, se muestra Google Pay preseleccionado porque hay dos formas de pago (tarjets y Google Pay) y el usuario puede seleccionar la que quiera. Pero si solo defines una forma de pago y el navegador la soporta, es posible que no es muestren estos detalles y se redirija al usuario directamente al pago (eso es por ejemplo lo que hace Chrome con Google Pay).