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#
<!-- 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 vencedata-coloredata-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_idna 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
failedouexpired.
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 osandbox, ele precisa incluir no mínimoallow-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.comemscript-src(o script) e emimg-src, e emframe-srclibere esse domínio e o domínio do checkout (o mesmo docheckout_urlda 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:
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#
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.
Navegador de app#
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:paidnem 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.