Skip to main content
POST
Confirmar a sessão (navegador)
Quem chama é o vext.js, no clique do botão de pagar. O valor, os itens, o reference e o metadata vêm da sessão e são ignorados no corpo — é essa a razão de a sessão existir: a chave publicável está no código-fonte da sua página, e sem o congelamento ela seria uma porta de cobrança de valor arbitrário. Ver Drop-in.
Uma sessão rende no máximo uma cobrança: repetir a chamada devolve a mesma venda, garantida por índice único no banco e não por uma conferência em código. Dois cliques simultâneos não viram dois pedidos. Ver Idempotência.
No Pix a cobrança nasce pending, e esta resposta é o QR — não o pagamento. Liberar o produto ao receber 201 entrega de graça para quem fechou o aplicativo do banco antes de pagar. Quem decide o desfecho é o webhook charge.paid; o quadro acompanha por GET /v1/embed/sessions/{code}/status.

Authorizations

X-Vext-Publishable-Key
string
header
required

Chave publicável do vendedor, criada no painel em Desenvolvedores → Embed, no formato pk_live_… / pk_test_….

Ao contrário da secreta, esta é para o NAVEGADOR: ela fica no código-fonte da página e qualquer pessoa a lê. Isso é esperado, e não um descuido - guardamos o valor em claro justamente para você poder copiá-lo de novo a cada site.

O que a protege é a lista de domínios autorizados da própria chave. Uma requisição vinda de origem que não está na lista é recusada com 403 origin_not_allowed, e a chave recém-criada, sem nenhum domínio declarado, recusa tudo.

Ela não carrega escopo. Uma pk_ não lista cobrança, não estorna e não consulta saldo: o que ela alcança são os endpoints sob /v1/embed, e essa lista é fechada. Por isso os endpoints deste grupo declaram publishableKey: [] - a lista vazia é literal, e não uma omissão.

Na navegação que carrega o iframe não há como enviar cabeçalho; ali a chave vai em ?pk=. Quando os dois vêm, o cabeçalho vence.

Headers

X-Vext-Client-Secret
string
required

O client_secret devolvido na abertura da sessão. A chave publicável diz de qual LOJA é o checkout; este diz qual VENDA.

Cabeçalho, e nunca query: na URL ele entraria no log de acesso e vazaria pelo Referer de qualquer recurso que a página carregasse depois.

Path Parameters

code
string
required

Código público da sessão, no formato cs_….

Pattern: ^cs_[0-9a-z]{26}$

Body

application/json

O corpo da confirmação, montado pelo nosso embed: o comprador (nome, e-mail, documento e telefone) e, no cartão, o token, as parcelas, o nome impresso e o endereço de cobrança.

O que NÃO está aqui é o ponto: valor, itens e loja vêm da sessão. O único campo deste corpo com uma decisão de verdade é o payment_method, e é por isso que ele está documentado à parte - os demais são o preenchimento do formulário.

payment_method
enum<string>
required

Como o comprador escolheu pagar. Obrigatório, e restrito ao que a SESSÃO oferece: o valor tem de estar em payment_methods, lido em GET /v1/embed/sessions/{code}. Fora dela, 422.

A lista permitida é a da sessão e não o enum inteiro pela mesma razão que o valor não vem do corpo - ela foi congelada pelo servidor do lojista, e aceitar aqui um método fora dela deixaria o navegador escolher o que o lojista recusou.

Ele decide que MAIS o corpo carrega:

  • com credit_card, vêm installments, card_token, card_holder_name e billing_address, além dos campos de 3DS quando a loja exige autenticação do portador;
  • com pix, nenhum deles é enviado. Não há cartão para parcelar, endereço para o antifraude comparar nem portador para autenticar, e o que chega é só o comprador.

Numa sessão de um clique (card_id) o campo não é lido: o método é sempre cartão, porque não existe PIX guardado no cofre.

Available options:
pix,
credit_card

Response

A cobrança.

Uma cobrança, como a API a devolve. Todo campo desta lista está sempre presente - os anuláveis vêm com null, nunca ausentes. Marcar como opcional o que nunca falta obrigaria você a testar a existência de uma chave que sempre existe.

Nos webhooks há uma exceção documentada: veja ChargeMinimal.

object
string
required
Allowed value: "charge"
id
string
required

Código público da cobrança. Nunca é a chave primária: expor o autoincremento diria a qualquer cliente quantas vendas a plataforma inteira processou.

Example:

"ch_01k1y6r6m6q2x0p3d9v4t7c8n2"

status
enum<string>
required

Situação da cobrança. Só os estados de trânsito - pending, processing e in_analysis - ainda mudam sozinhos; os demais são terminais, exceto os que ainda admitem estorno.

processing e in_analysis são do cartão: a autorização é decidida na mesma requisição, mas pode parar na análise de fraude antes de virar paid ou failed. No PIX a cobrança vai direto de pending para o desfecho.

partially_refunded é estado próprio, e não um refunded com asterisco: tratar uma venda devolvida pela metade como estornada faria seu relatório descontar o valor inteiro.

chargedback é definitivo: o dinheiro voltou pelo caminho da bandeira, e nem cancelamento nem estorno são mais possíveis.

Available options:
pending,
processing,
in_analysis,
paid,
expired,
canceled,
partially_refunded,
refunded,
failed,
chargedback
payment_method
enum<string>
required

O meio pelo qual esta cobrança foi criada. Omitir o campo na criação continua significando pix - é o que toda integração que existe hoje espera, e mudar isso as quebraria todas de uma vez.

Available options:
pix,
credit_card
amount
integer<int64>
required

Valor cobrado, em centavos inteiros.

currency
string
required
Allowed value: "BRL"
platform_fee
integer<int64>
required

Nossa taxa, em centavos inteiros. Congelada na criação: reflete o contrato que valia quando a venda aconteceu, não o de hoje.

net_amount
integer<int64>
required

O que fica com o vendedor, em centavos inteiros: amount menos a nossa taxa e menos a taxa do meio de pagamento, que é descontada direto do recebimento dele. Por isso amount - platform_fee dá um número MAIOR que este.

refunded_amount
integer<int64>
required

Total já devolvido ao comprador, em centavos inteiros. Acumulado entre estornos parciais.

description
string | null
required
reference
string | null
required
metadata
object
required

O que você enviou na criação. Sempre um objeto, {} quando não houve nada - nunca null, para o seu código não ter dois casos a tratar.

Example:
customer
object | null
required

null na cobrança que não tem comprador vinculado. A chave em si nunca falta.

pix
object
required

Presente em toda cobrança, inclusive nas de cartão - onde os três campos vêm null. Um objeto sempre presente evita o if (charge.pix) antes de cada leitura.

card
object
required

Presente em toda cobrança, inclusive nas de PIX - onde os campos vêm null. Mesma regra do pix acima, e pelo mesmo motivo.

O que não está aqui, e não vai estar: os seis primeiros dígitos, o código de retorno da adquirente e a nota do antifraude. Os dois primeiros são diagnóstico nosso; a nota numa resposta pública seria um oráculo de risco para quem testa cartão em lote. O código de recusa sai numa recusa, em error.details.decline_code, onde quem lê é o seu servidor.

created_at
string<date-time> | null
required
paid_at
string<date-time> | null
required
expired_at
string<date-time> | null
required
refunded_at
string<date-time> | null
required