Roteamento
Fluxos de roteamento
Como o construtor visual decide por qual adquirente cada transação passa, e como testar antes de publicar.
Guia de integração · 19 min de leitura
Nesta página
Um fluxo decide o caminho de cada transacao: qual adquirente tenta primeiro, quando passar por antifraude, quando dividir o valor e o que fazer na recusa.
Fluxos sao desenhados no painel, arrastando etapas. Esta pagina explica o modelo por tras do desenho - util para quem vai montar o fluxo e essencial para quem vai criar fluxos por API.
O modelo
Um fluxo e um grafo aciclico de nos ligados por arestas. Cada no tem portas de saida nomeadas, e cada porta leva a uma proxima etapa.
Gatilho ──▶ Faixa de ticket ──alto──▶ Antifraude ──aprovar──▶ Adquirente Y ──▶ Aprovar
│ │
│ recusar ──────────────────────────────▶ Recusar
└──demais──▶ Adquirente X ──aprovado──▶ Aprovar
Por que aciclico: um ciclo no caminho de autorizacao poderia girar indefinidamente enquanto o comprador espera. Para repetir uma cobranca em outra data existe o no de Retentativa, que agenda em vez de voltar no grafo.
Tipos de no
| Grupo | No | O que faz | Portas |
|---|---|---|---|
| Inicio | Gatilho | Evento que inicia o fluxo | next |
| Logica | Condicao | Divide em verdadeiro ou falso | true, false |
| Logica | Multiplos caminhos | Avalia casos em ordem | ids dos casos, default |
| Logica | Definir variavel | Guarda um valor para as proximas etapas | next |
| Risco | Antifraude | Consulta o provedor e ramifica | approve, review, decline, error |
| Risco | Validacao de cartao | Confere o cartao sem cobrar (Zero Auth) | valid, invalid, unavailable, error |
| Risco | Autenticacao 3DS | Autentica o portador ou envia Data Only | authenticated, not_authenticated, unavailable |
| Risco | Revisao manual | Pausa ate a decisao de um analista | approved, declined |
| Processamento | Rotear | Escolhe o conector (cartao nao troca) | approved, declined, error |
| Processamento | Capturar | Captura o valor autorizado | captured, failed |
| Processamento | Split | Divide entre recebedores (a rota executa) | next |
| Cobranca | Retentativa | Reagenda conforme a politica | scheduled, exhausted |
| Cobranca | Aguardar | Pausa e retoma depois do prazo | next |
| Integracao | Webhook | Emite flow.notification | next |
| Fim | Aprovar / Recusar | Encerra o fluxo | nenhuma |
Cada porta aceita uma ligacao. Duas setas saindo de "Aprovado" tornariam o
fluxo ambiguo, e o motor nao teria como escolher. E toda porta precisa de
destino, inclusive error: uma porta solta nao e "nada acontece", e o
pagamento terminaria sem decisao explicita.
No painel, um duplo clique na etapa abre a configuracao no painel lateral. As etapas que dependem de parceiro (antifraude, rota, validacao de cartao, 3DS) escolhem o provedor e a conta ali mesmo, com cadastro de chaves e Testar conexao - ver Conectores.
Antifraude: score ou recomendacao
O score de todo provedor e normalizado para 0 a 100 (100 = risco maximo),
para que trocar Konduto por ClearSale nao exija recalibrar o fluxo. O no decide
de um de dois jeitos (decisionMode):
| Modo | Quem decide | Configuracao |
|---|---|---|
score | As faixas do no: aprovar abaixo de X, recusar a partir de Y | approveBelow, declineAbove |
recommendation | A recomendacao do provedor (aprovar/revisar/recusar) | - |
Quando o provedor decide sem devolver score (a ClearSale decide por
status), vale a recomendacao dele nos dois modos - o Minstrel nunca inventa um
numero. Timeout (timeoutMs) ou provedor fora do ar saem pela porta error;
ligue-a a uma revisao manual para nao perder a venda.
Antifraude da adquirente no no Rotear
Alem do no Antifraude, que o Minstrel chama antes de autorizar, algumas
adquirentes analisam a fraude dentro da propria autorizacao. Hoje e o caso da
Cielo, quando a conta tem o recurso Antifraude da Cielo ligado (veja
Antifraude da Cielo). O no Rotear
decide, rota a rota, se essa analise roda, pela opcao Antifraude da
adquirente (acquirerFraudAnalysis):
Opcao (acquirerFraudAnalysis) | O que faz |
|---|---|
Seguir a conta (account) | Padrao. Analisa quando a conta que vai autorizar tem a analise ligada. |
Nao analisar (skip) | Nao analisa nesta rota, mesmo que a conta tenha a analise ligada. |
Ausente, vale account: fluxos ja publicados e os modelos prontos continuam
iguais. A opcao nao liga a analise numa conta que nao tem o recurso, porque isso
depende de contrato com a adquirente. E por candidata: num no com duas contas
Cielo, so a que tem a analise ligada a envia.
Quando usar skip:
- pedido de valor baixo, em que a tarifa por analise pesa mais que o risco:
separe-o com uma Condicao em
payment.amounte ligue-o a um Rotear comskip; - cliente confiavel, que voce ja conhece (
customer.groups,customer.tags); - um no Antifraude ja decidiu antes: analisar de novo seria pagar duas vezes pelo mesmo veredito.
A analise do adquirente so existe em cartao de credito iniciado pelo portador:
debito, Pix, boleto e cobranca do lojista (assinatura) nunca a enviam, com ou
sem skip. Para o que acontece com a venda depois, veja
Transacoes. O resultado
(origin: "acquirer") aparece no detalhe do pagamento ao lado das analises do
no Antifraude (origin: "flow_node").
Captura e revisao. Um pagamento em revisao de fraude fica authorized, e o
no Capturar espera o veredito nos dois modos:
capturar antes cobraria uma venda que o provedor ainda pode recusar. Em
immediate, o no segue pela porta captured com a captura adiada (a saida do
passo traz deferred: true): com captura manual ela entra na fila de capturas
agendadas e roda depois do aceite; com captura automatica o Minstrel ja captura
no aceite. Em delayed, o agendamento so roda depois do aceite. Na recusa, a
autorizacao e cancelada e nada e capturado. Para capturar antes do provedor
decidir, use POST /v1/payments/{id}/capture: a revisao fecha como
merchant_decided.
Validacao de cartao (Zero Auth)
O no Validacao de cartao (zero_auth) usa a autorizacao de valor zero
(Zero Auth) para conferir se o cartao esta ativo. Nao cobra, nao reserva
limite e nao avisa o portador. Serve para barrar um cartao morto antes de
gastar uma tentativa de venda, por exemplo na primeira cobranca de uma
assinatura.
| Porta | Quando sai por ela | Sugestao |
|---|---|---|
valid | Valido: o emissor confirmou que o cartao esta ativo. | Seguir para a rota. |
invalid | Invalido: o emissor disse que o cartao nao serve. | Recusar. Nao envie ao emissor. |
unavailable | Indisponivel: bandeira sem suporte, recurso desligado na conta ou token de outra conta. | Seguir sem validar, se o seu risco permitir. |
error | Falha tecnica (timeout, parceiro fora do ar). | Seguir sem validar ou desviar para uma revisao manual. |
Separar invalid de unavailable e a razao de o no existir: so o primeiro
justifica recusar a venda. unavailable nao diz nada sobre o cartao, e um
servico fora do ar ou nao habilitado na conta nunca deve virar "cartao ruim".
Enviar ao emissor um cartao invalid so geraria outra recusa, que ainda conta
nos programas de retentativa das bandeiras.
| Campo | Padrao | Efeito |
|---|---|---|
Conta (connectorAccountId) | A conta onde o cartao foi salvo | Opcional. O token da Cielo so vale na conta que o criou, entao deixar em branco e quase sempre o certo. Outra conta, que nao e a do cartao, sai por unavailable. |
reuseWithinDays | 30 (de 0 a 365) | Reaproveita uma validacao valid recente do mesmo cartao, sem consultar de novo. 0 valida sempre. |
O reaproveitamento existe porque o Zero Auth conta nos programas de
retentativa das bandeiras e pode ter custo no adquirente: validar o mesmo
cartao a cada pagamento seria pagar, e arriscar tarifa, por uma resposta que
ja se tem. So uma validacao valid e reaproveitada.
No editor, so aparecem as contas com a validacao de cartao ligada
(Plugins, conta, Recursos - ver
Conectores). Quando a validacao e
aprovada num cartao salvo, ela abre a cadeia da rede (IssuerTransactionId e,
na Mastercard, o TLID) como se fosse uma primeira transacao: as cobrancas sem o
cliente que vierem depois partem dela.
Exemplo: validar so a primeira compra do cliente.
Gatilho ──▶ Condicao: customer.is_first_purchase = true
│
├── true ──▶ Validacao de cartao ──valid──▶ Rotear ──approved──▶ Aprovar
│ │
│ └── invalid ──▶ Recusar
└── false ──▶ Rotear
As portas unavailable e error tambem precisam de destino, como qualquer
porta: no exemplo acima, ligue-as a um segundo Rotear para seguir sem validar.
O resultado fica disponivel para as regras seguintes em card.verification_status
e card.verified_days_ago (veja
Campos disponiveis nas regras). Para validar o
cartao na hora de salva-lo, sem fluxo, use o parametro verify descrito em
Clientes e grupos.
Autenticacao 3DS e Data Only
O no Autenticacao 3DS (three_ds) autentica o portador com o emissor do
cartao antes da autorizacao, ou, no Data Only, envia so os dados da compra.
Autenticado, a responsabilidade por fraude da venda passa ao emissor
(liability shift). O passo a passo no navegador esta em
Checkout transparente.
Modo (mode) | O que faz | Responsabilidade por fraude |
|---|---|---|
frictionless_preferred | Padrao. Pede ao emissor para nao desafiar o portador, sem garantia: se ele achar necessario, abre a janela de desafio. | Passa ao emissor quando o portador e autenticado. |
challenge_required | Exige o desafio ao portador. Mais seguro, converte menos. | Passa ao emissor quando o portador e autenticado. |
data_only | Visa e Mastercard. Envia os dados ao emissor sem autenticar o portador. Ajuda na aprovacao e conta na monitoria da Mastercard, que reporta lojas com menos de 10% das transacoes com 3DS ou Data Only. | Nao passa (ECI 04 na Mastercard, 07 na Visa). |
| Porta | Quando sai por ela | Sugestao |
|---|---|---|
authenticated | O portador foi autenticado ou, no modo data_only, o Data Only foi concluido. A autorizacao segue com a autenticacao (CAVV, ECI, versao). | Seguir para a rota. |
not_authenticated | O emissor negou a autenticacao ou o portador nao concluiu o desafio. Tambem e a porta da indisponibilidade quando onUnavailable e decline. | Recusar, ou tentar outro caminho. |
unavailable | O 3DS nao pode rodar (regras abaixo) e onUnavailable e continue, o padrao. | Seguir sem autenticar, se o seu risco permitir. |
| Campo | Padrao | Efeito |
|---|---|---|
mode | frictionless_preferred | Um dos tres modos acima. |
onUnavailable | continue | continue segue pela porta unavailable; decline sai por not_authenticated. |
Conta (connectorAccountId) | - | Opcional. Sem conta propria, vale o 3DS do adquirente quando houver. No editor, so aparecem as contas com o recurso 3DS e Data Only ligado. |
Quando o 3DS roda. Ele precisa do portador na pagina, entao so existe no
checkout transparente, com o pagamento
confirmado no navegador pelo SDK. Fora disso o no nao autentica e segue a regra
de onUnavailable:
- cobranca do lojista (MIT), como as de assinatura, que acontecem sem o cliente;
- confirmacao pelo servidor (
POST /v1/payments/:id/confirm); - bandeira fora de Visa, Mastercard, Elo e Amex (o Data Only vale so para Visa e Mastercard);
- conta sem o recurso 3DS e Data Only ligado ou sem as credenciais do 3DS (veja Conectores).
O fluxo pausa no no. Como na revisao manual, a resposta da API volta na
hora: o pagamento fica requires_action, com nextAction.type = "three_ds". O
SDK roda o script de 3DS da Cielo na pagina do lojista (o emissor pode abrir
uma janela de desafio) e informa o resultado em
POST /v1/public/payments/:id/three-ds; o fluxo continua do no, pela porta
que o resultado definir. A autorizacao leva a autenticacao: CAVV, ECI e
versao. O Minstrel nao grava o CAVV nem o XID.
Debito exige 3DS. A Cielo so autoriza debito com o portador autenticado.
Todo fluxo que roteia debit_card precisa do no de 3DS antes do no
Rotear; sem ele, a rota falha com "Debito exige autenticacao 3DS". O modo
data_only nao serve ao debito, porque nao autentica o portador. Para que um
3DS indisponivel nao chegue a rota de debito, ligue not_authenticated e
unavailable a um Recusar.
Exemplo: 3DS so no debito, e credito direto para a rota.
Gatilho --> Condicao: payment.method_type = debit_card
|
|-- true --> Autenticacao 3DS --authenticated--> Rotear --approved--> Aprovar
| |
| |-- not_authenticated --> Recusar
| '-- unavailable -------> Recusar
'-- false --> Rotear
Cada porta precisa de destino, como em qualquer no. O resultado fica no
detalhe do pagamento, em threeDs (veja
Transacoes).
Captura imediata ou adiada
O no Capturar tem dois modos. Em immediate (padrao), captura assim que a
autorizacao e aprovada. Em delayed, agenda a captura para delayHours horas
depois (captureScheduledAt) e quem a executa e o worker, nao o fluxo: o
pagamento fica authorized ate la.
A bandeira limita quanto tempo uma pre-autorizacao pode esperar, e o agendamento
respeita isso: se delayHours passar do prazo, a captura e marcada para 1 hora
antes do vencimento (authorizationExpiresAt), nunca depois. Veja os prazos e
o aviso de vencimento em
Transacoes.
Pagamento em revisao de fraude do adquirente espera o veredito: a captura adiada so roda depois do aceite. Veja Antifraude da adquirente no no Rotear.
Pausas: Aguardar e Revisao manual
Essas etapas nunca seguram a autorizacao. A execucao pausa, o pagamento
fica requires_action e a resposta da API volta na hora. Depois:
- Aguardar retoma sozinho pela porta
nextquando o prazo vence; - Revisao manual retoma pela decisao de um analista ou, se ninguem decidir
no prazo (
slaHours), pela decisao automaticaonSlaBreach.
O no de 3DS tambem pausa o fluxo, mas quem o retoma e o navegador do portador, com o resultado da autenticacao.
A decisao e uma chamada idempotente:
curl -X POST http://localhost:3333/v1/payments/pay_.../review \
-H "Authorization: Bearer $MINSTREL_API_KEY" \
-H "Idempotency-Key: revisao-pay_..." \
-H "Content-Type: application/json" \
-d '{ "decision": "approve", "note": "Cliente confirmou por telefone." }'
O fluxo continua de onde parou - aprovar pode disparar a autorizacao no
adquirente - e a resposta traz o pagamento ja com o status final. Se a revisao
ja foi decidida (por outra pessoa ou pelo prazo), a API responde 409.
Notificar o seu sistema
O no Notificar webhook emite o evento flow.notification ao fim da
execucao, com o nome escolhido no no em data.name. Assine esse evento uma vez
e use o nome para saber em que ponto do fluxo o pagamento passou:
{
"type": "flow.notification",
"data": {
"name": "antifraude_em_revisao",
"paymentId": "pay_...",
"flowId": "flw_...",
"flowRunId": "frun_..."
}
}
Campos disponiveis nas regras
As condicoes comparam campos de um catalogo fechado:
| Campo | Exemplo de uso |
|---|---|
payment.amount | Valor em centavos. > 10000 e acima de R$ 100,00 |
payment.installments | Numero de parcelas |
payment.initiator | customer (cliente presente) ou merchant (automatica) |
payment.method_type | card, debit_card, pix, boleto, wallet ou bank_transfer; por exemplo, 3DS so no debit_card |
card.brand | visa, mastercard, elo, amex, hiper |
card.bin | Primeiros digitos, para regra por emissor |
card.funding | credit, debit, prepaid |
card.country | Pais emissor, para regra de cartao estrangeiro |
card.verification_status | Resultado da validacao de cartao: valid, invalid ou unavailable. Vazio se o cartao nunca foi validado |
card.verified_days_ago | Dias desde a ultima validacao do cartao. Vazio se nunca foi validado; > 30 pega validacao antiga |
customer.tags | Etiquetas do cliente |
customer.groups | Grupos do cliente (ids cgr_...); o editor mostra os nomes |
customer.is_first_purchase | Primeira compra |
risk.score | Score do antifraude (0 a 100) |
attempt.number | Numero da tentativa |
attempt.previous_decline_reason | Motivo da recusa anterior |
subscription.is_recurring | E cobranca de assinatura |
metadata.<chave> | Qualquer metadado que voce enviou |
O catalogo e fechado de proposito. Expressao livre tornaria o fluxo impossivel de validar antes de publicar - e um fluxo invalido em producao decide o roteamento de dinheiro real.
Nao existe operador de expressao regular, tambem por decisao: regex fornecida
pelo usuario, avaliada no caminho critico de autorizacao, e vetor de ataque de
negacao de servico. contains, starts_with e ends_with cobrem os casos
reais.
Split e a rota que o executa
O no Split calcula e grava a divisao do pagamento entre recebedores (veja Split de pagamento); quem a executa e o adquirente da rota que vem depois. Por isso o Split vem antes da rota, e a rota precisa levar a uma conta que execute o split:
- a conta tem o recurso Split de pagamento ligado (na Cielo,
splitEnabled; o Sandbox executa sempre); - todos os recebedores do Split estao registrados nessa conta
(
connectorAccountIdeexternalRecipientId).
O Rotear pula as candidatas que nao cumprem as duas e registra no passo o que
falta em cada uma (skipped, com reason: "split_not_supported"). Se sobra uma
conta capaz, ela autoriza com a divisao. Se nenhuma serve, o pagamento nao e
autorizado: autorizar sem dividir liquidaria o valor inteiro para o lojista
principal. O erro split_not_supported sai pela porta error do no, e o
desfecho depende do que ela liga (Catalogo de erros).
Como cada recebedor pertence a uma conta, num pagamento dividido nao ha fallback para outra: so a conta onde os recebedores estao registrados e elegivel.
Aviso na publicacao. Se, ao publicar, nenhuma conta candidata de uma rota
a jusante de um no Split executa a divisao, a publicacao segue e devolve em
warnings um aviso invalid_node_config com severity: "warning", nodeId da
rota e field: "candidates". A mensagem lista o que falta em cada conta. E um
aviso, e nao um erro, porque o cadastro pode ser completado depois e o aviso some
sozinho; com ao menos uma conta capaz na rota, nao ha aviso.
Estrategias de roteamento
O no Rotear aceita varios conectores candidatos e quatro estrategias:
| Estrategia | Comportamento | Quando usar |
|---|---|---|
priority | Tenta na ordem definida | Tem um adquirente preferido |
weighted | Sorteia pelo peso (%) | Teste A/B ou divisao de volume (80/20) |
least_cost | Usa o custo cadastrado | Otimizar taxa |
round_robin | Alterna igualmente | Distribuir carga |
Cartao: uma adquirente por transacao
O token de um cartao e emitido por UMA adquirente - o CardToken da Cielo, o
tokenizationId da Rede - e so vale nela. Por isso, no cartao:
- o cartao salvo vai sempre para a conta onde foi salvo (
connectorAccountIdinformado no cadastro do cartao), mesmo que a estrategia do no aponte outra. Se o no de rota nao tiver essa conta, o pagamento falha comno_connector_availablee a mensagem diz qual conta incluir; - recusa ou falha nao trocam de adquirente. A nova tentativa e da politica
de retentativa (Retentativa), que respeita a ABECS e o
intervalo pedido pelo emissor, na mesma adquirente. O detalhe da transacao
mostra o motivo
card_single_acquirer.
A excecao e o token de bandeira proprio (card.isNetworkToken: true) quando
todas as contas do no aceitam token de bandeira externo: ai o fallback abaixo
vale tambem para o cartao.
Fallback
Vale para Pix e boleto, que nao dependem de token, e para cartao com token de bandeira proprio. Duas opcoes por no de roteamento:
fallbackOnConnectorFailure- tenta o proximo em timeout ou erro do provedor. Recomendado deixar ligado: a chance de pagamento segue intacta.fallbackOnReversibleDecline- tenta o proximo em recusa reversivel (so cartao com token de bandeira proprio).
Recusa irreversivel sempre interrompe o fallback, independentemente da configuracao. O emissor nunca aprovaria, portanto tentar outro adquirente seria custo garantido sem chance de aprovacao. Ver Retentativa.
No Retentativa: a politica vale de verdade
O no Retentativa escolhe como reagendar a cobranca de uma fatura recusada:
um preset (padrao-7-dias, conservadora-3-tentativas, persistente-15-dias)
ou uma politica cadastrada (retryPolicyId, que vence o preset). A politica
escolhida no no governa o numero de tentativas, os intervalos e a janela da
fatura, no lugar da politica da assinatura. Para deixar a assinatura decidir,
selecione Politica da assinatura no no (sem preset nem id).
O no nao afrouxa a ABECS nem o adquirente: recusa irreversivel nunca e retentada e o teto e o intervalo minimo do adquirente continuam valendo. O detalhe, a ordem de precedencia e o registro da decisao estao em Retentativa.
Simule antes de publicar
No editor, o botao Simular percorre o grafo com um contexto hipotetico e mostra o caminho que a transacao seguiria, com a explicacao de cada decisao. Nenhum conector e acionado e nada e gravado.
Por API:
curl -X POST http://localhost:3333/v1/flows/simulate \
-H "Authorization: Bearer $MINSTREL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"graph": { "nodes": [], "edges": [] },
"context": {
"payment.amount": 1500000,
"card.brand": "visa",
"risk.score": 20
}
}'
Resposta:
{
"outcome": "aprovado",
"path": [
{ "nodeId": "trigger", "explanation": "Gatilho: payment.authorization_requested." },
{
"nodeId": "faixas",
"handle": "alto",
"explanation": "Caso \"Acima de R$ 10.000,00\": payment.amount (1500000) maior que 1000000 => sim"
},
{
"nodeId": "antifraude",
"handle": "approve",
"explanation": "Score simulado 20 resultaria em approve."
},
{
"nodeId": "rota-alto",
"handle": "approved",
"explanation": "Rotearia para ca_adquirente_y (estrategia priority)."
}
]
}
Etapas que dependem de terceiros seguem o caminho feliz por padrao. Para ver o
outro caminho, informe o resultado suposto em assume, por tipo de no ou por
id: "assume": { "route": "declined" } responde "e se o adquirente recusar?".
Regras (condicao, multiplos caminhos) nunca sao supostas: sao elas que se quer
testar. O no de 3DS segue como autenticado; para ver o caminho de quem nao
conclui o desafio, use "assume": { "three_ds": "not_authenticated" }.
Versionamento
Publicar cria uma versao imutavel e move o ponteiro da versao ativa.
Isso permite duas coisas que importam em operacao:
- auditar por que uma transacao de tres meses atras foi roteada de certo jeito - o grafo exato daquele momento esta preservado;
- voltar atras instantaneamente, trocando o ponteiro para a versao anterior.
Cada execucao grava a trilha passo a passo em flow_run_steps, com a
explicacao de cada decisao em portugues. Quando o cliente pergunta por que a
transacao foi para o adquirente X, a resposta esta no banco.
Validacao na publicacao
Antes de uma versao entrar em vigor, verificamos:
- Schema - estrutura de cada no e de cada regra;
- Grafo - exatamente um gatilho, nenhum ciclo, nenhuma porta sem ligacao, nenhum no terminal com saida, ao menos um no de Aprovar ou Recusar;
- Referencias - toda conta de conector e todo recebedor citados existem, pertencem a sua organizacao, estao no mesmo ambiente e estao habilitados.
A terceira camada evita o erro mais silencioso: publicar um fluxo que aponta para uma conta desabilitada recusaria transacoes reais sem nenhuma pista.
Alem dos erros, a publicacao devolve avisos (warnings), que nao impedem de
publicar. Um deles cobre o split: rota depois de um no Split cujas contas
candidatas nenhuma executa a divisao (veja
Split e a rota que o executa).
Rascunhos aceitam configuracao incompleta - salvar nunca perde o trabalho em
andamento. A resposta do rascunho e de POST /v1/flows/validate lista cada
problema com o no (nodeId) e o campo (field), e o painel marca os dois.
Um fluxo em vigor por gatilho
Cada gatilho tem um fluxo em vigor por ambiente. Publicar coloca o fluxo em
vigor para o gatilho desenhado nele e tira o anterior - a resposta informa
quais sairam em replacedFlows. Para voltar ao fluxo antigo, publique-o de
novo.
A cobranca de fatura da recorrencia usa o fluxo do gatilho
invoice.payment_due; sem ele publicado, usa o de
payment.authorization_requested. Quem so desenhou o roteamento cobra a
recorrencia pelo mesmo caminho; quem quer tratar fatura de outro jeito (outro
adquirente, outra regra) publica um fluxo proprio para ela. Nos dois casos o
contexto traz subscription.is_recurring verdadeiro.