Skip to main content

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:
1

Etapa 1: Consulta de Débitos

Consulte os dados do veículo e seus débitos pendentes
2

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}
licensePlate
string
required
Placa do veículo no formato ABC1234 ou ABC1D23 (Mercosul)
uf
string
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:
POST /uvvi/v1/debts
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:
POST /uvvi/v1/card-token
cardNumber
string
required
Número do cartão de crédito (apenas números)
cardholderName
string
required
Nome do titular do cartão (como impresso no cartão)
expirationDate
string
required
Data de validade no formato MM/AAAA ou MM/AA
cvv
string
required
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
amount
number
required
Valor total a ser parcelado em reais
paymentMethod
string
required
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:
POST /uvvi/v1/checkout
debts
array
required
Lista de IDs dos débitos a serem pagos
customer
object
required
Dados do cliente pagador
vehicle
object
required
Dados do veículo
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:
POST /uvvi/v1/payment
checkoutId
string
required
ID do checkout gerado
paymentMethod
string
required
Método de pagamento: credit_card
cardToken
string
required
Token do cartão gerado na tokenização
installments
number
required
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
  }'
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

Status Imediatos (Cartão de Crédito)

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
paymentId
string
required
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

Fluxo Recomendado

1

Envie a Requisição

Faça a requisição de pagamento normalmente com timeout adequado de 30-60 segundos.
2

Trate a Resposta

Se receber resposta síncrona, processe o status imediatamente.
3

Em Caso de Timeout

Se ocorrer timeout, não considere como erro. Aguarde o webhook.
4

Receba o Webhook

O webhook será enviado com o status final do pagamento quando o processamento for concluído.
5

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