Cartão de crédito com 3DS
SDK JavaScript de tokenização e autenticação
Este guia mostra como aceitar cartão de crédito com autenticação 3DS (3-D Secure) usando o SDK da HiSo Unique. O SDK tokeniza o cartão no navegador e conduz a autenticação exigida pela adquirente da sua conta. Você integra uma vez só; o fluxo de cada adquirente fica por nossa conta.
Os dados abertos do cartão nunca passam pelo seu servidor: você envia apenas o token gerado pelo encrypt().
1º Passo: Carregar o SDK e obter as configurações 3DS
Importe o script na sua página de checkout e informe a sua public key:
<script src="https://api.hiso.com.br/v1/js"></script>
// IMPORTANTE: chame o setPublicKey assim que a tela for carregada.
const publicKey = "{PUBLIC_KEY}";
const moduleName = window["HiSoHelper"].getModuleName();
const settings = await window[moduleName].setPublicKey(publicKey);O setPublicKey devolve as configurações 3DS da sua conta. Se preferir, consulte-as diretamente:
// Opcional: o setPublicKey já devolve essas configurações.
const response = await fetch(
`https://api.hiso.com.br/v1/js/get3dsSettings?publicKey=${publicKey}`,
{ headers: { Accept: "application/json" } }
);
const settings = await response.json();{
"threeDSSecurity": true,
"threeDSSecurityType": "SCRIPT",
"iframeUrl": null,
"hideCardForm": false
}threeDSSecurity: indica se a adquirente aplica 3DS.threeDSSecurityType: método de autenticação (tabela abaixo).hideCardForm: quandotrue, esconda o formulário de cartão do checkout.iframeUrl: URL a carregar no iframe (somente paraIFRAME).
| threeDSSecurityType | Descrição |
|---|---|
NONE | Não há autenticação 3DS aplicada. |
IFRAME | A autenticação ocorre dentro de um iframe embutido na página. |
REDIRECT | O cliente é redirecionado para uma página externa para autenticar. |
SCRIPT | A autenticação é conduzida pelo próprio SDK, no navegador. |
Quando o tipo for IFRAME, crie o iframe dentro do formulário de pagamento e acompanhe a validação do formulário:
const iframe = document.createElement("iframe");
iframe.id = window["HiSoHelper"].getIframeId();
iframe.src = settings.iframeUrl;
iframe.width = "100%";
iframe.height = "400px";
iframe.style.border = "none";
document.getElementById("payment-form")?.appendChild(iframe);
window["HiSoHelper"].subscribeIframeFormValidation((data) => {
console.log(data.hasError);
});2º Passo: Chamar prepareThreeDS()
Prepara a autenticação da transação e pré-carrega os recursos da adquirente. Chame antes do encrypt() e sempre que o valor, as parcelas ou a moeda mudarem.
const currency = "BRL";
const amount = window["HiSoHelper"].convertDecimalToCents(3.5, currency); // 350
await window["HiSoHelper"].prepareThreeDS({
amount, // valor em centavos
installments: 1, // número de parcelas
});3º Passo: Chamar encrypt()
Gera o token do cartão. O SDK valida número (Luhn), validade e CVV e rejeita a promise com um erro (error.code) quando algo estiver inválido.
const moduleName = window["HiSoHelper"].getModuleName();
const token = await window[moduleName].encrypt({
number: "4111111111111111",
holderName: "JOAO DA SILVA",
expMonth: 9,
expYear: 2027,
cvv: "123",
});Se hideCardForm for true, chame o encrypt() com todos os campos null.
Importante: o token vale para uma transação e precisa ser finalizado na mesma página em que foi gerado (sem recarregar entre o encrypt e o finishThreeDS).
4º Passo: Criar a transação
No seu backend, crie a transação normalmente, enviando o token em card.hash (sem os demais campos do cartão). Para cartão, o endereço de cobrança em shipping.address é obrigatório, com o bairro real do cliente, além de telefone e documento.
POST https://api.hiso.com.br/v1/payment-transaction/create
authorization: Basic Base64(PUBLIC_KEY:SECRET_KEY)
{
"amount": 350,
"payment_method": "credit_card",
"installments": 1,
"card": { "hash": "<token do encrypt()>" },
"customer": {
"name": "Joao da Silva",
"email": "joao@email.com",
"phone": "11999998888",
"document": { "number": "12345678909", "type": "cpf" }
},
"shipping": {
"fee": 0,
"address": {
"street": "Av. Paulista",
"street_number": "1000",
"neighborhood": "Bela Vista",
"city": "São Paulo",
"state": "SP",
"zip_code": "01310100",
"country": "BR"
}
},
"items": [{ "title": "Pedido #123", "unit_price": 350, "quantity": 1, "tangible": false }],
"postback_url": "https://seu-site.com/webhook"
}Quando houver 3DS, a resposta traz o objeto three_ds e a transação fica PENDING até a autenticação:
{
"id": "a24207e615224923bf4a68265d519fc6",
"amount": 350,
"installments": 1,
"payment_method": "credit_card",
"status": "PENDING",
"three_ds": {
"required": true,
"session_id": "5f1c0b7e2d9a4c61b8f3e0a7d6c5b4a3",
"type": "SCRIPT",
"redirect_url": null
}
}5º Passo: Chamar finishThreeDS()
Entregue ao navegador a resposta do passo 4 e finalize a autenticação. Quando o tipo for REDIRECT, o SDK redireciona automaticamente para redirectUrl, a menos que você passe disableRedirect: true. Quando a transação não exige 3DS, a função resolve na hora com o status atual.
// transaction = resposta do passo 4 (repasse o objeto inteiro ao navegador)
const result = await window["HiSoHelper"].finishThreeDS(transaction, {
disableRedirect: false, // true para controlar o redirecionamento manualmente
});
// {
// status: "PAID" | "PENDING" | "REFUSED",
// approved: true | false,
// transactionId: "a24207e6...",
// threeDSRequired: true,
// redirectUrl: null,
// message: null
// }| status | Como tratar |
|---|---|
PAID | Pagamento aprovado. Aguarde o webhook para liberar o pedido. |
PENDING | Em análise (ex.: antifraude). Mantenha o pedido pendente até o webhook. |
REFUSED | Pagamento não aprovado ou 3DS não concluído. Para tentar de novo, crie uma nova transação. |
O resultado no navegador serve para a experiência do cliente. A fonte da verdade é o webhook enviado para a sua postback_url. Uma análise antifraude pode manter a transação em PENDING por algumas horas.
Content Security Policy
Se a sua página usa CSP, libere script-src e connect-src para o host do SDK e frame-src https:. O desafio 3DS abre páginas dos bancos emissores, escolhidas dinamicamente.