Realizar un pago
Este tema describe los pasos que debe seguir para realizar un pago mediante una sesión en la que recopila datos de pago confidenciales del pagador con campos alojados en su página de pago. Esto se logra utilizando la Session JavaScript library
(session.js) además de WSAPI. Para obtener un ejemplo de fragmento de código completo de toda la implementación de la página de pago en un sitio web, consulte Ejemplo de código de página de pago.
Paso 1: Crear una sesión
Cree una sesión enviando una solicitud Create Session.
desde su servidor. Especifique un límite de autenticación de sesión de 25. La respuesta devuelve un ID de sesión que debe utilizar en los pasos siguientes para hacer referencia a esta sesión.
URL | https://anzworldline.gateway.mastercard.com/api/rest/version/72/merchant/<merchant_ID>/session |
Método HTTP | POST |
{ "session": { "authenticationLimit": 25 } }
Paso 2: Actualizar la sesión con los detalles del pedido.
Actualice la sesión con al menos la moneda y el monto del pedido enviando una Update Session.
solicitud desde su servidor. La moneda del pedido es necesaria para que pueda determinar si la tarjeta de crédito que el pagador desea utilizar es compatible y si debe proporcionar su Código de seguridad de tarjeta (CSC).
URL | https://anzworldline.gateway.mastercard.com/api/rest/version/72/merchant/<merchant_ID>/session/<session_ID> |
Método HTTP | PUT |
{ "order": { "amount": 100, "currency": "USD" } }
Paso 3: Incluir la biblioteca Session JavaScript.
Incluya la biblioteca de JavaScript del cliente session.js hospedada por el motor de pagos en su página de pago agregando un elemento script
dentro del elemento head
. La ruta a este campo incluye tanto la versión de la API como el identificador del negocio para la sesión. Al hacerlo se coloca un objeto PaymentSession
en el espacio de nombres de la ventana.
<html> <head> <script src="https://anzworldline.gateway.mastercard.com/form/version/72/merchant/<MERCHANTID>/session.js"></script> </head> </html>
Paso 4: Crear la página de pago
Cree el código HTML para su página de pago, incluidos los campos para recopilar los detalles de pago necesarios del pagador.
readonly
y omita el atributo name
.Puede utilizar uno o más de los siguientes métodos de pago para capturar los detalles de pago del pagador. Los campos que debe incluir en su página de pago dependen del método de pago:
Tarjetas de crédito y débito
Puede capturar los siguientes detalles de la tarjeta en campos alojados:
card.number
card.expiryMonth
card.expiryYear
card.securityCode
card.nameOnCard
card.expiryMonth
, entonces el card.expiryYear
es obligatorio y viceversa.Tarjetas de regalo
Puede capturar los siguientes detalles de la tarjeta de regalo en los campos alojados:
giftCard.number
giftCard.pin
Para obtener más información, consulte Tarjetas de regalo.
Pagos de Automated Clearing House (ACH)
Puede capturar detalles de pago para Pagos directos (pagos) y Depósitos directos (reembolsos) a través de Automated Clearing House. Puede capturar los siguientes Automated Clearing House detalles en campos alojados:
ach.routingNumber
ach.bankAccountNumber
ach.bankAccountNumberConfirmation
ach.bankAccountHolder
ach.accountType
Para obtener más información, consulte Automated Clearing House.
Click to Pay
Puede capturar los detalles de pago desde la interacción de Click to Pay. Para obtener más información, consulte integración de Click to Pay Hosted Session.
El siguiente código de muestra ilustra los campos de la página de pago necesarios para un pago con tarjeta de crédito.
<!-- CREATE THE HTML FOR THE PAYMENT PAGE --> <div> Please enter your payment details: </div> <div> Cardholder Name: <input type="text" id="cardholder-name" class="input-field" title="cardholder name" aria-label="enter name on card" value="" tabindex="1" readonly> </div> <div> Card Number: <input type="text" id="card-number" class="input-field" title="card number" aria-label="enter your card number" value="" tabindex="2" readonly> </div> <div> Expiry Month: <input type="text" id="expiry-month" class="input-field" title="expiry month" aria-label="two digit expiry month" value="" tabindex="3" readonly> </div> <div> Expiry Year: <input type="text" id="expiry-year" class="input-field" title="expiry year" aria-label="two digit expiry year" value="" tabindex="4" readonly> </div> <div> Security Code: <input type="text" id="security-code" class="input-field" title="security code" aria-label="three digit CCV security code" value="" tabindex="5" readonly> </div> <div> <button id="payButton" onclick="pay();"> Pay Now </button> </div>
Paso 5: Configurar la sesión
Invoque la función PaymentSession.configure() con un objeto de configuración como argumento para adjuntar los campos hospedados a su página de pago y configurar la interacción de pago. Debe proporcionar lo siguiente en el objeto de configuración:
- ID de sesión recibido cuando creó la sesión.
- Selectores de campos para campos alojados para métodos de pago específicos. La configuración los reemplaza con los campos proxy correspondientes incrustados en iFrames alojados por Mastercard Gateway. Los campos proxy tienen la misma apariencia que los campos reemplazados.
- Opciones de mitigación para la prevención del clickjacking. El clickjacking, también conocido como "ataque de rectificación de UI", se produce cuando un atacante usa varias capas transparentes u opacas para engañar al usuario y lograr que haga clic en un botón o vínculo en otra página cuando intenta hacer clic en la página del primer nivel. Para utilizar Hosted Session, debe implementar una o más de las siguientes defensas contra ataques de clickjacking y especificar qué defensas se implementan mediante el campo frameEmbeddingMitigation:
- JavaScript: incluya el JavaScript "separador de marcos" en su página de pago.
- Opciones X-Frame: su servidor devuelve un encabezado de respuesta HTTP de opciones X-Frame.
- csp: su servidor devuelve un encabezado de respuesta HTTP de contenido-seguridad-política que contiene una directiva de antecesores de marcos.
Para obtener información sobre cómo defenderse contra ataques de clickjacking, consulte Referencia de defensa contra clickjacking en el sitio web externo OWASP.
- Devoluciones de llamada para administrar diversos eventos durante la interacción de la Hosted Session.
- initialized() se invoca cuando los campos alojados se adjuntan a su página de pago.
- formSessionUpdate() se invoca en respuesta a la función PaymentSession.updateSessionFromForm(paymentType) (consulte el siguiente paso).
- Detalles de interacción que definen la visibilidad y las opciones de interacción con el pagador para cierta información mostrada.
PaymentSession.configure({ session: “<your_session_ID>”, fields: { // ATTACH HOSTED FIELDS TO YOUR PAYMENT PAGE FOR A CREDIT CARD card: { number: “#card-number”, securityCode: “#security-code”, expiryMonth: “#expiry-month”, expiryYear: “#expiry-year”, nameOnCard: “#cardholder-name” } }, //SPECIFY YOUR MITIGATION OPTION HERE frameEmbeddingMitigation: [“javascript”], callbacks: { initialized: function(response) { // HANDLE INITIALIZATION RESPONSE }, formSessionUpdate: function(response) { // HANDLE RESPONSE FOR UPDATE SESSION }, }, interaction: { displayControl: { formatCard: “EMBOSSED”, invalidFieldCharacters: “REJECT” } } });
Paso 6: Actualizar la sesión con detalles del campo
Después de que el pagador haya ingresado sus detalles de pago en los campos alojados, invoque la función PaymentSession.updateSessionFromForm() con el método de pago aplicable como argumento. La función almacena los detalles de pago capturados en la sesión de pago. Una vez finalizada la operación, la devolución de llamada formSessionUpdate() se invoca con un parámetro de resultado. Verifique el campo result.status para determinar si la operación fue exitosa. Para obtener más información, consulte Manejo de respuestas de devolución de llamadas.
function pay() { // UPDATE THE SESSION WITH THE INPUT FROM HOSTED FIELDS PaymentSession.updateSessionFromForm('card'); }
Paso 7: Crear pago usando la sesión
Envíe la transacción de pago (u otra operación relacionada) desde su servidor al motor de pagos utilizando el ID de sesión (session.id) en la solicitud:
- Envíe la solicitud Retrieve Session para verificar los detalles incluidos en la sesión.
- Cree la solicitud de transacción agregando los campos necesarios no incluidos en la sesión.
- Envíe la solicitud de transacción.
Puede enviar múltiples operaciones relacionadas con el pago usando la misma sesión. Por ejemplo, puede iniciar un pago con una operación PAY y almacenar un token que represente los detalles del pago (para usar en transacciones futuras) con la operación Create or Update Token.
Ejemplo de código de página de pago
El siguiente código de muestra ilustra el código HTML de una página de pago completa.
<html> <head> // INCLUDE SESSION.JS JAVASCRIPT LIBRARY <script src="https://anzworldline.gateway.mastercard.com/form/version/<version>/merchant/<merchant_ID>/session.js"></script> // APPLY CLICK-JACKING STYLING AND HIDE CONTENTS OF THE PAGE <style id="antiClickjack">body{display:none !important;}>/style> </head> <body> // CREATE THE HTML FOR THE PAYMENT PAGE <div>Please enter your payment details:</div> <h3>Credit Card</h3> <div>Card Number: <input type="text" id="card-number" class="input-field" title="card number" aria-label="enter your card number" value="" tabindex="1" readonly></div> <div>Expiry Month:<input type="text" id="expiry-month" class="input-field" title="expiry month" aria-label="two digit expiry month" value="" tabindex="2" readonly></div> <div>Expiry Year:<input type="text" id="expiry-year" class="input-field" title="expiry year" aria-label="two digit expiry year" value="" tabindex="3" readonly></div> <div>Security Code:<input type="text" id="security-code" class="input-field" title="security code" aria-label="three digit CCV security code" value="" tabindex="4" readonly></div> <div>Cardholder Name:<input type="text" id="cardholder-name" class="input-field" title="cardholder name" aria-label="enter name on card" value="" tabindex="5" readonly></div> <div><button id="payButton" onclick="pay('card');">Pay Now</button></div> // JAVASCRIPT FRAME-BREAKER CODE TO PROVIDE PROTECTION AGAINST IFRAME CLICK-JACKING <script type="text/javascript"> if (self === top) { var antiClickjack = document.getElementById("antiClickjack"); antiClickjack.parentNode.removeChild(antiClickjack); } else { top.location = self.location; } PaymentSession.configure({ session: "<your_session_ID>", fields: { // ATTACH HOSTED FIELDS TO YOUR PAYMENT PAGE FOR A CREDIT CARD card: { number: "#card-number", securityCode: "#security-code", expiryMonth: "#expiry-month", expiryYear: "#expiry-year", nameOnCard: "#cardholder-name" } }, //SPECIFY YOUR MITIGATION OPTION HERE frameEmbeddingMitigation: ["javascript"], callbacks: { initialized: function(response) { // HANDLE INITIALIZATION RESPONSE }, formSessionUpdate: function(response) { // HANDLE RESPONSE FOR UPDATE SESSION if (response.status) { if ("ok" == response.status) { console.log("Session updated with data: " + response.session.id); //check if the security code was provided by the user if (response.sourceOfFunds.provided.card.securityCode) { console.log("Security code was provided."); } //check if the user entered a Mastercard credit card if (response.sourceOfFunds.provided.card.scheme == 'MASTERCARD') { console.log("The user entered a Mastercard credit card.") } } else if ("fields_in_error" == response.status) { console.log("Session update failed with field errors."); if (response.errors.cardNumber) { console.log("Card number invalid or missing."); } if (response.errors.expiryYear) { console.log("Expiry year invalid or missing."); } if (response.errors.expiryMonth) { console.log("Expiry month invalid or missing."); } if (response.errors.securityCode) { console.log("Security code invalid."); } } else if ("request_timeout" == response.status) { console.log("Session update failed with request timeout: " + response.errors.message); } else if ("system_error" == response.status) { console.log("Session update failed with system error: " + response.errors.message); } } else { console.log("Session update failed: " + response); } } }, interaction: { displayControl: { formatCard: "EMBOSSED", invalidFieldCharacters: "REJECT" } } }); function pay() { // UPDATE THE SESSION WITH THE INPUT FROM HOSTED FIELDS PaymentSession.updateSessionFromForm('card'); } </script> </body> </html>
Devoluciones de llamada de la página de pago
La Hosted Session le permite utilizar varias devoluciones de llamada para personalizar cómo se comporta la página de pago y qué tipo de comentarios proporciona al pagador.
Devoluciones de llamada para la configuración de la sesión
Esta sección define las devoluciones de llamada de configuración de sesión y las respuestas devueltas por sus devoluciones de llamada de resultados. Para ver un ejemplo de cómo manejar las devoluciones de llamada en el código de su página de pago, consulte Ejemplo de código de página de pago.
Las devoluciones de llamada utilizadas en la función PaymentSession.configure():
- La devolución de llamada inicializada (resultado) se invoca cuando los campos alojados se adjuntan a la página de pago:
- Si result.status=="ok", los campos alojados se adjuntan correctamente a su página de pago.
- Si result.status=="system_error" o result.status=="request_timeout", se produjo un error al adjuntar los campos alojados. Vuelva a intentarlo después de un breve retraso.
Ejemplo de respuesta de inicialización exitosa// An ok response { "status":"ok", }
Ejemplo de respuesta de inicialización fallida// An error response (system_error) { "status": "system_error", "message": "System error message." } // An error response (request_timeout) { "status" : "request_timeout", "message": "Request timeout error message." }
- La devolución de llamada formSessionUpdate(result) se invoca cuando el contenido del campo hospedado se almacena en la sesión:
- Si result.status=="ok", la sesión ahora contiene los detalles de pago recopilados.
Ejemplo de actualización de sesión de formulario para una respuesta correcta// An ok response { "status":"ok", "merchant": "TESTMERCHANT", "session": { "id": "SESSION000218450948092491657986" "updateStatus":"SUCCESS", "version":"e3f144ce02" }, "sourceOfFunds": { "provided": { "card": { "brand": "MASTERCARD", "expiry": { "month": "1", "year": "39" }, "fundingMethod": "DEBIT", "nameOnCard": "John Smith", "number": "512345xxxxxx8769", "scheme": "MASTERCARD" } }, "type": "CARD" }, "version": "43" }
- Si result.status=="fields_in_error", la entrada del pagador no es válida. Solicite al pagador que actualice su entrada. La estructura de respuesta errors contiene información acerca de los campos no válidos.
- Si result.status=="system_error" o result.status=="request_timeout", se ha producido un error al procesar la actualización. Vuelva a intentar la actualización de la sesión después de un breve retraso.
// An error response (fields_in_error) { "status": "fields_in_error", "session": { "id": "SESSION000218450948092491657986" }, "errors": { "cardNumber": "invalid", "securityCode": "invalid" }, version: "43" }
// An error response (system_error) { "status": "system_error", "session": { "id": "SESSION000218450948092491657986" }, "errors": { "message": "System error message." }, "version": "43" } // An error response (request_timeout) { "status": "request_timeout", "session": { "id": "SESSION000218450948092491657986" }, "errors": { "message": "Request timeout error message." }, "version": "43" }
Devoluciones de llamada para campos hospedados
La Hosted Session le permite registrar funciones de devolución de llamada para administrar eventos que pueden ocurrir en los campos hospedados durante la interacción del pagador. Los eventos le permiten realizar un seguimiento de lo que está haciendo el pagador y brindarle comentarios de validación durante varias etapas de interacción de pago.
Puede registrar funciones de devolución de llamada para los siguientes eventos:
- onChange(): se invoca cuando el valor de entrada en el campo hospedado en iFrame ha cambiado.
- onFocus(): se invoca cuando el campo hospedado en iFrame ha obtenido enfoque.
- onBlur(): se invoca cuando el campo hospedado en iFrame ha perdido enfoque. Una vez que el pagador haya terminado de escribir y abandone el campo, y se active este evento, invoque la función validate() y muestre cualquier error para el campo desde la devolución de llamada de la función validate().
- onMouseOver(): se invoca cuando el mouse se posa sobre un elemento en el campo hospedado.
- onMouseOut(): se invoca cuando se produce un evento de cursor fuera en el campo hospedado.
- onValidityChange(): se invoca después de cada pulsación de tecla del pagador, proporcionando información sobre la validez de la entrada de datos del pagador hasta el momento.
/** * Provide an array of field roles for proxy fields as the first parameter * Each callback function is invoked with the selector for the field whose proxy triggered the event. */ PaymentSession.onBlur( ["card.number", "card.nameOnCard", "card.securityCode", "card.expiryYear", "card.expiryMonth"], function (selector, role) { PaymentSession.validate('card', function (allresult) { if (allresult.card[role].isValid) { console.log("The field is valid"); document.querySelector(selector).style.borderColor = "green"; } else { console.log("The field is invalid"); document.querySelector(selector).style.borderColor = "red"; } }); PaymentSession.onFocus(['card.number', 'card.securityCode'], function(selector) { //handle focus event }); PaymentSession.onChange(['card.securityCode'], function(selector) { //handle change event }); PaymentSession.onMouseOver(['card.number'], function(selector) { //handle mouse over event }); PaymentSession.onMouseOut(['card.number'], function(selector) { //handle mouse out event }); PaymentSession.onValidityChange(["card.number", "card.nameOnCard"], function (selector, result) { if (result.isValid) { console.log("The field value is valid"); document.querySelector(selector).style.borderColor = "green"; } else if (result.isIncomplete) { console.log("The field value is not yet valid"); document.querySelector(selector).style.borderColor = "grey"; } else { console.log("The field value is invalid"); document.querySelector(selector).style.borderColor = "red"; } });
Preguntas frecuentes
¿Cómo manejo una situación en que el tipo de tarjeta que ingresa el pagador no es compatible con mi perfil del negocio?
Para manejar este evento, primero use la operación PAYMENT OPTIONS INQUIRY para obtener una lista de los tipos de tarjetas admitidos. Luego, inspeccione la información del tipo de tarjeta (sourceOfFunds.provided.card.brand y sourceOfFunds.provided.card.scheme) en la respuesta PaymentSession.updateSessionFromForm('card'), valídela con la lista de tipos de tarjetas admitidos y muestre un mensaje de error, si el tipo de tarjeta no es aceptado.
¿Cómo sé si se necesita y se ha proporcionado el CSC o CVV del pagador?
Para saber si se requiere CSC o CVV, utilice la operación PAYMENT OPTIONS INQUIRY. Si el pagador no proporciona un CSC/CVV, el campo securityCode NO se devuelve en la respuesta PaymentSession.updateSessionFromForm('card'). Si necesita un CSC/CVV y no hay ningún valor presente, debe mostrar un error al pagador.
¿Las devoluciones de llamada de eventos para campos hospedados funcionan en todos los exploradores?
Existen problemas conocidos con devoluciones de llamada de eventos en los siguientes sistemas operativos y exploradores:
- Internet Explorer 11 en Windows 10: Si interaction.displayControl.formatCard=EMBOSSED, el evento onChange() no se activa cuando cambia el valor de un campo hospedado.
- iOS9 en iPhone 6+: Los eventos onChange() y onBlur() no se activan cuando el pagador ingresa datos en un campo alojado y toca otro campo en la página de pago. Además, el pagador no puede navegar desde campos hospedados a otros campos en la página de pago y viceversa.