Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.pagamentos.dev/llms.txt

Use this file to discover all available pages before exploring further.

O que é roteamento inteligente?

O roteamento inteligente permite que o pagamentos.dev escolha automaticamente o provedor mais adequado para cada operação, em vez de sempre usar o mesmo. Isso é especialmente útil quando você integra múltiplos provedores e quer otimar custos ou garantir alta disponibilidade. Há duas estratégias de roteamento disponíveis:
  • melhorTaxa() — escolhe o provedor que oferece o menor custo de taxa para o valor e método de pagamento da transação.
  • disponibilidade() — tenta os provedores em uma ordem de prioridade definida por você, fazendo fallback automaticamente se o primeiro falhar.

Requisitos

Para usar roteamento, você precisa de pelo menos 2 provedores configurados. Além disso, todos os provedores devem ter uma taxa configurada.
import { Pagamentos, melhorTaxa, abacatepay, mercadopago } from 'pagamentos'

const pg = new Pagamentos({
  router: melhorTaxa(),
  providers: [
    abacatepay({
      apiKey: '...',
      taxa: { type: 'flat', value: 80 } // R$ 0,80 em centavos
    }),
    mercadopago({
      accessToken: '...',
      taxa: { type: 'percentage', value: (v) => v * 0.01 } // 1%
    })
  ]
})
Se algum provedor não tiver taxa configurada, o SDK lançará um erro no momento da inicialização.

Router melhorTaxa()

O router melhorTaxa() compara o custo líquido (valor - taxa) de cada provedor e escolhe o que oferece o melhor valor. A taxa nunca é descontada do valor enviado ao provedor — ela serve apenas para comparação interna de custo.

Exemplo prático

Imagine que você tem:
  • AbacatePay cobra uma taxa fixa de R$ 0,80 (80 centavos)
  • MercadoPago cobra 1% sobre o valor da transação
import { Pagamentos, melhorTaxa, abacatepay, mercadopago } from 'pagamentos'

const pg = new Pagamentos({
  router: melhorTaxa(),
  providers: [
    abacatepay({
      apiKey: '...',
      taxa: { type: 'flat', value: 80 }
    }),
    mercadopago({
      accessToken: '...',
      taxa: { type: 'percentage', value: (originalValue) => originalValue * 0.01 }
    })
  ]
})

// Para R$ 50,00 (5000 centavos):
// AbacatePay: 5000 - 80 = 4920
// MercadoPago: 5000 - 50 = 4950
// -> Escolhe MercadoPago
await pg.cobrancas.create({ idempotencyKey: crypto.randomUUID(), valor: 5000, metodoPagamento: 'pix' })

// Para R$ 100,00 (10000 centavos):
// AbacatePay: 10000 - 80 = 9920
// MercadoPago: 10000 - 100 = 9900
// -> Escolhe AbacatePay
await pg.cobrancas.create({ idempotencyKey: crypto.randomUUID(), valor: 10_000, metodoPagamento: 'pix' })

Tipos de taxa

Você pode definir a taxa de três formas:
TipoDescriçãoExemplo
flatValor fixo em centavos{ type: 'flat', value: 80 } = R$ 0,80
percentageFunção que recebe o valor original e retorna a taxa{ type: 'percentage', value: (v) => v * 0.01 } = 1%
asyncValor ou função assíncrona{ type: 'flat', value: async () => getFromDatabase() }

Taxa por método de pagamento

Você também pode definir taxas diferentes por método de pagamento usando um array:
woovi({
  appId: '...',
  mode: 'production',
  taxa: [
    { type: 'flat', metodosPagamento: ['pix'], value: 10 },
    { type: 'flat', metodosPagamento: ['boleto'], value: 100 }
  ]
})
Se você usar metodosPagamento em uma taxa, todos os métodos de pagamento usados pela sua aplicação devem estar cobertos por pelo menos uma taxa do provedor. Caso contrário, o SDK lançará um erro informando qual método não está coberto.

Router disponibilidade()

O router disponibilidade() define uma ordem de prioridade entre os provedores. Ele sempre tenta o primeiro da lista; se a operação falhar por timeout ou erro 5xx (após os retries configurados), ele passa automaticamente para o próximo provedor da ordem.
import { Pagamentos, disponibilidade, abacatepay, mercadopago, woovi } from 'pagamentos'

const pg = new Pagamentos({
  router: disponibilidade({ ordem: ['woovi', 'abacatepay', 'mercadopago'] }),
  providers: [
    woovi({ appId: '...', mode: 'production', taxa: { type: 'flat', value: 10 } }),
    abacatepay({ apiKey: '...', taxa: { type: 'flat', value: 80 } }),
    mercadopago({ accessToken: '...', taxa: { type: 'percentage', value: (v) => v * 0.01 } })
  ]
})
Neste exemplo:
  1. Sempre tenta a Woovi primeiro.
  2. Se a Woovi não responder dentro do timeout ou retornar 5xx, tenta a AbacatePay.
  3. Se a AbacatePay também falhar, tenta o MercadoPago.
  4. Se todos falharem, lança um erro agregado.

Configurações globais

Você pode configurar o timeout e o número de retries diretamente na instância Pagamentos:
const pg = new Pagamentos({
  router: melhorTaxa(),
  timeout: 15_000,      // 15 segundos (padrão)
  retryCount: 1,        // 1 tentativa por provedor (padrão)
  providers: [/* ... */]
})
OpçãoPadrãoDescrição
timeout15_000Tempo máximo de espera por uma resposta do provedor, em milissegundos.
retryCount1Número de tentativas por provedor antes de considerar que ele falhou.

Override manual do provedor

Mesmo com um router configurado, você pode forçar um provedor específico passando { provider: 'nome' } como último argumento da operação:
// Normalmente o router escolheria automaticamente
await pg.cobrancas.create({ idempotencyKey: crypto.randomUUID(), valor: 5000, metodoPagamento: 'pix' })

// Forçando um provedor específico
await pg.cobrancas.create(
  { idempotencyKey: crypto.randomUUID(), valor: 5000, metodoPagamento: 'pix' },
  { provider: 'abacatepay' }
)
Isso é útil para:
  • Testes e debugging
  • Casos especiais onde você sabe qual provedor usar
  • Migrar clientes gradualmente entre provedores

Exemplo completo

Aqui está um exemplo completo combinando roteamento por taxa com múltiplos provedores e configurações personalizadas:
import {
  Pagamentos,
  melhorTaxa,
  abacatepay,
  mercadopago,
  woovi,
  onCobrancaCreated
} from 'pagamentos'

const pg = new Pagamentos({
  router: melhorTaxa(),
  timeout: 10_000,     // 10 segundos de timeout
  retryCount: 2,       // 2 tentativas por provedor
  providers: [
    abacatepay({
      apiKey: process.env.ABACATEPAY_API_KEY!,
      taxa: { type: 'flat', value: 80 }
    }),
    mercadopago({
      accessToken: process.env.MERCADOPAGO_ACCESS_TOKEN!,
      taxa: { type: 'percentage', value: (v) => v * 0.01 }
    }),
    woovi({
      appId: process.env.WOOVI_APP_ID!,
      mode: 'production',
      taxa: [
        { type: 'flat', metodosPagamento: ['pix'], value: 15 },
        { type: 'flat', metodosPagamento: ['boleto'], value: 120 }
      ]
    })
  ],
  hooks: [
    onCobrancaCreated(async (evt) => {
      console.log(`Cobrança criada no provedor: ${evt.provider}`)
      console.log(`ID: ${evt.output.id}, Valor: ${evt.output.valor}`)
    })
  ]
})

// O SDK escolhe automaticamente o provedor mais barato
const cobranca = await pg.cobrancas.create({
  idempotencyKey: crypto.randomUUID(),
  valor: 7500, // R$ 75,00
  metodoPagamento: 'pix',
  cliente: {
    nome: 'Maria Souza',
    documento: '987.654.321-00'
  }
})

Dicas e boas práticas

  • Taxas em centavos: o tipo flat sempre usa centavos. 80 = R0,80,1000=R 0,80, `1000` = R 10,00.
  • Taxa é apenas para comparação: o valor enviado ao provedor é o valor original da cobrança. A taxa não é descontada automaticamente.
  • Cobertura completa de métodos: quando usar metodosPagamento em taxas, certifique-se de que todos os métodos que sua aplicação usa estejam cobertos.
  • Combine com hooks: use lifecycle hooks para registrar qual provedor foi escolhido em cada transação. Isso ajuda na análise e reconciliação.
  • Monitore falhas: ao usar disponibilidade(), monitore logs de fallback para identificar provedores com instabilidade.
  • Teste antes de ativar: teste o comportamento do router com valores diferentes para entender quando cada provedor será escolhido.

Quando usar cada router?

CenárioRouter recomendado
Quer minimizar custos de taxamelhorTaxa()
Tem provedores com SLA diferentesdisponibilidade()
Quer priorizar um provedor mas ter backupdisponibilidade()
Taxas variam muito por valor de transaçãomelhorTaxa()
Precisa de alta disponibilidade (failover)disponibilidade()