Throne

Cartão

Throne Elements

Atributos do elemento, eventos com código estável, sandbox, página de uma tela só e navegador de app.

Ver em Markdown

O que é#

O Throne Elements é o checkout de cartão embutido na sua página. Você cria o checkout no seu servidor com POST /elements/checkout (ou com POST /elements/checkout/br, o Checkout Brasil) e coloca o transaction_id num container. O script do Throne monta o elemento ali dentro. O comprador digita o cartão no elemento e o seu servidor nunca toca no número do cartão.

O mesmo elemento serve para as seis adquirentes. O que muda entre elas está em Comparar adquirentes.

Colocar na página#

HTML
<!-- onde o checkout deve aparecer -->
<div data-throne-elements
     data-id="ae3bf1da-0c9b-4818-9140-c6432152c23e"
     data-color="#7c3aed"
     data-theme="light"
     data-radius="10"></div>

<script src="https://app.thronecorporate.com/throne-elements.js" async></script>
Atributo O que faz
data-throne-elements Marca o container. Pode haver mais de um na página
data-id O transaction_id da criação. Precisa ser o UUID exato, senão nada aparece
data-color Cor do botão e dos realces, no formato #rrggbb
data-theme light ou dark. O elemento também detecta sozinho a cor de fundo do seu site e se ajusta a ela
data-radius Arredondamento dos cantos, de 0 a 32 (px). Padrão 10

Nota No Checkout Brasil, a criação também pode pedir o texto do botão, as cores, o formato e uma moldura pelo objeto appearance, e o que vier nele vence data-color e data-radius. Veja Aparência.

Quando criar o checkout#

  • Crie no clique de compra, não quando a página carrega. Assim você não gasta checkout com quem só olhou a página.
  • Guarde o transaction_id na sessão do comprador. Se ele voltar à página em até 24 horas, mostre o mesmo checkout em vez de criar outro.
  • O mesmo checkout aceita várias tentativas de cartão. Crie um novo só depois de failed ou expired.

Boas práticas#

  • Carregue o script do endereço acima. Não hospede uma cópia: o elemento depende do endereço de origem do script.
  • Não fixe a altura do container nem esconda o overflow. O elemento ajusta a própria altura conforme a tela do checkout.
  • Não coloque o elemento dentro de outro iframe com sandbox. Se não der para tirar o sandbox, ele precisa incluir no mínimo allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation. Sem isso, a verificação do banco e o pagamento em navegador de app não funcionam em algumas adquirentes.
  • O pagamento precisa começar pelo clique do comprador no botão do elemento. Não dispare o pagamento por código.
  • Se a sua página envia o header Cross-Origin-Opener-Policy: same-origin, a janela de verificação do banco pode perder o contato com o elemento. Sem esse header, nada a fazer. Com ele, teste um pagamento completo no computador e no celular antes de publicar.
  • Se o seu site usa Content-Security-Policy, libere https://app.thronecorporate.com em script-src (o script) e em img-src, e em frame-src libere esse domínio e o domínio do checkout (o mesmo do checkout_url da resposta).

Página de uma tela só (React, Vue e outras)#

O script monta os containers que existem quando ele carrega. Se você inserir o container depois, chame:

JavaScript
window.ThroneElements.mount();

Chame de novo sempre que inserir um container novo. Um container já montado não muda: trocar o data-id dele e chamar mount() não troca o checkout, e o elemento continua mostrando o anterior, com o valor antigo.

Para mostrar outro checkout, remova o container antigo, insira um novo com o data-id novo e chame mount(). Em React, use o transaction_id como key do container (<div key={transactionId} data-throne-elements data-id={transactionId} />) e chame mount() num useEffect que depende do transactionId: o React cria um container novo a cada checkout.

Eventos na sua página#

JavaScript
window.addEventListener('throne-elements:ready', () => {
  // elemento montado, pronto para receber o cartão
});

window.addEventListener('throne-elements:paid', (e) => {
  // e.detail.transaction_id: o comprador concluiu. Mostre o "obrigado".
});

window.addEventListener('throne-elements:error', (e) => {
  const code = e.detail.code || e.detail.message; // code é fixo; message é texto
  // decida pelo code; mostre o texto só como apoio
});

Também funcionam as funções window.ThroneElements.onready, onpaid e onerror, que recebem o mesmo objeto de e.detail.

Os eventos são sinais de tela. A confirmação que vale para liberar o pedido é o webhook transaction.paid ou o GET /transactions/{id} com status: "paid". O elemento pode terminar sem paid mesmo numa venda aprovada: o comprador pode fechar a página, a conexão pode cair ou o pagamento pode seguir por outro caminho, como o do navegador de app abaixo.

Códigos de erro#

Em throne-elements:error, decida pelo campo e.detail.code. Ele é um código fixo, em inglês, que não muda com o idioma do comprador. O campo e.detail.message traz o texto mostrado ao comprador, no idioma dele, e serve só para log. Se code não vier, use message quando ele for um dos códigos abaixo e trate qualquer outro texto como declined.

code Significado Sterling Imperium NovaCorp Eminence Apex ShadowBank Vortex
declined Cartão recusado. O comprador pode tentar de novo Sim Sim Sim Sim Sim Sim Sim
attempts_exhausted Acabaram as tentativas deste checkout Sim Em parte (veja abaixo) Sim Sim Sim Sim Sim
closed O checkout fechou por recusa enquanto a página estava aberta Não Não Sim Não Não Não Não
window_closed O comprador fechou a janela de verificação sem concluir Não Não Sim Não Não Não Não
canceled O comprador cancelou a verificação do banco Não Não Sim Não Não Não Não
popup_blocked A janela de verificação fechou logo depois de abrir, antes do envio do cartão. Nada foi cobrado e o comprador pode tentar de novo Não Não Sim Não Não Não Não
timeout A confirmação demorou mais que o esperado. O resultado final chega pelo webhook ou pela consulta Não Não Sim Sim Sim Sim Sim
limit A adquirente não aceita o valor desta venda no cartão. O checkout fechou Não Não Não Sim Sim Não Não
network Falha de conexão do comprador Sim Sim Sim Sim Sim Sim Sim
token Os dados do cartão não passaram na validação inicial. Não consome tentativa Sim Não Não Sim (veja abaixo) Sim Sim Sim
expired O checkout passou da validade Sim Sim Sim Sim Sim Sim Sim
ended O checkout foi encerrado Sim Sim Sim Sim Sim Sim Sim

Uma janela de verificação bloqueada na abertura não gera popup_blocked: na NovaCorp, o pagamento segue pela própria aba, como no navegador de app.

Na Eminence, a verificação do banco aparece dentro do próprio elemento, sem janela, e o comprador pode sair dela pelo botão Cancelar. O Cancelar não gera evento na hora: o elemento espera o banco encerrar a verificação pendente e então envia declined ou network; se isso não acontecer em alguns minutos, envia timeout. token também chega quando a Eminence recusa os dados do cartão depois do envio; nesse caso a tentativa é contada. limit fecha o checkout como failed: crie um checkout novo com outra adquirente habilitada.

Na Apex não há verificação do banco: o resultado sai na própria tentativa, dentro do elemento. timeout chega quando a análise antifraude demora; o resultado final vem pelo webhook ou pela consulta. token chega quando os dados do cartão não passam na validação, antes da cobrança, e não consome tentativa. limit fecha o checkout como failed, como na Eminence: crie um checkout novo com outra adquirente habilitada.

Na ShadowBank também não há verificação do banco: o resultado sai na própria tentativa, dentro do elemento. timeout chega quando a análise antifraude demora; o resultado final vem pelo webhook ou pela consulta. token chega quando os dados do cartão não passam na validação, antes da cobrança, e não consome tentativa. A ShadowBank não envia limit.

Na Imperium, e.detail não traz code, só message. Por isso o exemplo acima lê e.detail.code || e.detail.message. Falha de conexão, validade e encerramento chegam como network, expired e ended. Numa recusa durante o pagamento, inclusive a última, message traz o texto mostrado ao comprador, no idioma dele, e não diz se ainda há tentativa: attempts_exhausted só chega quando o elemento abre num checkout que já fechou. Trate esse texto como declined e deixe o próprio elemento mostrar ao comprador se ele pode tentar de novo. Para saber se o checkout fechou, consulte GET /transactions/{id}: com failed, crie um checkout novo.

Instagram, Facebook, o app do Google, TikTok e outros apps abrem links num navegador próprio. Esses navegadores não abrem uma segunda janela.

  • Sterling, Imperium, Eminence, Apex, ShadowBank e Vortex: nada muda. O pagamento acontece todo dentro do elemento e os eventos chegam normalmente.
  • NovaCorp: a própria aba sai da sua página e vai para a página segura de pagamento. O comprador passa pela tela do banco e termina lá. A sua página não recebe throne-elements:paid nem outro evento, e o comprador não volta sozinho para a sua loja. O mesmo acontece quando um navegador comum bloqueia a janela de verificação.

A venda continua sendo confirmada normalmente pelo webhook transaction.paid e pelo GET. Por isso:

  • libere o pedido pelo webhook, nunca só pelo evento da página;
  • envie a conversão da campanha pelo seu servidor ao receber transaction.paid, como em Webhooks;
  • mande o e-mail de confirmação do pedido pelo servidor, porque o comprador pode não ver a sua página de obrigado.

Se o comprador voltar à sua página pelo botão voltar, o elemento pode montar de novo já pago e disparar throne-elements:paid. Isso não é garantido: não dependa disso.

Idioma#

O checkout sai no idioma do país do comprador, identificado pelo IP. Compradores no Brasil, em Portugal ou de país não identificado veem em inglês. O idioma não é configurado pela API. Detalhes por adquirente em Comparar adquirentes. No Checkout Brasil, a página sai sempre em português.