Throne

Cartão

Checkout Brasil

Checkout de cartão para o comprador brasileiro: página sempre em português, CPF pedido na tela, comprador de qualquer país e botão e moldura ajustáveis pela API, com o mesmo Throne Elements e o mesmo webhook.

Ver em Markdown

O que é#

O Checkout Brasil é o checkout de cartão para o comprador brasileiro. Você cria o checkout com POST /elements/checkout/br e coloca o transaction_id no mesmo Throne Elements que já usa. O que muda está na página que o comprador vê: ela sai sempre em português, pede o CPF junto com o cartão e abre para comprador de qualquer país.

O nome e o CPF que o comprador digita vão para a adquirente junto com o cartão, na autorização. São os dados que o emissor de um cartão brasileiro espera receber numa compra.

Nota Nada a mudar no que já está no ar. O POST /elements/checkout continua igual, com a mesma resposta e o mesmo webhook. O Checkout Brasil é um endpoint a mais, para a página do seu funil que vende ao comprador brasileiro.

Antes de começar#

O Checkout Brasil funciona nas adquirentes habilitadas para o Checkout Brasil na sua conta. As adquirentes de cartão da sua conta estão em GET /elements/acquirers, mas nem toda adquirente atende o Checkout Brasil: se nenhuma das suas atender, a criação responde 422 acquirer_not_enabled e nada é criado. Para pedir a habilitação, fale com o suporte.

  • A chave de API é a mesma, com a permissão transactions:write. Nenhuma chave precisa ser gerada de novo.
  • O comprador precisa ter CPF. Sem um CPF válido, o pagamento não sai da página. Para o comprador sem CPF, use o checkout comum.
  • A Idempotency-Key, o timeout de 60 segundos e a regra de repetição são os de sempre. Veja Comece aqui.

Criar#

A criação fala com a adquirente. Use 60 segundos de timeout no seu cliente HTTP e gere a Idempotency-Key antes de chamar, guardando junto do pedido. Use uma chave nova, nunca a de uma chamada ao POST /elements/checkout: a chave devolve a resposta da chamada em que foi usada.

cURL
curl -X POST https://app.thronecorporate.com/api/v1/elements/checkout/br \
  --max-time 60 \
  -H "Authorization: Bearer $THRONE_PK:$THRONE_SK" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "amount_cents": 9700,
    "currency": "brl",
    "customer": { "name": "Maria Souza", "email": "maria@exemplo.com" }
  }'

201 Created:

JSON
{
  "transaction_id": "c4d7a2b1-6e3f-4a9c-8b5d-2f1e0a9c7b63",
  "status": "pending",
  "checkout_url": "https://pay.example.com/checkout/5a4b3c2d1e0f99887766554433221100",
  "display": { "currency": "BRL", "amount_cents": 9700 },
  "expires_at": "2026-10-20T14:20:00Z"
}

A resposta é a mesma do checkout comum: transaction_id, status, checkout_url, acquirer (a adquirente que ficou com a venda), display, expires_at e, quando houver aviso, warnings. Veja a resposta do checkout comum. O que é próprio do Checkout Brasil está em Referência dos campos.

Na sua página, nada muda:

HTML
<div data-throne-elements
     data-id="c4d7a2b1-6e3f-4a9c-8b5d-2f1e0a9c7b63"
     data-color="#7c3aed"
     data-theme="light"
     data-radius="10"></div>

<script src="https://app.thronecorporate.com/throne-elements.js" async></script>

O elemento monta a página em português, com o campo de CPF junto dos dados do cartão. O comprador digita o cartão, o nome e o CPF, e paga. Os eventos throne-elements:ready, throne-elements:paid e throne-elements:error chegam como sempre. A confirmação que vale para liberar o pedido continua sendo o webhook transaction.paid ou o GET /transactions/{id} com status: "paid".

O que muda em relação ao checkout comum#

Item Checkout comum Checkout Brasil
Endpoint POST /elements/checkout POST /elements/checkout/br
Idioma da página Pelo país do comprador Sempre português, seja qual for o país do comprador, o idioma do navegador ou o ?nl= no checkout_url
CPF Não pede Pede na tela. Obrigatório e conferido antes do envio
País do comprador Segue o país do comprador Qualquer país: a página abre e o pagamento vai para a adquirente seja qual for o país do comprador ou do cartão
Adquirente A pedida em acquirer ou a padrão da conta A habilitada para o Checkout Brasil na conta. acquirer é opcional e só aceita uma que atenda o Checkout Brasil. O roteamento fixado na conta e o roteamento por valor não valem aqui
one_click_from e recurrence Aceitos Não existem: 422 field_not_supported
Aparência da página data-color, data-theme e data-radius do elemento Os mesmos, mais o objeto appearance na criação: texto do botão, valor no botão, cores, formato, tamanho e moldura. Veja Aparência
Throne Elements, eventos, moedas, limites, tentativas, validade de 24 horas, status e webhook Iguais Iguais

O comportamento da página depois do clique em pagar (verificação do banco, tentativas, códigos em throne-elements:error) é o da adquirente que ficou com a venda, como no checkout comum: veja o guia dela em Comparar adquirentes.

Aparência#

Você pode ajustar a página do Checkout Brasil na própria criação, com o objeto appearance: o texto do botão, se o valor aparece nele, as cores, o arredondamento, a altura e a largura do botão, e uma moldura em volta dos campos. Tudo é opcional. O que você não mandar segue o padrão e os atributos data-color e data-radius do elemento, como hoje.

cURL
curl -X POST https://app.thronecorporate.com/api/v1/elements/checkout/br \
  --max-time 60 \
  -H "Authorization: Bearer $THRONE_PK:$THRONE_SK" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "amount_cents": 9700,
    "currency": "brl",
    "appearance": {
      "button": { "text": "Finalizar compra", "background_color": "#15803d" },
      "fields": { "radius": 8 },
      "frame": { "border_width": 1, "padding": 24, "shadow": "md" }
    }
  }'

O botão sai "Finalizar compra R$ 97,00" em verde, com o texto em branco escolhido sozinho para ficar legível, e os campos ficam dentro de uma moldura com borda e sombra.

Campo Aceita Padrão O que faz
button.text Texto de 2 a 32 caracteres: letras, com ou sem acento, espaço e ! ? , - ', com pelo menos uma letra Pagar Texto do botão. Número, símbolo de moeda e as palavras da lista abaixo não entram: o valor aparece sozinho
button.show_amount true ou false true Mostra o valor depois do texto. Com false, o botão mostra só o texto e o valor aparece fora dele: logo acima do botão, ou no topo do formulário quando a venda é criada em outra moeda
button.background_color Cor #rrggbb O data-color Cor do botão
button.text_color Cor #rrggbb, só junto de background_color Escolhida sozinha Cor do texto do botão. O contraste com o fundo precisa ser de 3:1 ou mais
button.radius Inteiro de 0 a 32 O dos campos Arredondamento do botão, em px. Com a metade da altura, o botão vira pílula
button.height Inteiro de 44 a 64 48 Altura mínima do botão, em px. Texto longo quebra a linha e o botão cresce
button.full_width true ou false true Com false, o botão fica do tamanho do texto, centralizado, com no mínimo 200 px
fields.focus_color Cor #rrggbb button.background_color, senão o data-color Cor de destaque: a borda do campo em foco, o contorno de foco do botão e o indicador da tela de espera
fields.radius Inteiro de 0 a 32 O data-radius, senão 10 Arredondamento dos campos, em px
frame.max_width Inteiro de 320 a 720 460 Largura máxima do checkout, em px
frame.padding Inteiro de 0 a 40 0 Espaço entre a moldura e os campos, em px. Em tela de até 400 px, no máximo 6
frame.border_width Inteiro de 0 a 3 0 Espessura da borda da moldura. Com só border_color, vale 1. Em tela de até 400 px, no máximo 1
frame.border_color Cor #rrggbb A cor das linhas dos campos Cor da borda
frame.radius Inteiro de 0 a 32 12 Arredondamento da moldura
frame.shadow none, sm, md ou lg none Sombra da moldura. Em site escuro, prefira a borda: a sombra quase não aparece

Como a validação funciona:

  • Mande JSON com os tipos certos: 48, não "48"; false, não "false". Uma chave com null vale como ausente.
  • Chave que não existe, valor fora da regra ou combinação impossível: 422 invalid_appearance e nada é criado. A resposta traz field com o caminho da chave, por exemplo appearance.button.text.
  • O texto do botão não aceita, em maiúsculas ou minúsculas, as palavras real, reais, centavo, centavos, grátis, gratis, gratuito, gratuita, free, zero, cancelar, voltar, fechar e sair: o botão sempre paga o valor da venda.
  • Contraste: text_color com contraste menor que 3:1 sobre background_color é recusado. De 3:1 até 4,5:1 é aceito, com o aviso low_contrast em warnings. Branco sobre #16a34a dá 3,29:1 (aceito, com aviso); branco sobre #15803d, 5,01:1.
  • fields.focus_color que quase some sobre fundo claro ou escuro também gera low_contrast.
  • A moldura precisa deixar pelo menos 256 px para os campos: frame.max_width, menos 32 (ou 56 com shadow: lg), menos duas vezes a soma de frame.padding e frame.border_width.

Quem vence quando você também usa os atributos do elemento:

Aspecto Sem a chave em appearance Com a chave
Cor do botão data-color button.background_color
Cor de destaque dos campos data-color fields.focus_color, senão button.background_color
Arredondamento data-radius, nos campos e no botão fields.radius e button.radius
Tema e cor de fundo data-theme e a detecção do fundo do seu site Os mesmos: appearance não muda

As chaves que você manda ficam gravadas na criação e não mudam pela URL do checkout; as que você não manda seguem os atributos do elemento. Para mudar o que foi gravado, crie um checkout novo.

O que não muda: os nomes e os exemplos dos campos (número do cartão, nome no cartão, validade, CVV e CPF), a frase de segurança abaixo do botão, os textos de processamento, de verificação do banco, de aprovação e de recusa, o botão "Tentar de novo", a fonte e as bandeiras. São os textos que o comprador e o banco esperam ver numa página de pagamento.

O botão em cada momento: antes do clique, o seu texto, com ou sem o valor; durante o envio, "Processando", desativado e nas suas cores; recusado, a tela de recusa com "Tentar de novo", e de volta ao formulário o botão volta ao seu texto; aprovado, a tela de pagamento aprovado.

Erros#

Os erros do checkout comum valem aqui, com o mesmo significado: invalid_amount, currency_not_supported, fx_unavailable, card_not_enabled, invalid_acquirer, os de Idempotency-Key, 502 checkout_failed e 503 temporarily_unavailable. Veja a tabela do checkout comum. O que é próprio do Checkout Brasil:

Status error message Quando Repetir
422 acquirer_not_enabled O Checkout Brasil não está habilitado para nenhuma adquirente da sua conta. Fale com o suporte. A conta não tem adquirente habilitada para o Checkout Brasil. Nada foi criado Não, até habilitar
422 acquirer_not_enabled A adquirente pedida não está habilitada para o Checkout Brasil na sua conta. O campo acquirer pediu uma adquirente que não atende o Checkout Brasil. Nada foi criado Com chave nova, sem o campo ou com outra adquirente
422 field_not_supported O campo one_click_from não é aceito no Checkout Brasil. Remova o campo e repita a chamada. O corpo trouxe one_click_from ou recurrence. Nada foi criado Com chave nova, sem o campo
422 invalid_appearance appearance.button.color não existe. Em appearance.button valem: text, show_amount, background_color, text_color, radius, height e full_width. O objeto appearance trouxe chave que não existe, valor fora da regra ou combinação impossível. O campo field diz qual chave. Nada foi criado Com chave nova, depois de corrigir

No Checkout Brasil, invalid_amount vem com alternatives vazio e o 503 não sugere outra adquirente: acima do máximo, divida o pedido.

Decida sempre pelo campo error. O message é texto de apoio e pode mudar.

Perguntas que aparecem sempre#

O CPF do comprador fica guardado? Não. Ele vai para a adquirente na autorização do pagamento e só. O Throne não guarda o CPF digitado, e ele não volta na consulta nem no webhook. Se você quiser o documento registrado na venda, mande customer.document na criação, como no checkout comum.

Serve para Pix? Não. O Checkout Brasil é só cartão. Para Pix, use POST /transactions com payment_method: "pix", como em Cobrar com Pix.

Posso usar o mesmo Throne Elements? Sim. O script, os atributos e os eventos são os mesmos: só troque o data-id pelo transaction_id novo. Vale a regra de sempre: para trocar de checkout, use um container novo (detalhes).

Preciso de outra chave de API? Não. A mesma chave, com transactions:write, cria os dois checkouts.

E se o comprador não tiver CPF? O pagamento não sai: o campo é obrigatório e conferido na tela. Para esse comprador, crie o checkout comum.

O customer.document da criação preenche o CPF? Não. O campo CPF da página nasce vazio e o comprador digita o dele. O que vai para a adquirente é o CPF digitado na tela; o customer.document fica registrado na venda e volta no webhook, como no checkout comum.

O ?nl= no checkout_url muda o idioma? Não. No Checkout Brasil a página sai em português sempre, inclusive para teste.

A venda aparece diferente na consulta ou no webhook? Não. É uma venda de cartão como as outras: mesmo GET /transactions/{id}, mesmo transaction.paid, mesmo acquirer.

Posso mudar a frase de segurança ou o nome dos campos? Não. Só o botão, as cores, o formato e a moldura mudam, pelo objeto appearance. O resto é o texto que o comprador e o banco esperam ver numa página de pagamento.

O appearance funciona no POST /elements/checkout? Não. Ele só existe no Checkout Brasil; no checkout comum o campo é ignorado.

Referência dos campos#

Requisição, POST /elements/checkout/br:

Campo Obrigatório Regra
amount_cents Sim Inteiro na menor unidade da moeda (R$ 97,00 = 9700). Mínimo e máximo como no checkout comum: pela adquirente, pela moeda e pela cotação do dia
currency Sim Código de 3 letras, maiúsculas ou minúsculas. As mesmas 48 moedas do checkout comum; para o comprador brasileiro, brl
acquirer Não Só uma adquirente habilitada para o Checkout Brasil na sua conta; outra volta 422 acquirer_not_enabled. Sem o campo, a venda vai para a habilitada
customer.name Não Como no checkout comum: vai pré-preenchido no nome do cartão, e o comprador pode corrigir
customer.email, customer.document, customer.document_type, customer.phone, customer.address Não Como no checkout comum: ficam registrados na venda e voltam no webhook. Nenhum gera erro; o que vier fora do formato é ajustado ou descartado, com aviso em warnings
appearance Não Objeto com button, fields e frame. Veja Aparência. Fora da regra: 422 invalid_appearance
one_click_from, recurrence Não existem 422 field_not_supported

metadata e itens não são aceitos, como no checkout comum: guarde o transaction_id para ligar a venda ao seu pedido.

Resposta 201: os mesmos campos do checkout comum. Veja a referência da resposta. O que é próprio do Checkout Brasil:

  • warnings pode trazer, além dos avisos de customer, o aviso low_contrast, sobre appearance.

Veja também Cartão: como funciona e Throne Elements.