Pular para o conteúdo principal
O Plugin Pix Indireto (BTG) conecta-se a diversos serviços da Lerian e provedores externos para processar pagamentos Pix. Configurá-lo envolve definir a conexão do plugin com cada serviço e preparar os dados de que esses serviços precisam para operar. O plugin é executado em duas camadas principais — uma Aplicação que expõe a API Pix e processa a lógica de negócio, e um conjunto de Workers que tratam dos webhooks de entrada vindos do BTG, da entrega de eventos de saída para o seu sistema e da conciliação DICT com o BACEN. As duas camadas compartilham a mesma configuração de base (licença, Midaz, CRM, BTG), mas têm suas próprias configurações específicas de serviço.

Pré-requisitos


Antes de começar, certifique-se de que você tem:
  • Seu ISPB (Identificador do Sistema de Pagamentos Brasileiro) — o identificador de 8 dígitos derivado do CNPJ da sua instituição
  • Acesso às suas instâncias do Midaz e do CRM (implantadas e em execução)
  • Acesso aos serviços do provedor BTG (o BTG fornece as credenciais)
# Your institution's ISPB (8 digits)
PIX_ISPB=12345678
PIX_ISPB também é usado para detectar transferências intra-PSP (P2P): quando o ISPB de destino de uma transferência corresponde a esse valor, o plugin liquida a transferência internamente em vez de roteá-la para o BTG, ainda reportando-a ao BACEN. Consulte Transferências intra-PSP.

1. Licença


O plugin é uma solução enterprise e requer uma licença válida para operar. A Lerian fornece a chave de licença durante o onboarding.
# License key provided by Lerian
LICENSE_KEY=

# Authorized organization IDs (comma-separated)
ORGANIZATION_IDS=
Documentação relacionada: Licença da Lerian

2. Access Manager (opcional)


O Access Manager trata da autenticação do plugin. Quando habilitado, ele valida todas as requisições recebidas antes que elas cheguem à API do plugin.
# Require authentication for all plugin requests (true/false)
PLUGIN_AUTH_ENABLED=false

# Access Manager service URL
PLUGIN_AUTH_ADDRESS=
Quando PLUGIN_AUTH_ENABLED=true, o plugin valida o cabeçalho Authorization de cada requisição para garantir que:
  • O token pertence a um usuário ou aplicação autorizado
  • O token concede acesso ao endpoint e método de API solicitados
Você só precisa fornecer credenciais de cliente (CLIENT_ID / CLIENT_SECRET) para os serviços Midaz, CRM e Fee se esses serviços também tiverem a autenticação do Access Manager habilitada.
Documentação relacionada: Access Manager

3. Midaz


O Midaz é o ledger central de todas as transações Pix que o plugin processa. O plugin registra toda operação de cash-in, cash-out e devolução no Midaz como uma transação de partidas dobradas.

Conexão


# Your organization ID in Midaz
MIDAZ_ORGANIZATION_ID=

# Your ledger ID in Midaz
MIDAZ_LEDGER_ID=

# Midaz Transaction module URL
MIDAZ_TRANSACTION_URL=

# Midaz Onboarding module URL
MIDAZ_ONBOARDING_URL=

# Midaz API credentials (required if Midaz has authentication enabled)
MIDAZ_CLIENT_ID=
MIDAZ_CLIENT_SECRET=

Requisitos de ativo


Configure um ativo na sua organização e ledger com estas propriedades:
PropriedadeValor
Tipocurrency
CódigoBRL
Vincule todas as contas ao seu ledger usando o ativo BRL. O plugin rejeita operações em contas que não correspondam a essa configuração.

Configuração de conta


Antes de usar o plugin, crie no Midaz uma conta para cada cliente sob o seu ISPB. Use o endpoint Create an Account para configurar as contas. Cada conta deve:
  • Pertencer à organização e ao ledger que você configurou
  • Usar o ativo BRL

Cabeçalho X-Account-Id


Muitas operações Pix exigem o cabeçalho X-Account-Id para identificar qual conta está executando a ação. Esse ID corresponde ao ID da conta no ledger do Midaz. Quando você chama um endpoint do plugin, o valor de X-Account-Id informa ao plugin:
  • Qual conta usar nas operações de ledger
  • Quais dados do cliente buscar no CRM
  • Qual saldo validar e atualizar

Como o plugin usa o ID da conta

O plugin usa o ID da conta de forma diferente dependendo do tipo de operação:
Tipo de fluxoComo o plugin usa o ID da conta
Não transacional (por exemplo, criação de chaves ou QR Codes)Busca os dados do cliente e da conta bancária no CRM
Transacional (por exemplo, pagamentos, devoluções)Busca os dados do cliente para iniciar o pagamento
Valida os dados da conta para autorização de pagamento recebido
Executa a transação no ledger

Conformidade da conta


O plugin não impõe restrições de conta em nível de negócio, como contas bloqueadas ou suspensas. Sua aplicação é responsável por validar o status da conta antes de chamar o plugin. Para impedir liquidações Pix em uma conta específica, bloqueie-a diretamente no Midaz. O plugin recebe uma rejeição ao tentar registrar a transação. Documentação relacionada:

4. CRM


O CRM armazena as informações do cliente (titular) e suas contas bancárias associadas. Toda conta do Midaz deve ter um titular e uma conta alias correspondentes no CRM para realizar operações Pix. O plugin consulta os dados do CRM para:
  • Registrar e validar chaves Pix
  • Montar as mensagens de pagamento para o BACEN
  • Autorizar transações recebidas
  • Processar fluxos de devolução e disputa

Conexão


# CRM base URL
PLUGIN_CRM_BASE_URL=

# CRM API credentials (required if CRM has authentication enabled)
PLUGIN_CRM_CLIENT_ID=
PLUGIN_CRM_CLIENT_SECRET=

Titulares


Os dados do titular representam o cliente que é dono da conta. Crie cada titular no CRM antes de executar qualquer operação Pix para esse cliente.

Campos obrigatórios

CampoRequisitoExemplo
nameNo máximo 120 caracteresMaria Silva Santos
documentPara NATURAL_PERSON, um CPF com 11 dígitos; para LEGAL_PERSON, um CNPJ com 14 dígitos (apenas números)12345678900
typeTipo de pessoa (valores enum do CRM)NATURAL_PERSON

Campos opcionais

CampoQuando usar
legalPerson.tradeNameAo associar um nome fantasia aos dados da chave
addresses.primaryObrigatório para a criação de cobrança com vencimento
Documentação relacionada: Create a Holder

Contas alias


As contas alias vinculam uma conta do Midaz aos seus dados bancários. Cada conta alias deve incluir as informações bancárias que o ecossistema Pix exige para o processamento de transações.

Campos obrigatórios

CampoRequisitoExemplo
accountIdID da conta no Midaz (UUID)3c90c3cc-0d44-4b50-8888-8dd25736052a
bankingDetails.branchExatamente 4 dígitos0001
bankingDetails.accountDe 1 a 20 dígitos123456789
bankingDetails.typeTipo de conta (veja a tabela abaixo)CACC
bankingDetails.openingDateFormato YYYY-MM-DD2024-01-15
O campo bankingDetails.branch deve conter exatamente 4 dígitos. Complete com zeros à esquerda se necessário. Por exemplo, se o número da agência for 1, registre-o como 0001. O plugin só consegue validar a conta no CRM quando o código da agência segue esse formato.

Tipos de conta suportados

CódigoDescrição
CACCConta corrente
SLRYConta salário
SVGSConta poupança
TRANConta de pagamento
Documentação relacionada: Create an Alias Account

5. Provedor BTG


O BTG é o participante direto que conecta sua instituição à infraestrutura Pix do BACEN. O BTG fornece as credenciais diretamente quando sua instituição se cadastra na integração indireta com o BACEN.

Conexão


# BTG API base URL
BTG_BASE_URL=

# BTG API credentials
BTG_CLIENT_ID=
BTG_CLIENT_SECRET=

mTLS (segurança de webhook)


O TLS mútuo (mTLS) adiciona uma camada extra de segurança ao validar o certificado do BTG nas requisições de webhook. Isso garante que os webhooks recebidos realmente se originam do BTG.
# Enable mTLS validation (true/false)
# Use 'true' in production, 'false' for local development
MTLS_ENABLED=false

# How long to cache the certificate before refreshing
# Format: Go duration (e.g., 24h, 12h, 1h)
MTLS_CERTIFICATE_TTL=24h

# BTG endpoint that provides the public certificate for signature validation
BTG_CERTIFICATE_URL=

# Timeout for certificate fetch requests
# Format: Go duration (e.g., 10s, 30s)
MTLS_HTTP_TIMEOUT=10s
Sempre habilite o mTLS em ambientes de produção. Desabilite-o apenas durante o desenvolvimento local.

6. Serviço de Fee (opcional)


Habilite o cálculo de taxas para cobrar e distribuir automaticamente as taxas sobre pagamentos recebidos. Isso é opcional — se você não configurar, o plugin processa as transações sem cálculo de taxas.

Conexão


# Fee calculation method (currently only 'segment' is supported)
CASHIN_FEE_CALCULATION_TYPE=

# Fee service URL
FEE_SERVICE_URL=

# Request timeout in milliseconds
FEE_SERVICE_TIMEOUT=5000

# Fee service API credentials (required if the fee service has authentication enabled)
FEE_CLIENT_ID=
FEE_CLIENT_SECRET=

Como funciona


Quando você define CASHIN_FEE_CALCULATION_TYPE=segment, o plugin:
  1. Recupera o segmento associado à conta recebedora
  2. Calcula as taxas aplicáveis antes de processar a transação no Midaz
  3. Distribui o pagamento recebido de acordo com as regras de pacote vinculadas a esse segmento

Passos de configuração


  1. Crie segmentos no Midaz — Defina os segmentos de conta que determinam as regras de taxa
  2. Configure pacotes no Fee Engine — Vincule cada segmento às suas regras de cálculo de taxa
  3. Atribua segmentos às contas — Crie ou atualize contas do Midaz com o ID de segmento apropriado
Documentação relacionada:

7. Conciliação DICT (VSync)


O VSync concilia seus dados DICT locais com o BACEN processando todos os eventos relacionados a chaves do dia. Isso garante que seu estado local permaneça consistente com os registros oficiais do BACEN.
# Write block window (24-hour format, UTC)
ENTRY_WRITE_BLOCK_START=23:30
ENTRY_WRITE_BLOCK_END=23:35

# Allowed network range for reconciliation services
RECONCILIATION_INTERNAL_CIDR=
Durante a conciliação, o banco de dados bloqueia temporariamente as operações de escrita para evitar inconsistências de dados com o BACEN. Planeje a janela de bloqueio de escrita para períodos de baixo tráfego.
O intervalo CIDR restringe quais redes podem disparar a conciliação. O plugin rejeita automaticamente as requisições de fora desse intervalo.

Configuração de cache Redis


O VSync usa o Redis para armazenar em cache as entradas BTG/DICT e os titulares do CRM durante a conciliação. Em implantações via Helm, o REDIS_HOST padrão aponta para o sidecar Valkey embutido, portanto nenhuma configuração extra é necessária para uma instalação padrão.
# Connection (always used)
REDIS_HOST=<release>-valkey:6379
REDIS_MASTER_NAME=
REDIS_DB=0
REDIS_PROTOCOL=3

# Connection pool and retries (always used)
REDIS_POOL_SIZE=10
REDIS_MIN_IDLE_CONNS=0
REDIS_READ_TIMEOUT=3
REDIS_WRITE_TIMEOUT=3
REDIS_DIAL_TIMEOUT=5
REDIS_POOL_TIMEOUT=2
REDIS_MAX_RETRIES=3
REDIS_MIN_RETRY_BACKOFF=8
REDIS_MAX_RETRY_BACKOFF=512

# Authentication (optional — only used if set)
REDIS_PASSWORD=

# TLS (optional — only used if REDIS_TLS=true)
REDIS_TLS=false
REDIS_CA_CERT=

# GCP IAM authentication (optional — only used if REDIS_USE_GCP_IAM=true)
REDIS_USE_GCP_IAM=false
REDIS_SERVICE_ACCOUNT=
GOOGLE_APPLICATION_CREDENTIALS=
REDIS_TOKEN_LIFETIME=60
REDIS_TOKEN_REFRESH_DURATION=45

# VSync cache TTLs (always used)
CACHE_BTG_ENTRY_TTL=30m
CACHE_CRM_HOLDER_TTL=30m
Em implantações via Helm, o REDIS_HOST padrão aponta para o sidecar Valkey embutido (<release-name>-valkey:6379) — nenhuma configuração de Redis adicional é necessária, a menos que você se conecte a uma instância externa.

Conexão (sempre usada)

VarTipoPadrãoDescrição
REDIS_HOSTstring (host:port, CSV)<release>-valkey:6379 (Helm chart)Endereço(s) do Redis. O padrão aponta para o Valkey embutido (<release-name>-valkey:6379). Múltiplos endereços separados por vírgula definem a topologia Sentinel/Cluster.
REDIS_MASTER_NAMEstring""Nome do master do Sentinel. Vazio = standalone (conexão direta).
REDIS_DBint0Número do banco de dados lógico do Redis.
REDIS_PROTOCOLint3Versão do protocolo RESP (2 ou 3).

Pool de conexões e retentativas (sempre usado)

VarTipoPadrãoDescrição
REDIS_POOL_SIZEint10Máximo de conexões no pool.
REDIS_MIN_IDLE_CONNSint0Mínimo de conexões ociosas mantidas prontas.
REDIS_READ_TIMEOUTint (segundos)3Timeout da operação de leitura.
REDIS_WRITE_TIMEOUTint (segundos)3Timeout da operação de escrita.
REDIS_DIAL_TIMEOUTint (segundos)5Timeout para estabelecer a conexão inicial.
REDIS_POOL_TIMEOUTint (segundos)2Timeout aguardando uma conexão livre do pool.
REDIS_MAX_RETRIESint3Máximo de retentativas para um comando que falhou.
REDIS_MIN_RETRY_BACKOFFint (milissegundos)8Atraso mínimo entre retentativas.
REDIS_MAX_RETRY_BACKOFFint (segundos)512Atraso máximo entre retentativas. Observação: armazenado em segundos no código (unidade diferente da mínima).

Autenticação (opcional — usada apenas se definida)

VarTipoPadrãoDescrição
REDIS_PASSWORDstring (secret)""Senha do Redis. Vazio = sem autenticação por senha.

TLS (opcional — usado apenas se REDIS_TLS=true)

VarTipoPadrãoDescrição
REDIS_TLSboolfalseHabilita o TLS. Obrigatoriamente true em DEPLOYMENT_MODE=saas (validado na inicialização).
REDIS_CA_CERTstring (PEM base64)""Certificado CA (base64) para validar o servidor quando o TLS estiver ativo.

Autenticação GCP IAM (opcional — usada apenas se REDIS_USE_GCP_IAM=true)

VarTipoPadrãoDescrição
REDIS_USE_GCP_IAMboolfalseHabilita a autenticação GCP IAM (Memorystore) em vez de senha.
REDIS_SERVICE_ACCOUNTstring""Conta de serviço do GCP que gera o token de acesso.
GOOGLE_APPLICATION_CREDENTIALSstring""Caminho das credenciais do GCP (lido via CredentialsBase64FromEnvValue) para gerar o token.
REDIS_TOKEN_LIFETIMEint (minutos)60Tempo de vida do token IAM gerado.
REDIS_TOKEN_REFRESH_DURATIONint (minutos)45Intervalo de renovação do token (deve ser menor que o tempo de vida).

TTLs de cache do VSync (sempre usados)

VarTipoPadrãoDescrição
CACHE_BTG_ENTRY_TTLGo duration30mTTL do cache para entradas BTG/DICT no Redis. Valor negativo reverte para o padrão.
CACHE_CRM_HOLDER_TTLGo duration30mTTL do cache para titulares do CRM no Redis. Valor negativo reverte para o padrão.

8. Segurança de webhook interno


O plugin usa um canal de comunicação interno entre os serviços Worker e Aplicação. Assinaturas HMAC-SHA256 protegem esse canal para evitar adulteração e ataques de replay.
# Shared secret for signing internal requests (Worker -> Application)
# Must be at least 32 characters
# Generate one with: openssl rand -base64 32
INTERNAL_WEBHOOK_SECRET=

# Validate signatures on incoming internal webhooks (true/false)
# Always use 'true' in production
INTERNAL_WEBHOOK_VALIDATION_ENABLED=true

# Maximum age (in seconds) for request timestamps before rejection
# Default: 300 (5 minutes)
INTERNAL_WEBHOOK_TIMESTAMP_TOLERANCE=300
Use exatamente o mesmo valor de INTERNAL_WEBHOOK_SECRET nos serviços Aplicação e Worker. Uma divergência faz com que o plugin rejeite todos os webhooks internos.

9. Camadas de worker


O plugin opera com três camadas de worker, cada uma tratando de uma parte diferente do ciclo de vida do Pix. Todos os workers são executados como serviços separados ao lado da aplicação principal.

Worker de entrada


O worker de entrada recebe notificações de webhook do BTG e as encaminha para a sua aplicação para processamento.
# URL where the application receives internal webhooks
WEBHOOK_INBOUND_BASE_URL=

# Shared secret for signing requests (must match the application's INTERNAL_WEBHOOK_SECRET)
INTERNAL_WEBHOOK_SECRET=

Worker de saída


O worker de saída envia notificações de eventos do plugin para a sua aplicação via webhooks. É assim que o seu sistema se mantém informado sobre eventos Pix (transferências, devoluções, reivindicações, disputas).

Prioridade de resolução de URL

O plugin resolve as URLs de webhook nesta ordem, usando a primeira correspondência:
  1. URL de entidade — Uma URL específica para o tipo de evento (por exemplo, WEBHOOK_DICT_CLAIM_URL)
  2. URL de fluxo — Uma URL para a categoria mais ampla (por exemplo, WEBHOOK_DICT_URL)
  3. URL padrão — A URL de fallback (WEBHOOK_DEFAULT_URL)
# Default fallback URL
WEBHOOK_DEFAULT_URL=

# DICT-related events
WEBHOOK_DICT_URL=
WEBHOOK_DICT_CLAIM_URL=
WEBHOOK_DICT_INFRACTION_REPORT_URL=
WEBHOOK_DICT_REFUND_URL=

# MED 2.0 Funds Recovery events (DICT flow)
# These route under the DICT flow and fall back to WEBHOOK_DICT_URL,
# then WEBHOOK_DEFAULT_URL, if no entity-specific URL is set.
WEBHOOK_DICT_FUNDS_RECOVERY_URL=
WEBHOOK_DICT_FUNDS_RECOVERY_EVENT_URL=

# Refund events
WEBHOOK_REFUND_CASHIN_URL=
WEBHOOK_REFUND_CASHOUT_URL=

# Transfer events
WEBHOOK_TRANSFER_CASHIN_URL=
WEBHOOK_TRANSFER_CASHOUT_URL=
Você pode começar apenas com WEBHOOK_DEFAULT_URL para receber todos os eventos em um único endpoint e, em seguida, dividir gradualmente em URLs específicas por entidade conforme o seu sistema evolui.
Para um aprofundamento sobre tipos de evento de webhook, payloads, comportamento de retentativa e boas práticas, consulte o guia de Webhooks.

Worker de conciliação


O worker de conciliação precisa das mesmas credenciais da camada Aplicação para estes serviços:
  • CRM — URL e credenciais
  • BTG — URL e credenciais
  • Midaz — ID da organização
Consulte as seções correspondentes acima para detalhes sobre cada configuração. Você pode restringir quando o worker opera configurando uma janela de tempo específica. Isso é especialmente útil para agendar as tarefas de conciliação em horários de baixo movimento. O plugin suporta janelas de tempo que cruzam a meia-noite.
# Start time in HH:MM format (24-hour). Example: "23:00" for 11 PM
RECONCILIATION_START_TIME=

# End time in HH:MM format (24-hour). Example: "05:00" for 5 AM
RECONCILIATION_END_TIME=
Se você deixar os dois campos vazios, o worker é executado sem restrições de horário — 24/7.
A janela operacional de conciliação é ancorada ao fuso horário America/Sao_Paulo. Em imagens de contêiner mínimas/distroless que não trazem os dados de fuso horário, o runtime recorre ao UTC e a janela configurada pode desviar em até 3 horas em relação ao bloqueio de escrita do DICT. Defina TZ=America/Sao_Paulo (e garanta que o tzdata esteja disponível) no contêiner do worker de conciliação para manter a janela alinhada com o BACEN.
Os endpoints de cashout e devolução do Pix Indireto suportam idempotência através do cabeçalho de requisição X-Idempotency, com TTL configurável via X-TTL. Para estratégias de retentativa e detalhes de implementação, consulte Retentativas e idempotência.

10. Observabilidade (OpenTelemetry)


O plugin vem com instrumentação completa do OpenTelemetry (traces, métricas e logs) nas camadas Aplicação e Worker. Todo fluxo Pix é rastreado de ponta a ponta — transferências (cash-in e cash-out), devoluções, webhooks de entrada e saída, conciliação DICT e liquidação intra-PSP — para que você possa acompanhar um único pagamento ao longo das chamadas ao plugin, Midaz, CRM e BTG. A telemetria fica desabilitada por padrão. Habilite-a e aponte o exportador OTLP para o seu collector:
# Master switch — telemetry is off until this is true
ENABLE_TELEMETRY=true

# Resource attributes that identify this service in your backend
OTEL_RESOURCE_SERVICE_NAME=plugin-br-pix-indirect-btg
OTEL_LIBRARY_NAME=github.com/LerianStudio/plugin-br-pix-indirect-btg
OTEL_RESOURCE_SERVICE_VERSION=${VERSION}
OTEL_RESOURCE_DEPLOYMENT_ENVIRONMENT=${ENV_NAME}

# OTLP collector endpoint (gRPC, default port 4317)
OTEL_EXPORTER_OTLP_ENDPOINT_PORT=4317
OTEL_EXPORTER_OTLP_ENDPOINT=otel-collector:${OTEL_EXPORTER_OTLP_ENDPOINT_PORT}
Quando ENABLE_TELEMETRY=true, OTEL_EXPORTER_OTLP_ENDPOINT é obrigatório. Defina as mesmas variáveis OTel na Aplicação e em cada Worker para que os traces se correlacionem entre os serviços.

Exportador: gRPC e TLS


O plugin exporta traces, métricas e logs via OTLP/gRPC. O esquema do endpoint controla a segurança do transporte:
Valor do endpointTransporteSegurança
https://collector:4317gRPC sobre TLSSeguro (recomendado para produção)
http://collector:4317gRPC, texto planoInseguro — inferido automaticamente
collector:4317 (apenas host:port)gRPC, texto planoInseguro — inferido automaticamente
Exportadores inseguros (texto plano) são rejeitados fora de ambientes de desenvolvimento. Em staging ou produção, use um endpoint https://, ou reconheça explicitamente o risco por meio da permissão de OTEL inseguro da lib-commons somente quando você controlar totalmente o caminho de rede até o collector.

Exemplo: endpoint do collector


Aponte o plugin para qualquer collector compatível com OTLP (o OpenTelemetry Collector, Grafana LGTM/Alloy, etc.) escutando na porta gRPC:
# Local / development (plaintext gRPC)
ENABLE_TELEMETRY=true
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317

# Production (TLS gRPC)
ENABLE_TELEMETRY=true
OTEL_EXPORTER_OTLP_ENDPOINT=https://otel-collector.example.com:4317
O collector então distribui a telemetria para os seus backends de tracing, métricas e logging.

11. Saúde e prontidão


A Aplicação e os Workers expõem uma sonda de prontidão em /readyz (junto com as verificações de liveness padrão). Aponte a sonda de prontidão do seu orquestrador para esse endpoint para que o tráfego só seja roteado quando o serviço e suas dependências estiverem prontos.

Finalidade da transferência (MED 2.0)


O endpoint de cashout aceita um cabeçalho opcional X-Purpose que identifica a finalidade da transação, usado em transferências de devolução do MED 2.0. Quando omitido, o padrão é TRANSFER.
# Example: a MED 2.0 refund transfer
POST /v1/transfers/cashout/process
X-Purpose: INSTANT_PAYMENT_REFUND
Os valores suportados são TRANSFER e INSTANT_PAYMENT_REFUND. Consulte MED 2.0 — Recuperação de Fundos para detalhes.

Próximos passos


Com o plugin totalmente configurado, você está pronto para começar a operar o Pix. Explore estes tópicos para se aprofundar: