UNPKG

payment-token-efi

Version:

Módulo Javascript que permite a criptografia dos dados do cartão do cartão a partir do browser do cliente para gerar o payment_token e identificar a bandeira do cartão.

424 lines (372 loc) 26.6 kB
<!doctype html> <html lang="pt-br"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link id="favicon" href="./assets/img/favicon.png" rel="shortcut icon" type="image/png"> <title>Exemplo Payment Token | Efí</title> <!-- CSS --> <link href="./assets/css/bootstrap.min.css" rel="stylesheet"> <link href="./assets/css/custom.css" rel="stylesheet"> <!-- Script --> <script src="./dist/payment-token-efi-umd.min.js"></script> <script> document.addEventListener('DOMContentLoaded', () => { // Aguarda o carregamento da página para iniciar os scripts // Configuração var inputIdentificadorConta = document.getElementById("identificadorConta"); var inputValorTotal = document.getElementById("valorTotal"); // Dados cartão var inputNumeroCartao = document.getElementById("numeroCartao"); var inputBandeira = document.getElementById("bandeira"); var inputMesVencimento = document.getElementById("mesVencimento"); var inputAnoVencimento = document.getElementById("anoVencimento"); var inputCvv = document.getElementById("cvv"); var inputNomeTitular = document.getElementById("nomeTitular"); var inputDocumentoTitular = document.getElementById("documentoTitular"); // Resultados var inputParcelas = document.getElementById("opcoesParcelamento"); var inputPaymentToken = document.getElementById("paymentToken"); var inputmascaraCartao = document.getElementById("mascaraCartao"); // Botão de acionamento var btnGerarToken = document.getElementById("gerarPaymentToken"); const efi = EfiPay.CreditCard; efi .debugger(true) .setEnvironment('sandbox') // 'production' or 'sandbox'; inputNumeroCartao.addEventListener("input", async function () { /* * Identifica a bandeira a partir do número do cartão * @params { numeroCartao } */ if (inputNumeroCartao.value.length >= 15) { try { resultBandeira = await efi .setCardNumber(inputNumeroCartao.value) .verifyCardBrand(); inputBandeira.value = resultBandeira; buscarParcelamemto(resultBandeira); // aciona a função para buscar as opções de parcelamento } catch (error) { alert(`Erro ao obter a bandeira!\n\nCódigo: ${error.code}\nNome: ${error.error}\nMensagem: ${error.error_description}`); console.warn(`Algo deu errado ao verificar a bandeira.\n ${error}`); } } /* * FIM - Identifica a bandeira a partir do número do cartão */ }); async function buscarParcelamemto(bandeira) { /* * Retorna as informações de parcelamento * @params { identificadorConta, ambiente, bandeira, valorTotal } */ try { const resultParcelas = await efi .setAccount(inputIdentificadorConta.value) .setBrand(bandeira) .setTotal(parseInt(inputValorTotal.value)) .getInstallments(); const opcoes = resultParcelas.installments.map(installment => ` <option value="${installment.installment}"> ${installment.installment} x de R$${installment.currency} ${installment.has_interest === false ? "sem juros" : ""} </option>` ).join(''); inputParcelas.innerHTML = `<option value="0">Escolha como deseja pagar</option>${opcoes}`; } catch (error) { alert(`Erro ao buscar as parcelas!\n\nCódigo: ${error.code}\nNome: ${error.error}\nMensagem: ${error.error_description}`); throw new Error(`Something went wrong.\n ${error}`); } /* * FIM - Retorna as informações de parcelamento */ } btnGerarToken.addEventListener("click", async function () { btnGerarToken.classList.add('disabled'); btnGerarToken.innerHTML = '<div class="spinner-border spinner-border-sm text-info" role="status"> <span class="visually-hidden">Loading...</span></div>'; /* * Retorna o payment_token e card_mask * @params { identificadorConta, ambiente, {bandeira, numeroCartao, cvv, mesVencimento, anoVencimento, reuse} } */ try { const resultPaymentToken = await efi .setAccount(inputIdentificadorConta.value) .setCreditCardData({ brand: inputBandeira.value, number: inputNumeroCartao.value, cvv: inputCvv.value, expirationMonth: inputMesVencimento.value, expirationYear: inputAnoVencimento.value, holderName: inputNomeTitular.value, holderDocument: inputDocumentoTitular.value, reuse: false }) .getPaymentToken(); let payment_token = resultPaymentToken.payment_token; let card_mask = resultPaymentToken.card_mask; inputPaymentToken.value = payment_token; mascaraCartao.value = card_mask; btnGerarToken.classList.remove('btn-primary'); btnGerarToken.classList.add('btn-success'); btnGerarToken.innerHTML = 'Gerar novamente'; btnGerarToken.classList.remove('disabled'); } catch (error) { alert(`Erro ao buscar ao gerar o payment_token!\n\nCódigo: ${error.code}\nNome: ${error.error}\nMensagem: ${error.error_description}`); btnGerarToken.innerHTML = 'Gerar payment_token'; btnGerarToken.classList.remove('disabled'); throw new Error(`Something went wrong.\n ${error}`); } /* * FIM - Retorna o payment_token e card_mask */ }); inputValorTotal.addEventListener("input", function () { if (inputIdentificadorConta.value.length === 32 && inputNumeroCartao.value.length >= 16 && inputValorTotal.value.length >= 3) { buscarParcelamemto(inputBandeira.value); } }); inputIdentificadorConta.addEventListener("input", function () { if (inputIdentificadorConta.value.length === 32 && inputNumeroCartao.value.length >= 16) { buscarParcelamemto(inputBandeira.value); } }); inputParcelas.addEventListener("change", function () { btnGerarToken.classList.remove('disabled'); }); const populateYears = (selectId, range) => { const nextYear = new Date().getFullYear() + 1; const selectElement = document.getElementById('anoVencimento'); for (let i = 0; i <= range; i++) { const year = nextYear + i; const option = document.createElement("option"); option.value = year; option.textContent = year; selectElement.appendChild(option); } } populateYears('anoVencimento', 10); }); </script> </head> <body> <div class="container"> <header class="d-flex flex-wrap justify-content-center py-2 mb-2"> <a href="" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-dark text-decoration-none"> <img style="height: 80px;" src="./assets/img/logo-ef.svg" alt="Logo Efí"> </a> <ul class="nav nav-pills"> <li class="nav-item"> <a href="https://github.com/efipay/frontend-payment-token-efi" target="_blank" class="nav-link">Github</a> </li> <li class="nav-item"> <a href="https://dev.sejaefi.com.br/docs/pagamento-com-cartao#1-obten%C3%A7%C3%A3o-do-payment_token" target="_blank" class="nav-link">Documentação</a> </li> <li class="nav-item"> <a href="https://comunidade.sejaefi.com.br/" target="_blank" class="nav-link">Comunidade</a> </li> </ul> <div class="py-2 text-center"> <h2>Página de demonstração - Gerar payment_token</h2> <p class="lead">Um payment_token é um conjunto de caracteres gerado de forma segura pela API Efí que representa os dados do cartão de crédito do pagador.</p> </div> </header> <main> <form method="POST" action="./" novalidate> <!-- Início - Configuração para funcionamento do script - Identificador de conta --> <!-- Veja aqui onde oncontrá-lo: https://sejaefi.link/rJeE-NNOm2 --> <h4 class="mb-3">Configuração</h4> <div class="row"> <div class="col-md-8"> <label for="identificadorConta" class="form-label">Identificador de conta * <code data-bs-toggle="tooltip" data-bs-placement="top" title="(String - '00000000000000000000000000000000')"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16"> <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/> <path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/> </svg> </code> <code> <a target="_blank" href="./assets/img/local-identificador-de-conta.png"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-link-45deg" viewBox="0 0 16 16"> <path d="M4.715 6.542 3.343 7.914a3 3 0 1 0 4.243 4.243l1.828-1.829A3 3 0 0 0 8.586 5.5L8 6.086a1.002 1.002 0 0 0-.154.199 2 2 0 0 1 .861 3.337L6.88 11.45a2 2 0 1 1-2.83-2.83l.793-.792a4.018 4.018 0 0 1-.128-1.287z"/> <path d="M6.586 4.672A3 3 0 0 0 7.414 9.5l.775-.776a2 2 0 0 1-.896-3.346L9.12 3.55a2 2 0 1 1 2.83 2.83l-.793.792c.112.42.155.855.128 1.287l1.372-1.372a3 3 0 1 0-4.243-4.243L6.586 4.672z"/> </svg>onde encontro?</a> </code> </label> <input type="text" class="form-control" name="identificadorConta" id="identificadorConta" required> </div> <div class="col-md-4"> <label for="valorTotal" class="form-label">Valor total * <code data-bs-toggle="tooltip" data-bs-placement="top" title="(Integer) Ex: '24990' equivale a R$249,90"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16"> <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/> <path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/> </svg> </code> </label> <input type="number" class="form-control" name="valorTotal" id="valorTotal" value="24990" required> </div> </div> <!-- Fim - Configuração para funcionamento do script - Identificador de conta --> <hr> <!-- Início - Inputs com informações do cartão de crédito --> <h4 class="mb-3">Informação do cartão <code> <a target="_blank" href="https://www.invertexto.com/gerador-de-cartao-de-credito"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-link-45deg" viewBox="0 0 16 16"> <path d="M4.715 6.542 3.343 7.914a3 3 0 1 0 4.243 4.243l1.828-1.829A3 3 0 0 0 8.586 5.5L8 6.086a1.002 1.002 0 0 0-.154.199 2 2 0 0 1 .861 3.337L6.88 11.45a2 2 0 1 1-2.83-2.83l.793-.792a4.018 4.018 0 0 1-.128-1.287z"/> <path d="M6.586 4.672A3 3 0 0 0 7.414 9.5l.775-.776a2 2 0 0 1-.896-3.346L9.12 3.55a2 2 0 1 1 2.83 2.83l-.793.792c.112.42.155.855.128 1.287l1.372-1.372a3 3 0 1 0-4.243-4.243L6.586 4.672z"/> </svg>cartão fictício</a> </code> </h4> <div class="row gy-3"> <div class="col-md-7"> <label for="numeroCartao" class="form-label">Número do cartão * <code data-bs-toggle="tooltip" data-bs-placement="top" title="(String - 'XXXXXXXXXXXXXXXX')"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16"> <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/> <path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/> </svg> </code> </label> <input type="text" class="form-control" name="numeroCartao" id="numeroCartao" required> </div> <div class="col-md-5"> <!-- Bandeira será preenchida dinamicamente de acordo com o número do cartão informado --> <label for="bandeira" class="form-label">Bandeira * <code data-bs-toggle="tooltip" data-bs-placement="top" title="(String - 'visa', 'mastercard', 'amex', 'elo', 'hipercard') Obtida a partir do número do cartão"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16"> <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/> <path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/> </svg> </code> </label> <input type="text" class="form-control" name="bandeira" id="bandeira" readonly required> </div> <div class="col-md-4"> <label for="mesVencimento" class="form-label">Mês de vencimento * <code data-bs-toggle="tooltip" data-bs-placement="top" title="(String - 'MM')"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16"> <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/> <path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/> </svg> </code> </label> <select class="form-select" name="mesVencimento" id="mesVencimento" required> <option selected>01</option> <option>02</option> <option>03</option> <option>04</option> <option>05</option> <option>06</option> <option>07</option> <option>08</option> <option>09</option> <option>10</option> <option>11</option> <option>12</option> </select> </div> <div class="col-md-4"> <label for="anoVencimento" class="form-label">Ano de vencimento * <code data-bs-toggle="tooltip" data-bs-placement="top" title="(String - 'YYYY')"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16"> <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/> <path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/> </svg> </code> </label> <select class="form-select" name="anoVencimento" id="anoVencimento" required> </select> </div> <div class="col-md-4"> <label for="cvv" class="form-label">Código de segurança (cvv) * <code data-bs-toggle="tooltip" data-bs-placement="top" title="(String - '123')"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16"> <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/> <path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/> </svg> </code> </label> <input type="text" class="form-control" name="cvv" id="cvv" required> </div> <div class="col-md-6"> <label for="nomeTitular" class="form-label">Nome do titular do cartão * <code data-bs-toggle="tooltip" data-bs-placement="top" title="(String - 'Nome Sobrenome')"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16"> <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/> <path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/> </svg> </code> </label> <input type="text" class="form-control" name="nomeTitular" id="nomeTitular" required> </div> <div class="col-md-6"> <label for="documentoTitular" class="form-label">CPF/CNPJ do titular do cartão * <code data-bs-toggle="tooltip" data-bs-placement="top" title="(String - CPF: '94271564656' ou CNPJ: '99794567000144')"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16"> <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/> <path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/> </svg> </code> </label> <input type="text" class="form-control" name="documentoTitular" id="documentoTitular" required> </div> <div class="col-md-12"> <label for="opcoesParcelamento" class="form-label">Opções de parcelamento <code data-bs-toggle="tooltip" data-bs-placement="top" title="Obtida quando definida a bandeira"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16"> <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/> <path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/> </svg> </code> </label> <select class="form-select" id="opcoesParcelamento" name="opcoesParcelamento"> <option value="0">Digite o número do cartão</option> </select> </div> </div> <!-- Fim - Inputs com informações do cartão de crédito --> <hr> <!-- Início - Informação de parcelamento e botão para acionar a geração do payment_token --> <div class="row g-3"> <div class="col-md-12"> <button class="w-100 btn btn-primary btn-lg disabled" id="gerarPaymentToken" type="button">Gerar Payment Token</button> </div> </div> <!-- Fim - Informação de parcelamento e botão para acionar a geração do payment_token --> <hr> <h4 class="mb-3">Resultado <code data-bs-toggle="tooltip" data-bs-placement="top" title="Obtidas após execução das funções acionadas pelo botão"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16"> <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/> <path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/> </svg> </code> </h4> <div class="row g-3"> <div class="col-md-6"> <!-- Input que receberá o payment_token gerado --> <label for="paymentToken" class="form-label">Payment Token <code data-bs-toggle="tooltip" data-bs-placement="top" title="payment_token gerado para ambiente de homologação"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-info-circle" viewBox="0 0 16 16"> <path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/> <path d="m8.93 6.588-2.29.287-.082.38.45.083c.294.07.352.176.288.469l-.738 3.468c-.194.897.105 1.319.808 1.319.545 0 1.178-.252 1.465-.598l.088-.416c-.2.176-.492.246-.686.246-.275 0-.375-.193-.304-.533L8.93 6.588zM9 4.5a1 1 0 1 1-2 0 1 1 0 0 1 2 0z"/> </svg></label> </code> <input type="text" class="form-control" name="paymentToken" id="paymentToken" readonly> </div> <div class="col-md-6"> <!-- Input que receberá o card_mask gerado --> <label for="mascaraCartao" class="form-label">Máscara do cartão</label> <input type="text" class="form-control" name="mascaraCartao" id="mascaraCartao" readonly> </div> </div> <br> </form> </main> </body> </html>