Visão Geral
O fluxo completo da Uvvipague permite que o parceiro consulte débitos veiculares e realize o pagamento de forma integrada, com proteção antifraude incluída.
Antifraude Integrado : Todos os pagamentos passam pelo sistema antifraude da Uvvipague, garantindo segurança nas transações.
Fluxo de Integração
O processo completo é dividido em duas etapas principais:
Etapa 1: Consulta de Débitos
Consulte os dados do veículo e seus débitos pendentes
Etapa 2: Pagamento e Liquidação
Tokenize o cartão, gere o checkout e efetue o pagamento
Etapa 1: Consulta de Débitos
Nesta etapa, você consulta as informações do veículo e seus débitos pendentes.
1.1 Enriquecer Dados do Veículo (Opcional)
Primeiro, você pode enriquecer os dados do veículo usando apenas a placa:
GET /api/v1/vehicle/enrichment/{licensePlate}
Placa do veículo no formato ABC1234 ou ABC1D23 (Mercosul)
Sigla do estado (opcional, mas recomendado para otimizar a consulta)
curl --request GET \
--url 'https://api.uvvipague.com.br/api/v1/vehicle/enrichment/ABC1234?uf=SP' \
--header 'x-api-key: SUA_API_KEY_AQUI' \
--header 'Content-Type: application/json'
Resposta:
{
"success" : true ,
"data" : {
"placa" : "ABC1234" ,
"renavam" : "12345678901" ,
"chassi" : "9BWZZZ377VT004251" ,
"uf" : "SP" ,
"municipio" : "São Paulo" ,
"marca" : "VOLKSWAGEN" ,
"modelo" : "GOL 1.0" ,
"anoFabricacao" : "2020" ,
"anoModelo" : "2021" ,
"cor" : "PRATA" ,
"combustivel" : "FLEX" ,
"categoria" : "PARTICULAR"
}
}
Este passo é opcional . Você pode pular direto para a consulta de débitos se já tiver os dados do veículo (placa, RENAVAM e CPF/CNPJ do proprietário).
1.2 Consultar Débitos do Veículo
Consulte os débitos pendentes do veículo:
curl --request POST \
--url 'https://api.uvvipague.com.br/uvvi/v1/debts' \
--header 'x-api-key: SUA_API_KEY_AQUI' \
--header 'Content-Type: application/json' \
--data '{
"state": "SP",
"licensePlate": "ABC1234",
"renavam": "12345678901",
"cpfCnpj": "12345678900"
}'
Resposta:
{
"success" : true ,
"transactionId" : 817210768 ,
"debts" : [
{
"id" : "9547B3A8-05B9-4D1C-8C72-A500BB6D93EF" ,
"amount" : 293.50 ,
"title" : "Multa de Trânsito" ,
"description" : "Infração de velocidade" ,
"type" : "ticket" ,
"dueDate" : "2024-01-15" ,
"isExpired" : true
},
{
"id" : "312D6A5F-2B5A-4694-84DA-F640FC01CC74" ,
"amount" : 1009.36 ,
"title" : "Licenciamento 2024" ,
"description" : "Taxa de licenciamento anual" ,
"type" : "licensing" ,
"year" : 2024 ,
"isExpired" : false
}
],
"totalAmount" : 1302.86
}
Etapa 2: Pagamento e Liquidação
Após consultar os débitos, você pode processar o pagamento.
2.1 Tokenizar Cartão de Crédito
Antes de processar o pagamento, tokenize os dados do cartão para maior segurança:
Número do cartão de crédito (apenas números)
Nome do titular do cartão (como impresso no cartão)
Data de validade no formato MM/AAAA ou MM/AA
Código de segurança (CVV - 3 ou 4 dígitos)
curl --request POST \
--url 'https://api.uvvipague.com.br/uvvi/v1/card-token' \
--header 'x-api-key: SUA_API_KEY_AQUI' \
--header 'Content-Type: application/json' \
--data '{
"cardNumber": "4111111111111111",
"cardholderName": "JOAO DA SILVA",
"expirationDate": "12/2030",
"cvv": "123"
}'
Resposta:
{
"success" : true ,
"data" : {
"token" : "tok_abc123def456ghi789" ,
"brand" : "visa" ,
"lastFourDigits" : "1111" ,
"expiresAt" : "2024-01-16T14:30:00Z"
}
}
Segurança : Nunca armazene dados completos do cartão. Sempre use o token gerado para processar pagamentos.
2.2 Simular Parcelas (Opcional)
Antes de criar o checkout, você pode simular as opções de parcelamento disponíveis:
POST /uvvi/v1/installments
Valor total a ser parcelado em reais
Método de pagamento: credit_card
curl --request POST \
--url 'https://api.uvvipague.com.br/uvvi/v1/installments' \
--header 'x-api-key: SUA_API_KEY_AQUI' \
--header 'Content-Type: application/json' \
--data '{
"amount": 1302.86,
"paymentMethod": "credit_card"
}'
Resposta:
{
"success" : true ,
"amount" : 1302.86 ,
"installments" : [
{
"number" : 1 ,
"installmentAmount" : 1342.95 ,
"totalAmount" : 1342.95 ,
"interestRate" : 3.08 ,
"interestAmount" : 40.09
},
{
"number" : 2 ,
"installmentAmount" : 676.49 ,
"totalAmount" : 1352.98 ,
"interestRate" : 3.84 ,
"interestAmount" : 50.12
},
{
"number" : 3 ,
"installmentAmount" : 467.95 ,
"totalAmount" : 1403.85 ,
"interestRate" : 7.75 ,
"interestAmount" : 100.99
},
{
"number" : 4 ,
"installmentAmount" : 363.46 ,
"totalAmount" : 1453.84 ,
"interestRate" : 11.59 ,
"interestAmount" : 150.98
},
{
"number" : 5 ,
"installmentAmount" : 301.18 ,
"totalAmount" : 1505.90 ,
"interestRate" : 15.58 ,
"interestAmount" : 203.04
},
{
"number" : 6 ,
"installmentAmount" : 259.65 ,
"totalAmount" : 1557.90 ,
"interestRate" : 19.57 ,
"interestAmount" : 255.04
}
]
}
Importante : A simulação mostra todas as opções de parcelamento disponíveis com os valores exatos de juros. Use essas informações para apresentar as opções ao usuário antes de processar o pagamento.
Atenção : Todos os pagamentos possuem juros aplicados, incluindo pagamento à vista (1x) e PIX. Sempre apresente o valor total ao usuário de forma transparente.
2.3 Gerar Checkout
Crie um checkout com os débitos que serão pagos:
Lista de IDs dos débitos a serem pagos
curl --request POST \
--url 'https://api.uvvipague.com.br/uvvi/v1/checkout' \
--header 'x-api-key: SUA_API_KEY_AQUI' \
--header 'Content-Type: application/json' \
--data '{
"debts": [
"9547B3A8-05B9-4D1C-8C72-A500BB6D93EF",
"312D6A5F-2B5A-4694-84DA-F640FC01CC74"
],
"customer": {
"name": "João da Silva",
"email": "joao@example.com",
"cpfCnpj": "12345678900",
"phone": "11987654321"
},
"vehicle": {
"licensePlate": "ABC1234",
"renavam": "12345678901",
"uf": "SP"
}
}'
Resposta:
{
"success" : true ,
"checkoutId" : "chk_xyz789abc123def456" ,
"amount" : 1302.86 ,
"debts" : [
{
"id" : "9547B3A8-05B9-4D1C-8C72-A500BB6D93EF" ,
"amount" : 293.50
},
{
"id" : "312D6A5F-2B5A-4694-84DA-F640FC01CC74" ,
"amount" : 1009.36
}
],
"expiresAt" : "2024-12-15T23:59:59Z"
}
2.4 Efetuar Pagamento
Realize o pagamento usando cartão de crédito ou PIX:
Método de pagamento: credit_card
Token do cartão gerado na tokenização
Número de parcelas (1 para pagamento à vista)
curl --request POST \
--url 'https://api.uvvipague.com.br/uvvi/v1/payment' \
--header 'x-api-key: SUA_API_KEY_AQUI' \
--header 'Content-Type: application/json' \
--data '{
"checkoutId": "chk_xyz789abc123def456",
"paymentMethod": "credit_card",
"cardToken": "tok_abc123def456ghi789",
"installments": 1
}'
curl --request POST \
--url 'https://api.uvvipague.com.br/uvvi/v1/payment' \
--header 'x-api-key: SUA_API_KEY_AQUI' \
--header 'Content-Type: application/json' \
--data '{
"checkoutId": "chk_xyz789abc123def456",
"paymentMethod": "pix"
}'
Resposta PIX: {
"success" : true ,
"paymentId" : "pay_pix123abc456def" ,
"status" : "awaiting_payment" ,
"qrCode" : "00020126580014br.gov.bcb.pix..." ,
"qrCodeImage" : "data:image/png;base64,iVBORw0KGgo..." ,
"expiresAt" : "2024-12-15T18:30:00Z"
}
Resposta Cartão de Crédito:
{
"success" : true ,
"paymentId" : "pay_abc123def456ghi789" ,
"status" : "paid" ,
"transactionId" : "817210768" ,
"amount" : 1302.86 ,
"installments" : 1 ,
"paidAt" : "2024-12-15T14:30:00Z"
}
Status de Pagamento
Ao processar pagamento com cartão, os seguintes status são retornados imediatamente:
paid Pago : Transação aprovada e processada com sucesso
in_analysis Em Análise : Transação em análise pelo antifraude
refused Recusado : Transação recusada pela operadora ou antifraude
processing Processando : Transação sendo processada
awaiting_payment Aguardando Pagamento : Aguardando confirmação (comum em PIX)
Todos os Status Possíveis
Para ver a lista completa de status de transações, incluindo status de liquidação, consulte a documentação de status .
2.5 Consultar Status do Pedido
Após o pagamento, você pode consultar o status de liquidação:
POST /uvvi/v1/payment/status
ID do pagamento a ser consultado
curl --request POST \
--url 'https://api.uvvipague.com.br/uvvi/v1/payment/status' \
--header 'x-api-key: SUA_API_KEY_AQUI' \
--header 'Content-Type: application/json' \
--data '{
"paymentId": "pay_abc123def456ghi789"
}'
Resposta:
{
"success" : true ,
"paymentId" : "pay_abc123def456ghi789" ,
"status" : "paid" ,
"liquidationStatus" : "settled" ,
"amount" : 1302.86 ,
"paidAt" : "2024-12-15T14:30:00Z" ,
"settledAt" : "2024-12-16T10:15:00Z" ,
"debts" : [
{
"id" : "9547B3A8-05B9-4D1C-8C72-A500BB6D93EF" ,
"status" : "settled" ,
"settledAt" : "2024-12-16T10:15:00Z"
},
{
"id" : "312D6A5F-2B5A-4694-84DA-F640FC01CC74" ,
"status" : "settled" ,
"settledAt" : "2024-12-16T10:15:00Z"
}
]
}
Resumo dos Endpoints
Enriquecer Veículo GET /api/v1/vehicle/enrichment/{placa}Enriquece dados do veículo pela placa (opcional)
Consultar Débitos POST /uvvi/v1/debtsConsulta débitos pendentes do veículo
Tokenizar Cartão POST /uvvi/v1/card-tokenGera token seguro do cartão de crédito
Simular Parcelas POST /uvvi/v1/installmentsSimula opções de parcelamento disponíveis
Gerar Checkout POST /uvvi/v1/checkoutCria checkout com débitos selecionados
Efetuar Pagamento POST /uvvi/v1/paymentProcessa pagamento via cartão ou PIX
Consultar Pagamento POST /uvvi/v1/payment/statusVerifica status e liquidação do pagamento
Fluxo Completo - Diagrama
Exemplo Completo de Integração
const UvvipagueClient = require ( './uvvipague-client' );
async function processarPagamentoCompleto () {
const client = new UvvipagueClient ( process . env . UVVIPAGUE_API_KEY );
try {
// 1. Enriquecer dados do veículo (opcional)
console . log ( '1. Enriquecendo dados do veículo...' );
const veiculo = await client . enriquecerVeiculo ({
licensePlate: 'ABC1234' ,
uf: 'SP'
});
console . log ( 'Veículo:' , veiculo . data );
// 2. Consultar débitos
console . log ( '2. Consultando débitos...' );
const debitos = await client . consultarDebitos ({
state: 'SP' ,
licensePlate: 'ABC1234' ,
renavam: veiculo . data . renavam ,
cpfCnpj: '12345678900'
});
console . log ( `Encontrados ${ debitos . debts . length } débitos` );
console . log ( `Total: R$ ${ debitos . totalAmount } ` );
// 3. Simular parcelas
console . log ( '3. Simulando parcelas...' );
const simulacao = await client . simularParcelas ({
amount: debitos . totalAmount ,
paymentMethod: 'credit_card'
});
console . log ( `Opções de parcelamento: ${ simulacao . installments . length } ` );
simulacao . installments . forEach ( opt => {
console . log ( ` ${ opt . number } x de R$ ${ opt . installmentAmount . toFixed ( 2 ) } (total: R$ ${ opt . totalAmount . toFixed ( 2 ) } )` );
});
// 4. Tokenizar cartão
console . log ( '4. Tokenizando cartão...' );
const token = await client . tokenizarCartao ({
cardNumber: '4111111111111111' ,
cardholderName: 'JOAO DA SILVA' ,
expirationMonth: '12' ,
expirationYear: '2025' ,
securityCode: '123'
});
console . log ( 'Token gerado:' , token . cardToken );
// 5. Criar checkout
console . log ( '5. Criando checkout...' );
const checkout = await client . criarCheckout ({
debts: debitos . debts . map ( d => d . id ),
customer: {
name: 'João da Silva' ,
email: 'joao@example.com' ,
cpfCnpj: '12345678900' ,
phone: '11987654321'
},
vehicle: {
licensePlate: 'ABC1234' ,
renavam: veiculo . data . renavam ,
uf: 'SP'
}
});
console . log ( 'Checkout ID:' , checkout . checkoutId );
// 6. Efetuar pagamento
console . log ( '6. Efetuando pagamento...' );
const pagamento = await client . efetuarPagamento ({
checkoutId: checkout . checkoutId ,
paymentMethod: 'credit_card' ,
cardToken: token . cardToken ,
installments: 1
});
console . log ( 'Pagamento ID:' , pagamento . paymentId );
console . log ( 'Status:' , pagamento . status );
// 7. Aguardar e consultar status
console . log ( '7. Aguardando processamento...' );
await sleep ( 5000 );
const status = await client . consultarPagamento ({
paymentId: pagamento . paymentId
});
console . log ( 'Status final:' , status . status );
console . log ( 'Status de liquidação:' , status . liquidationStatus );
return {
success: true ,
paymentId: pagamento . paymentId ,
status: status
};
} catch ( error ) {
console . error ( 'Erro no processamento:' , error . message );
throw error ;
}
}
function sleep ( ms ) {
return new Promise ( resolve => setTimeout ( resolve , ms ));
}
// Executar
processarPagamentoCompleto ()
. then ( result => console . log ( 'Sucesso!' , result ))
. catch ( error => console . error ( 'Falha:' , error ));
Processamento Síncrono vs Assíncrono
Importante sobre Timeouts : A API pode retornar respostas de forma síncrona na maioria dos casos, porém, em situações de alta carga ou lentidão nos sistemas dos Detrans, você pode receber um timeout na resposta síncrona.
Comportamento da API
A API Uvvipague opera em dois modos:
Cenário Ideal : Quando os sistemas estão operando normalmente, você recebe a resposta imediatamente na mesma requisição.// Requisição
const response = await fetch ( '/uvvi/v1/payment' , {
method: 'POST' ,
body: JSON . stringify ( paymentData )
});
// Resposta imediata
const result = await response . json ();
console . log ( result . status ); // 'paid', 'refused', etc.
Status retornados sincronamente:
paid - Pagamento aprovado
refused - Pagamento recusado
in_analysis - Em análise
processing - Processando
Cenário de Timeout : Se a API não conseguir processar em tempo hábil, você receberá um timeout.// Requisição
try {
const response = await fetch ( '/uvvi/v1/payment' , {
method: 'POST' ,
body: JSON . stringify ( paymentData ),
signal: AbortSignal . timeout ( 30000 ) // 30 segundos
});
const result = await response . json ();
} catch ( error ) {
if ( error . name === 'TimeoutError' ) {
console . log ( 'Timeout - aguardar webhook' );
// Aguardar notificação via webhook
}
}
Ação recomendada:
Aguarde a notificação via webhook
O webhook será enviado quando o processamento for concluído
Use o transactionId ou externalId para correlacionar
Fluxo Recomendado
Envie a Requisição
Faça a requisição de pagamento normalmente com timeout adequado de 30-60 segundos.
Trate a Resposta
Se receber resposta síncrona, processe o status imediatamente.
Em Caso de Timeout
Se ocorrer timeout, não considere como erro. Aguarde o webhook.
Receba o Webhook
O webhook será enviado com o status final do pagamento quando o processamento for concluído.
Fallback Manual
Se não receber o webhook após as retentativas, consulte manualmente o status usando o endpoint de consulta.
Exemplo de Implementação
async function processarPagamento ( paymentData ) {
const timeoutMs = 30000 ; // 30 segundos
try {
// Tentar resposta síncrona
const controller = new AbortController ();
const timeoutId = setTimeout (() => controller . abort (), timeoutMs );
const response = await fetch ( '/uvvi/v1/payment' , {
method: 'POST' ,
headers: {
'x-api-key' : process . env . API_KEY ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ( paymentData ),
signal: controller . signal
});
clearTimeout ( timeoutId );
const result = await response . json ();
// Resposta síncrona recebida
console . log ( 'Resposta síncrona:' , result . status );
await processarStatusPagamento ( result );
return {
mode: 'sync' ,
status: result . status ,
paymentId: result . paymentId
};
} catch ( error ) {
if ( error . name === 'AbortError' ) {
// Timeout - aguardar webhook
console . log ( 'Timeout na API - aguardando webhook' );
// Salvar no banco como "aguardando webhook"
await database . payments . create ({
externalId: paymentData . externalId ,
status: 'awaiting_webhook' ,
createdAt: new Date ()
});
return {
mode: 'async' ,
status: 'awaiting_webhook' ,
message: 'Aguardando confirmação via webhook'
};
}
throw error ;
}
}
// Handler do webhook
app . post ( '/webhook/uvvipague' , async ( req , res ) => {
// Retornar 200 imediatamente
res . status ( 200 ). json ({ received: true });
const { paymentId , status , externalId } = req . body ;
// Atualizar status no banco
await database . payments . update (
{ externalId },
{
status ,
paymentId ,
processedAt: new Date (),
mode: 'webhook'
}
);
console . log ( `Pagamento ${ paymentId } atualizado via webhook: ${ status } ` );
});
Boas Práticas
Configure Timeout Adequado Use timeout de 30-60 segundos para dar tempo de processamento sem travar sua aplicação.
Sempre Configure Webhook Configure webhooks mesmo que receba resposta síncrona. É seu fallback em caso de timeout.
Use externalId Sempre envie externalId único para correlacionar requisições com webhooks.
Status Intermediário Salve status intermediário “awaiting_webhook” quando ocorrer timeout para tracking.
Resumo : Trate a API como síncrona por padrão , mas esteja preparado para processamento assíncrono via webhook em caso de timeout. Configure webhooks como parte essencial da integração.
Próximos Passos