Página de pago de la tienda virtual con autenticación 3DS.

Después de realizar el paso de creación de la transacción, se debe mostrar la página del comerciante al usuario. En esta página, con integración de pago mediante JavaScript y autenticación 3DS 2.0, es crucial incluir dos archivos en la página de pago: un script JS y una hoja de estilo CSS. Estos dos archivos son esenciales para asegurar que el pago con autenticación 3DS 2.0 funcione correctamente. Además de estos archivos, es necesario agregar una etiqueta HTML a la página de pago (esta etiqueta HTML se utilizará en caso de que se produzca el flujo de 3DS method).

A continuación, se muestran las URL para descargar:

Script JS#

A continuación se encuentran las URL de homologación y producción para descargar:

URL para el entorno de producción:

https://esitef.softwareexpress.com.br/js/esitefauthenticatepayment-1.0.min.js

URL para el entorno de Homologación:

https://esitef-homologacao.softwareexpress.com.br/js/esitefauthenticatepayment-1.0.min.js

Hoja de estilo CSS#

A continuación se encuentran las URLs de homologación y producción para descargar:

URL para el entorno de producción:

https://esitef.softwareexpress.com.br/css/v2/threeds.css

URL para el entorno de Homologación:

https://esitef-homologacao.softwareexpress.com.br/css/v2/threeds.css

Tag div#

A continuación se encuentra la etiqueta div obligatoria para el funcionamiento del método 3DS:

<div id="divThreeDsMethodData"></div>

Los campos de la tarjeta deben contener las clases especificadas a continuación:

ParâmetroDescripciónFormatoObrigatório
esitef-cardnumberNúmero de la tarjeta del comprador (PAN).< 19 N
esitef-cardexpirydateFecha de vencimiento de la tarjeta en formato MMAA.= 4 N
esitef-cardexpirymonth
& esitef-cardexpiryyear
Mes y año de vencimiento de la tarjeta, en los formatos MM y AA, respectivamente. Estos campos pueden enviarse en lugar de esitef-cardexpirydate. Si se envían todos al mismo tiempo, la fecha separada (esitef-cardexpirymonth y esitef-cardexpiryyear) tendrá prioridad.= 2 N
esitef-cardsecuritycodeCódigo de seguridad de la tarjeta.< 5 N
esitef-cardholderNombre del titular de la tarjeta. Obligatorio solo para pagos con e-Rede, GetNet WS y VR AN (SmartNet).< 30 ANCOND.

Se deben llamar a dos funciones durante el proceso de pago:

startThreeDsDetalles de la llamada : Esta función debe ser llamada mediante un evento después de completar la entrada de la tarjeta; inicia el 3DS y, dependiendo del bin, puede realizar la llamada al método 3DS si es necesario.

esitefDoPaymentDetalles de la llamada : Esta función debe ser llamada mediante un evento después de completar todos los datos necesarios para finalizar el proceso de pago. Esta llamada iniciará la autenticación 3DS; en algunos casos, el emisor puede solicitar un desafío que el comprador debe realizar. En este escenario, se abrirá un modal con el desafío correspondiente. En este caso, el comerciante debe redirigir el final de la solicitud a una pantalla de procesamiento y esperar la respuesta del aviso de estado.

A continuación, se muestra un ejemplo de una página integrada con el pago JavaScript de Carat:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Coleta de dados de cartão via JS</title>
<script type="text/javascript"
src="https://esitef-homologacao.softwareexpress.com.br/js/esitefauthenticatepayment-1.0.min.js"></script>
<script type="text/javascript"
src="https://esitef-homologacao.softwareexpress.com.br/lojateste/loja/js/lib/jquery.min.js"></script>
<script type="text/javascript"
src="https://esitef-homologacao.softwareexpress.com.br/lojateste/loja/js/lib/jquery.payment.js"></script>
<script type="text/javascript"
src="https://esitef-homologacao.softwareexpress.com.br/lojateste/loja/js/lib/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://esitef-homologacao.softwareexpress.com.br/css/v2/style.css">
<link rel="stylesheet" href="https://esitef-homologacao.softwareexpress.com.br/css/font-awesome.min.css"/>
<link rel="stylesheet" href="https://esitef-homologacao.softwareexpress.com.br/css/v2/payment.css">
<link rel="stylesheet" href="https://esitef-homologacao.softwareexpress.com.br/css/v2/payment-credit.css"/>
<link rel="stylesheet" href="https://esitef-homologacao.softwareexpress.com.br/css/v2/bootstrap.min.css"/>
<link rel="stylesheet" href="https://esitef-homologacao.softwareexpress.com.br/css/v2/error.css">
<link rel="stylesheet" href="https://esitef-homologacao.softwareexpress.com.br/css/v2/authentication.css">
<link rel="stylesheet" href="https://esitef-homologacao.softwareexpress.com.br/css/v2/threeds.css"/>
<script type="text/javascript">
$(document).ready(function() {
/* limpa cartao da consulta bin */
$("#card-number").val('');
$("#bin-card-expiration-month").val('');
$("#bin-card-expiration-year").val('');
$("#bin-security-code").val('');
$(".payment-checked-number").hide();
$(".payment-error-number").hide();
$(".bin-payment-checked-due").hide();
$(".bin-payment-error-due").hide();
$(".bin-payment-checked-security-code").hide();
$(".bin-payment-error-security-code").hide();
$(".payment-checked-holdername").hide();
$(".payment-error-holdername").hide();
$("#card-number").removeClass('has-error-input');
$('#card-number').payment('restrictNumeric');
/* inicializacao das restricoes dos campos */
$('#bin-card-expiration-year').payment('restrictNumeric');
$('#bin-card-expiration-month').payment('restrictNumeric');
$('#bin-security-code').payment('restrictNumeric');
$("#bin-security-code").payment('formatCardCVC');
$("#card-number").on('blur', function() {
result = isFieldSizeValid($(this).val(), 16, null);
updateIconSignAndInput("#card-number", ".payment-checked-number", ".payment-error-number", (result));
if(result){
threedMethod();
}
enableConfirmButton(result);
});
$('#bin-security-code').on('blur', function() {
result = isFieldSizeValid($(this).val(), 3, null);
updateIconSignAndInput("#bin-security-code", ".bin-payment-checked-security-code", ".bin-payment-error-security-code", result);
});
$('#bin-security-code').on('keyup', function() {
result = isFieldSizeValid($(this).val(), 3, null);
updateIconSignAndInput("#bin-security-code", ".bin-payment-checked-security-code", ".bin-payment-error-security-code", result);
$(this).removeClass("has-error-input");
/* Mostra o check verdinho e muda o foco pro proximo campo */
if ($(this).val().length == 4) {
updateIconSignAndInput("#bin-security-code", ".bin-payment-checked-security-code", ".bin-payment-error-security-code", true);
}
enableConfirmButton(result);
});
$('#bin-card-expiration-month').on('keyup', function() {
var cleanedValue = $(this).val().replace(/[^0-9]+/g, '');
$(this).val(cleanedValue);
if ($(this).val().length == 2) {
$("#bin-card-expiration-year").focus();
}
enableConfirmButton(result);
});
$("#bin-card-expiration-month").on('blur', function() {
result = isFieldSizeValid($(this).val(), 2, null);
resultMonth = isValidMonth($(this).val());
updateIconSignAndInput("#bin-card-expiration-month", ".bin-payment-checked-due", ".bin-payment-error-due", (result && resultMonth));
/* caso especial para data de vencimento */
if (!isFieldSizeValid($("#bin-card-expiration-year").val(), 2, null)) {
$(".bin-payment-checked-due").hide();
$(".bin-payment-error-due").show();
}
enableConfirmButton(result);
});
$('#bin-card-expiration-year').on('keyup', function() {
var cleanedValue = $(this).val().replace(/[^0-9]+/g, '');
$(this).val(cleanedValue);
result = isFieldSizeValid($(this).val(), 2, null);
updateIconSignAndInput("#bin-card-expiration-year", ".bin-payment-checked-due", ".bin-payment-error-due", result);
enableConfirmButton(result);
});
$('#bin-card-expiration-year').on('blur', function() {
result = isFieldSizeValid($(this).val(), 2, null);
updateIconSignAndInput("#bin-card-expiration-year", ".bin-payment-checked-due", ".bin-payment-error-due", result);
/* caso especial para data de vencimento */
if (!isValidMonth($("#bin-card-expiration-month").val()) || !isFieldSizeValid($("#bin-card-expiration-month").val(), 2, null)) {
$(".bin-payment-checked-due").hide();
$(".bin-payment-error-due").show();
}
enableConfirmButton(result);
});
$("#card-holdername").on('blur', function() {
result = isFieldSizeValid($(this).val(), 1, null);
updateIconSignAndInput("#card-holdername", ".payment-checked-holdername", ".payment-error-holdername", (result));
enableConfirmButton(result);
});
});
function enableConfirmButton(result){
if (result && isAllFieldsOK()) {
$(".step-confirm").prop("disabled", false);
} else {
$(".step-confirm").prop("disabled", true);
}
}
function updateIconSignAndInput(inputSelector, iconSelectorOK, iconSelectorError, validation) {
if (validation) {
$(iconSelectorOK).show();
$(iconSelectorError).hide();
$(inputSelector).removeClass("has-error-input");
} else {
$(iconSelectorOK).hide();
$(iconSelectorError).show();
$(inputSelector).addClass("has-error-input");
}
}
function resetIconSignAndInput(inputSelector, iconSelectorOK, iconSelectorError, validation) {
$(iconSelectorOK).hide();
$(iconSelectorError).hide();
$(inputSelector).removeClass("has-error-input");
}
function isFieldSizeValid(value, minSize, maxSize) {
if (value.length >= minSize) {
/* verifica se maxSize foi passado nao nulo */
if (maxSize) {
if (value.length <= maxSize) {
return true;
} else {
return false;
}
}
return true;
}
return false;
}
function isValidMonth(value) {
if (value <= 12 && value > 0) {
return true;
}
return false;
}
function isAllFieldsOK() {
if ($("#card-number").is(":visible")
&& !$(".payment-checked-number").is(":visible")) {
return false;
}
if ($("#bin-card-expiration-year").is(":visible")
&& !$(".bin-payment-checked-due").is(":visible")) {
return false;
}
if ($("#bin-security-code").is(":visible")
&& !$(".bin-payment-checked-security-code").is(":visible")) {
return false;
}
if ($("#card-expiration-year").is(":visible")
&& $("#card-expiration-year").val().length < 2) {
return false;
}
if ($("#card-expiration-month").is(":visible")
&& $("#card-expiration-month").val().length < 2) {
return false;
}
if ($("#security-code").is(":visible")
&& $("#security-code").val().length < 3) {
return false;
}
if ($("#card-holdername").is(":visible")
&& $("#card-holdername").val().length == 0) {
return false;
}
return true;
}
function findGetParameter(parameterName) {
var result = null,
tmp = [];
var items = location.search.substr(1).split("&");
for (var index = 0; index < items.length; index++) {
tmp = items[index].split("=");
if (tmp[0] === parameterName) result = decodeURIComponent(tmp[1]);
}
return result;
}
function myPay() {
var request = {
onSuccess: function(response) {
var responseValue = JSON.stringify(response);
localStorage.setItem('resultSuccess', responseValue);
if (response.payment.status == 'PPC') {
window.location = 'loja-pag-pendente-3ds-mpi.html?nit='+ findGetParameter('nit');
} else {
window.location = 'loja-sucesso-3ds-mpi.html';
}
},
onProcessing: function() {
window.location = 'loja-pag-pendente-3ds-mpi.html?nit='+ findGetParameter('nit');
},
onFailure: function(response) {
var responseValue = JSON.stringify(response);
localStorage.setItem('resultFailure', responseValue);
window.location = 'loja-fracasso-js.html';
},
onInvalid: function(response) {
var message = response[0].field + ' ' + response[0].cause;
for (var i = 1; i < response.length; i++) {
message += ', ' + response[i].field + ' ' + response[i].cause;
}
document.getElementById('resultInvalid').innerHTML = message;
},
nit: findGetParameter('nit'),
payToken: findGetParameter('payToken'),
merchantId: findGetParameter('merchantId'),
authenticate: 'true'
};
esitefDoPayment(request);
}
function threedMethod() {
var request = {
onSuccess: function(response) {
var responseValue = JSON.stringify(response);
},
onFailure: function(response) {
var responseValue = JSON.stringify(response);
console.log("Error 3ds method: "+ responseValue);
},
onInvalid: function(response) {
var message = response[0].field + ' ' + response[0].cause;
for (var i = 1; i < response.length; i++) {
message += ', ' + response[i].field + ' ' + response[i].cause;
}
document.getElementById('resultInvalid').innerHTML = message;
},
nit: findGetParameter('nit'),
payToken: findGetParameter('payToken'),
merchantId: findGetParameter('merchantId'),
authorizerId: findGetParameter('authorizerId')
};
startThreeDs(request);
}
</script>
</head>
<body>
<form id="pagamentoForm" name="pagamentoForm" method="POST">
<div class="row">
<div class="payment-input col-md-12 col-sm-12 col-xs-12" id="payment-input-card" style="">
<div class="payment-input-box payment-input-box-pf col-md-offset-2 col-sm-offset-1 col-md-10 col-sm-10 col-xs-12">
<div class="row">
<div class="input-title col-md-12 col-sm-12">
<span class="glyphicon glyphicon-credit-card input-title-icon col-md-1 col-sm-1 col-xs-1"></span>
<span class="input-title-value">Informe os dados do seu cartão</span>
</div>
</div>
<div class="input-box-left col-md-6 col-sm-7 col-xs-12 ">
<div class="row" id="cardnumber-box">
<div class="input-card-number col-md-11 col-sm-11 col-xs-12">
<label for="card-number" class="col-md-12 col-sm-12 col-xs-12 input-label">
Número do Cartão *
</label>
<div class="col-md-7 col-sm-7 col-xs-10 box-card-number">
<input type="tel" id="card-number" maxlength="19" autocomplete="off"
placeholder="•••• •••• •••• ••••"
class="form-control col-md-5 col-sm-5 col-xs-5 esitef-cardnumber">
</div>
<span class="glyphicon glyphicon-ok col-md-1 col-sm-1 col-xs-1 payment-checked payment-checked-number"
style="display: block;"></span>
<span class="fa fa-exclamation col-md-1 col-sm-1 col-xs-1 payment-error payment-error-number"
style="display: none;"></span>
</div>
</div>
<div id="box-dados-extra-cartao">
<div class="row">
<div id="input-bin-due-date-security-code"
class="input-bin-due-date-security-code col-md-6 col-sm-6 col-xs-12">
<label for="bin-card-expiration-month"
class="col-md-12 col-sm-12 col-xs-12 input-label input-label-due">Data de
Validade&nbsp;<span data-toggle="tooltip" data-placement="top" title=""
data-original-title="A data de validade está localizada na frente do seu cartão. Informe o mês e o ano (MM/AA).">[?]</span>
</label>
<div class="col-md-4 col-sm-5 col-xs-5 box-due-date">
<input type="tel" class="form-control esitef-cardexpirymonth" autocomplete="off"
id="bin-card-expiration-month" placeholder="••" maxlength="2">
</div>
<span class="col-md-1 col-sm-1 col-xs-2 bar-due">/</span>
<div class="col-md-4 col-sm-5 col-xs-5 box-due-date">
<input type="tel" class="form-control esitef-cardexpiryyear" autocomplete="off"
id="bin-card-expiration-year" placeholder="••" maxlength="2">
</div>
<span id="bin-payment-checked-due"
class="glyphicon glyphicon-ok col-md-1 col-sm-1 col-xs-1 payment-checked bin-payment-checked-due"
style="display: block;"></span>
<span id="bin-date-checked-error"
class="fa fa-exclamation col-md-1 col-sm-1 col-xs-1 payment-error bin-payment-error-due"
style="display: none;"></span>
</div>
<div id="input-bin-security-code"
class="input-bin-security-code col-md-6 col-sm-6 col-xs-12">
<label for="bin-security-code"
class="col-md-12 col-sm-12 col-xs-12 input-label input-bin-label-security-code">Código
de segurança
<span id="bin-security-code-tooltip" data-toggle="tooltip" data-placement="top"
title=""
data-original-title="<div><p style='font-weight: bold; margin: 0 0 0 1rem;'>Código de segurança</p><div style='display: flex; text-align: center; align-items: center;'><img src='/images/v2/tooltip-security-in.png' class='img-responsive'/><p>Número de <span style='color:red;' >3 a 4 dígitos </span> no verso do cartão</p></div></div>"> [?] </span>
</label>
<div class="box-bin-security-code col-md-4 col-sm-5 col-xs-11">
<input type="tel"
class="col-md-5 col-sm-5 col-xs-5 form-control esitef-cardsecuritycode"
id="bin-security-code" maxlength="5" autocomplete="off" placeholder="•••">
</div>
<span id="bin-security-code-checked-ok"
class="glyphicon glyphicon-ok col-md-1 col-sm-1 col-xs-1 payment-checked bin-payment-checked-security-code"
style="display: block;"></span>
<span id="bin-security-code-checked-error"
class="fa fa-exclamation col-md-1 col-sm-1 col-xs-1 payment-error bin-payment-error-security-code"
style="display: none;"></span>
</div>
</div>
</div>
<div class="row" id="cardholdername-box">
<div class="input-card-holdername col-md-11 col-sm-11 col-xs-12">
<label for="card-holdername" class="col-md-12 col-sm-12 col-xs-12 input-label">
Nome(com está no cartão) *
</label>
<div class="col-md-7 col-sm-7 col-xs-10 box-card-holdername">
<input type="tel" id="card-holdername" autocomplete="off"
class="form-control col-md-5 col-sm-5 col-xs-5 esitef-cardholder">
</div>
<span class="glyphicon glyphicon-ok col-md-1 col-sm-1 col-xs-1 payment-checked payment-checked-holdername"
style="display: block;"></span>
<span class="fa fa-exclamation col-md-1 col-sm-1 col-xs-1 payment-error payment-error-holdername"
style="display: none;"></span>
</div>
</div>
</div>
<div class="input-box-right col-md-4 col-sm-5 col-xs-12">
<div class="row visible-xs col-xs-12">
<div class="cod-xs-12 site-seguro-dados-cartao">
<img src="/images/v2/site-seguro-icon.png"
class="site-seguro-dados-cartao-card-icon img-responsive" alt="SITE 100% SEGURO">
<span>SITE 100% SEGURO</span>
</div>
</div>
<div class="col-md-12 col-sm-12 col-xs-12 step-button-submit payment-button-submit ">
<button type="button" id="step-confirm" onclick="myPay()"
class="step-confirm btn btn-success col-md-12 col-sm-12 col-xs-12 btn-loader"
disabled="">
CONFIRMAR PAGAMENTO
<span class="glyphicon glyphicon-menu-right step-confirm-icon step-confirm-icon-payment"
aria-hidden="true"></span>
</button>
<div class="col-md-12 col-sm-12 col-xs-12 next-step-container">
<span class="next-step">
Próximo Passo:
</span>
<span id="nextStepValue" class="next-step-value">
&nbsp;
Validação de Pagamento
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
<p id="resultInvalid" style="color:red"></p>
<div id="divThreeDsMethodData">
</div>
<div class="modal fade" id="myModal" role="dialog" tabindex="-1" aria-labelledby="exampleModalLabel" aria-modal="true">
</div>
</body>
</html>

Puntos importantes de la implementación del ejemplo anterior:

  • Importación del js para la autenticación 3DS:
<script type="text/javascript" src="https://esitef-homologacao.softwareexpress.com.br/js/esitefauthenticatepayment-1.0.min.js"></script>
  • Importación del css para la autenticación 3DS:
<link rel="stylesheet" href="https://esitef-homologacao.softwareexpress.com.br/css/v2/threeds.css" />
  • Llamada a la función. Más información. (la llamada está dentro de la función threedMethod) al completar el campo de número de tarjeta con un tamaño de 16:
$("#card-number").on('blur', function() {
result = isFieldSizeValid($(this).val(), 16, null);
updateIconSignAndInput("#card-number", ".payment-checked-number", ".payment-error-number", (result));
if(result){
threedMethod();
}
enableConfirmButton(result);
});
  • Implementación de la creación de la solicitud y llamada a startThreeDs:
function threedMethod() {
var request = {
onSuccess: function(response) {
var responseValue = JSON.stringify(response);
},
onFailure: function(response) {
var responseValue = JSON.stringify(response);
console.log("Error 3ds method: "+ responseValue);
},
onInvalid: function(response) {
var message = response[0].field + ' ' + response[0].cause;
for (var i = 1; i < response.length; i++) {
message += ', ' + response[i].field + ' ' + response[i].cause;
}
document.getElementById('resultInvalid').innerHTML = message;
},
nit: findGetParameter('nit'),
payToken: findGetParameter('payToken'),
merchantId: findGetParameter('merchantId'),
authorizerId: findGetParameter('authorizerId')
};
startThreeDs(request);
}
  • Implementación de la creación de la solicitud y llamada de esitefDoPayment:
function myPay() {
var request = {
onSuccess: function(response) {
var responseValue = JSON.stringify(response);
localStorage.setItem('resultSuccess', responseValue);
if (response.payment.status == 'PPC') {
window.location = 'loja-pag-pendente-3ds-mpi.html?nit='+ findGetParameter('nit');
} else {
window.location = 'loja-sucesso-3ds-mpi.html';
}
},
onProcessing: function() {
window.location = 'loja-pag-pendente-3ds-mpi.html?nit='+ findGetParameter('nit');
},
onFailure: function(response) {
var responseValue = JSON.stringify(response);
localStorage.setItem('resultFailure', responseValue);
window.location = 'loja-fracasso-js.html';
},
onInvalid: function(response) {
var message = response[0].field + ' ' + response[0].cause;
for (var i = 1; i < response.length; i++) {
message += ', ' + response[i].field + ' ' + response[i].cause;
}
document.getElementById('resultInvalid').innerHTML = message;
},
nit: findGetParameter('nit'),
payToken: findGetParameter('payToken'),
merchantId: findGetParameter('merchantId'),
authenticate: 'true'
};
esitefDoPayment(request);
}
  • Implementación de la div con id ="divThreeDsMethodData" para la ejecución del método 3DS:
<div id ="divThreeDsMethodData"></div>