Checkouts
Checkout Transparente
/v1/checkouts/payhttps://api.validapay.com.brhttps://sandbox.validapay.com.brAutenticação
Nenhuma autenticação via header — credenciais enviadas no body da requisição.
Este é o endpoint onde o pagamento é de fato processado. O cliente preenche os dados diretamente na sua página e você envia para cá.
Efetuar pagamento via checkout transparente
Use esta rota para concluir uma compra a partir de uma sessão de checkout já criada. Não precisa de login — qualquer pessoa com o ID da sessão pode pagar.
Quando o pagamento é aprovado, a sessão é marcada como paga e não pode ser usada novamente.
Autenticação: não é necessária.
Identificação da sessão (obrigatório — um dos dois)
| Campo | Tipo | Descrição |
|---|---|---|
sessionId | texto | ID da sessão criada pelo vendedor. Começa com cs_ (produção) ou SANDBOX_cs_ (sandbox) |
checkoutId | texto | Mesmo que sessionId — aceito como alternativa |
Forma de pagamento
| Campo | Obrig. | Tipo | Descrição |
|---|---|---|---|
paymentMethod | ✅ | texto | Forma de pagamento: pix, creditcard ou boleto |
Cartão de crédito — preencha card OU tokenId:
| Campo | Obrig. | Tipo | Descrição |
|---|---|---|---|
card.number | ✅* | texto | Número do cartão (13 a 19 dígitos, só números) |
card.cvv | ✅* | texto | Código de segurança (3 ou 4 dígitos) |
card.name | ✅* | texto | Nome exatamente como está no cartão |
card.expiration | ✅* | texto | Validade no formato MM/YYYY (ex: 12/2027) |
paymentMethodId | ✅* | texto | ID de cartão tokenizado via /v1/payment-methods/tokenize — substitui card |
tokenId | ✅* | texto | Token de cartão salvo em pagamento anterior — substitui card |
cardInfo.brand | ❌ | texto | Bandeira do cartão tokenizado (ex: VISA) |
cardInfo.maskedNumber | ❌ | texto | Número mascarado do cartão tokenizado (ex: 411111******1111) |
cardInfo.holderName | ❌ | texto | Nome do titular do cartão tokenizado |
cardInfo.expiration | ❌ | texto | Validade do cartão tokenizado (MM/YYYY) |
*Para cartão, preencha card com os dados brutos, ou paymentMethodId com um cartão tokenizado, ou tokenId com um token salvo.
Dados do comprador
Se a sessão já foi criada com dados do cliente, eles são preenchidos automaticamente. Os campos enviados aqui sobrescrevem os da sessão.
| Campo | Obrig. | Tipo | Descrição |
|---|---|---|---|
customer.name | ✅ | texto | Nome completo do comprador |
customer.email | ✅ | texto | E-mail do comprador |
customer.documentNumber | ✅ | texto | CPF (11 dígitos) ou CNPJ (14 dígitos), somente números |
customer.phone | ❌ | texto | Telefone no formato internacional (ex: +5511999998888) |
customer.cep | ❌ | texto | CEP com 8 dígitos — necessário para PIX com dados do pagador |
customer.address.street | ✅ boleto | texto | Rua ou logradouro |
customer.address.number | ✅ boleto | texto | Número da residência |
customer.address.complement | ❌ | texto | Complemento (apto, sala, etc.) |
customer.address.neighborhood | ✅ boleto | texto | Bairro |
customer.address.city | ✅ boleto | texto | Cidade |
customer.address.state | ✅ boleto | texto | Estado com 2 letras (ex: SP) |
customer.address.zipCode | ✅ boleto | texto | CEP com 8 dígitos |
customer.address.country | ❌ | texto | País (padrão BR) |
customer.address.cityCode | ❌ | texto | Código IBGE da cidade — necessário para emissão de nota fiscal |
customer.metadata | ❌ | objeto | Informações extras do cliente (chave-valor livre) |
*Campos marcados como "✅ boleto" são obrigatórios apenas quando paymentMethod é boleto.
Produto ou valor
Se a sessão já tem produtos configurados, não é necessário enviar. Para alterar ou usar uma cobrança avulsa:
| Campo | Obrig. | Tipo | Descrição |
|---|---|---|---|
items[].priceId | ✅* | texto | ID do preço do produto (price_...) |
items[].quantity | ❌ | número | Quantidade (padrão: 1) |
items[].isOrderBump | ❌ | sim/não | Marcar como produto adicional (order bump) |
amount | ✅* | número | Valor em reais para cobrança avulsa — use quando não há items |
description | ❌ | texto | Descrição da cobrança avulsa |
*Envie items com produtos ou amount com valor avulso — um dos dois é obrigatório.
Parcelamento
| Campo | Obrig. | Tipo | Descrição |
|---|---|---|---|
installments | ❌ | número | Quantidade de parcelas (1 a 12, padrão 1). Limite por tipo de plano: anual→12, semestral→6, trimestral→3, avulso→12 |
passFeesToCustomer | ❌ | sim/não | Repassar as taxas da plataforma para o comprador (padrão: não) |
freeInstallments | ❌ | número | Quantidade de parcelas sem juros (0 a 12, padrão 1) |
Recorrência
| Campo | Obrig. | Tipo | Descrição |
|---|---|---|---|
billingDay | ❌ | número | Dia do mês em que as cobranças recorrentes serão geradas (1 a 31) |
prorataStartDate | ❌ | texto | Data de início para cálculo de pró-rata (YYYY-MM-DD) |
recurrencyStartDate | ❌ | texto | Data de início da recorrência (YYYY-MM-DD, hoje ou futura) |
Boleto
| Campo | Obrig. | Tipo | Descrição |
|---|---|---|---|
dueDate | ❌ | texto | Data de vencimento do boleto (YYYY-MM-DD, deve ser maior que hoje) |
boletoDueDays | ❌ | número | Dias até o vencimento a partir de hoje (mínimo 1) — calculado automaticamente se dueDate for informado |
expirationAfterDueDate | ❌ | número | Dias para o boleto ser cancelado após o vencimento (0 a 60) |
boletoInstructions.fine | ❌ | número | Multa por atraso em porcentagem (0.1 a 100). A soma de fine + interest não pode passar de 60% |
boletoInstructions.interest | ❌ | número | Juros mensais por atraso em porcentagem (0.1 a 100) |
boletoInstructions.discount.amount | ❌ | número | Valor do desconto para pagamento antecipado |
boletoInstructions.discount.modality | ❌ | texto | Tipo do desconto: fixed (valor em reais) ou percent (porcentagem). Padrão: fixed |
boletoInstructions.discount.limitDate | ❌ | texto | Data limite para usar o desconto (YYYY-MM-DD, deve ser antes de dueDate) |
PIX com dados do pagador
| Campo | Obrig. | Tipo | Descrição |
|---|---|---|---|
expiration | ❌ | texto | Data de expiração do QR Code PIX (YYYY-MM-DD, não pode ser passada) |
Cupom e descontos
| Campo | Obrig. | Tipo | Descrição |
|---|---|---|---|
couponCode | ❌ | texto | Código de cupom de desconto |
discounts | ❌ | lista | Descontos manuais — sobrescrevem os da sessão. Cada item deve ter type (PERCENTAGE ou FIXED) e amount ou value. Campos opcionais: paymentMethod, fromCycle, toCycle, durationMonths |
Split de pagamento
| Campo | Obrig. | Tipo | Descrição |
|---|---|---|---|
split[].type | ✅ | texto | Tipo do repasse: percentage (porcentagem) ou fixed (valor fixo) |
split[].accountNumber | ❌ | texto | Número da conta que vai receber o repasse |
split[].amount | ✅ | número | Valor ou porcentagem do repasse |
Outros
| Campo | Obrig. | Tipo | Descrição |
|---|---|---|---|
metadata | ❌ | objeto | Informações extras (chave-valor livre) que ficam salvas na cobrança |
nfConfigId | ❌ | texto | ID da configuração de nota fiscal. Quando informado, o endereço do comprador é obrigatório |
dfp_id | ❌ | texto | ID de device fingerprint — usado para análise antifraude |
Erros comuns: 404 SESSION_NOT_FOUND (sessão não existe), 400 SESSION_INACTIVE (sessão já foi paga ou expirou), 400 INVALID_DATA (campo inválido), 402 (pagamento recusado pelo banco).
Body
application/json
{
"sessionId": "cs_abc123",
"paymentMethod": "creditcard",
"customer": {
"name": "João da Silva",
"email": "joao@email.com",
"documentNumber": "12345678901",
"phone": "+5511999998888",
"cep": "01310100",
"address": {
"street": "Av. Paulista",
"number": "1000",
"complement": "Apto 52",
"neighborhood": "Bela Vista",
"city": "São Paulo",
"state": "SP",
"zipCode": "01310100",
"country": "BR",
"cityCode": "3550308"
},
"metadata": { "origem": "site" }
},
"paymentMethodId": "pm_abc123",
"card": {
"number": "4111111111111111",
"cvv": "123",
"name": "JOAO DA SILVA",
"expiration": "12/2027"
},
"items": [
{ "priceId": "price_abc123", "quantity": 1, "isOrderBump": false }
],
"installments": 1,
"passFeesToCustomer": false,
"freeInstallments": 1,
"billingDay": 10,
"prorataStartDate": "2026-06-15",
"recurrencyStartDate": "2026-07-01",
"dueDate": "2026-07-30",
"boletoDueDays": 7,
"expirationAfterDueDate": 30,
"boletoInstructions": {
"fine": 2.0,
"interest": 1.0,
"discount": {
"amount": 10.0,
"modality": "fixed",
"limitDate": "2026-07-28"
}
},
"expiration": "2026-07-30",
"couponCode": "PROMO10",
"discounts": [
{
"type": "PERCENTAGE",
"value": 10,
"paymentMethod": "pix",
"fromCycle": 1,
"toCycle": 3,
"durationMonths": 3
}
],
"split": [
{
"type": "percentage",
"accountNumber": "123456",
"amount": 10
}
],
"metadata": { "referencia": "pedido-001" },
"nfConfigId": null,
"dfp_id": null
}Schema
| Field | Type | Required | Description |
|---|---|---|---|
sessionId | string | - | - |
paymentMethod | string | - | - |
customer | object | - | - |
paymentMethodId | string | - | - |
card | object | - | - |
items[1] | array | - | - |
installments | number | - | - |
passFeesToCustomer | boolean | - | - |
freeInstallments | number | - | - |
billingDay | number | - | - |
prorataStartDate | string | - | - |
recurrencyStartDate | string | - | - |
dueDate | string | - | - |
boletoDueDays | number | - | - |
expirationAfterDueDate | number | - | - |
boletoInstructions | object | - | - |
expiration | string | - | - |
couponCode | string | - | - |
discounts[1] | array | - | - |
split[1] | array | - | - |
metadata | object | - | - |
nfConfigId | object | - | - |
dfp_id | object | - | - |
Headers
| Name | Type | Value | Required |
|---|---|---|---|
| Content-Type | - | application/json | Optional |
const url = 'https://sandbox.validapay.com.br/v1/checkouts/pay';
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
"sessionId": "cs_abc123",
"paymentMethod": "creditcard",
"customer": {
"name": "João da Silva",
"email": "joao@email.com",
"documentNumber": "12345678901",
"phone": "+5511999998888",
"cep": "01310100",
"address": {
"street": "Av. Paulista",
"number": "1000",
"complement": "Apto 52",
"neighborhood": "Bela Vista",
"city": "São Paulo",
"state": "SP",
"zipCode": "01310100",
"country": "BR",
"cityCode": "3550308"
},
"metadata": { "origem": "site" }
},
"paymentMethodId": "pm_abc123",
"card": {
"number": "4111111111111111",
"cvv": "123",
"name": "JOAO DA SILVA",
"expiration": "12/2027"
},
"items": [
{ "priceId": "price_abc123", "quantity": 1, "isOrderBump": false }
],
"installments": 1,
"passFeesToCustomer": false,
"freeInstallments": 1,
"billingDay": 10,
"prorataStartDate": "2026-06-15",
"recurrencyStartDate": "2026-07-01",
"dueDate": "2026-07-30",
"boletoDueDays": 7,
"expirationAfterDueDate": 30,
"boletoInstructions": {
"fine": 2.0,
"interest": 1.0,
"discount": {
"amount": 10.0,
"modality": "fixed",
"limitDate": "2026-07-28"
}
},
"expiration": "2026-07-30",
"couponCode": "PROMO10",
"discounts": [
{
"type": "PERCENTAGE",
"value": 10,
"paymentMethod": "pix",
"fromCycle": 1,
"toCycle": 3,
"durationMonths": 3
}
],
"split": [
{
"type": "percentage",
"accountNumber": "123456",
"amount": 10
}
],
"metadata": { "referencia": "pedido-001" },
"nfConfigId": null,
"dfp_id": null
})
};
fetch(url, options)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));Response Examples
{
"success": true,
"subscriptionId": "sub_xxx",
"customerId": "cus_xxx",
"chargeId": "cha_xxx"
}{
"success": true,
"chargeId": "cha_abc123",
"status": "paid"
}{
"success": true,
"subscriptionId": "sub_xxx",
"pix": {
"emv": "...",
"qrCode": "..."
}
}{
"success": true,
"subscriptionId": "sub_xxx",
"boleto": {
"digitableLine": "...",
"dueDate": "2024-02-15"
}
}{
"success": false,
"status": "failed",
"error": "Cartão recusado"
}{
"code": "SESSION_NOT_FOUND"
}{
"error": {
"message": "Cobrança não encontrada",
"code": "CHARGE_NOT_FOUND"
}
}{
"error": {
"message": "Apenas cobranças pendentes podem ser processadas",
"code": "CHARGE_NOT_PAYABLE"
}
}{
"error": {
"message": "tokenId, card ou paymentMethodId é obrigatório",
"code": "MISSING_CARD_DATA"
}
}