Contrato de transporte
| Campo | Valor |
|---|---|
ce-source | plugin-br-bank-transfer |
| Tópico | lerian.streaming.plugin-br-bank-transfer |
ce-type | studio.lerian.plugin-br-bank-transfer.<event-key> |
| Versão do schema | Por evento, no catálogo abaixo |
| Content type | application/json |
ce-subject | O id da transferência. payment_initiation.created leva o id da iniciação, e transfer_incoming.undeliverable leva o jdIncomingMessageId dele |
ce-tenantid | O seu tenant, no modo multi-tenant |
| Entrega | Pelo outbox do PostgreSQL. O relay do outbox é o único publisher do broker |
| Manifesto em runtime | GET /streaming/manifest |
STREAMING_ENABLED=true e as variáveis de streaming. Com o streaming desligado, o plugin descarta os eventos. Se você definir STREAMING_CLOUDEVENTS_SOURCE, o valor deve ser exatamente plugin-br-bank-transfer. Em produção, o plugin serve o manifesto apenas quando a autenticação está ligada.
Alguns eventos são de melhor esforço: quando a escrita deles no outbox falha, o plugin mantém a mudança que eles anunciam e não publica o evento. Se um evento esperado não chegar, leia a transferência com Get Transfer.
Catálogo de eventos
Iniciação e ciclo de vida da transferência
| Chave do evento | Schema | Dispara quando |
|---|---|---|
payment_initiation.created | 1.0.0 | Initiate Transfer criou uma iniciação, antes da confirmação dela. |
transfer.initiated | 1.0.0 | O plugin criou uma transferência TED OUT ou TED entre cores a partir de uma iniciação confirmada. |
transfer.processing_started | 1.0.0 | Um TED OUT entrou em processamento (CREATED para PENDING para PROCESSING). |
transfer.completed | 1.2.0 | Um TED OUT, P2P ou TED entre cores foi concluído. Para um TED OUT, o STR o liquidou, ou um operador o liquidou manualmente. Para um TED entre cores, o outro core creditou o destinatário. |
transfer.rejected | 1.1.0 | Um TED OUT ou TED entre cores foi rejeitado, e a retenção dele foi cancelada. Para um TED OUT, a JD o recusou no envio, ou o STR recusou a liquidação. Para um TED entre cores, o outro core recusou o crédito, ou o JD Courier não alcançou nenhum destinatário. |
Conciliação
| Chave do evento | Schema | Dispara quando |
|---|---|---|
transfer.reconciliation_required | 1.0.0 | Um TED OUT com resultado desconhecido entrou em conciliação. |
transfer.reconciliation_resolved | 1.5.0 | O worker de conciliação ou um operador resolveu uma transferência. |
transfer.reconciliation_exhausted | 1.1.0 | O worker de conciliação parou depois do número máximo de tentativas e moveu a transferência para revisão manual. |
transfer.reconciliation_failed | 1.0.0 | O worker de conciliação falhou um TED OUT em um erro determinístico. |
transfer.reconciliation_manual_retry_requested | 1.0.0 | Um operador devolveu um TED OUT da revisão manual para a fila de conciliação. |
transfer.scope_repaired | 1.0.0 | Um operador corrigiu o ledger em que uma transferência está registrada. Nenhum dinheiro se moveu. |
Transferências de entrada
| Chave do evento | Schema | Dispara quando |
|---|---|---|
transfer_incoming.completed | 1.0.0 | O plugin creditou um TED IN ou um crédito ao cliente, ou lançou um crédito ou uma devolução entre cores do outro core (transferType CROSS_CORE_IN). |
transfer_incoming.chargeback | 1.1.0 | Um TED IN concluído falhou em um chargeback STR0010R2. O worker de TED IN o envia, e também um operador que fecha manualmente um chargeback estacionado. |
transfer_incoming.undeliverable | 1.0.0 | O plugin registrou um crédito de entrada que não conseguiu entregar. |
transfer_incoming.return_requested | 1.0.0 | A devolução de um TED IN entrou em processamento: a retenção está colocada, e o STR0010 está prestes a ser enviado. |
transfer_incoming.returned | 1.0.0 | O STR liquidou a devolução de um TED IN, e o crédito original foi revertido. |
transfer_incoming.return_rejected | 1.0.0 | A devolução de um TED IN foi recusada, e a retenção dela foi cancelada. |
transfer_incoming.return_manual_review | 1.0.0 | A devolução de um TED IN aguarda um operador. |
Devoluções de TED OUT e de P2P
| Chave do evento | Schema | Dispara quando |
|---|---|---|
transfer_outgoing.devolution_notified | 1.1.0 | O plugin registrou uma devolução (STR0010R2) de um TED OUT na transferência original. |
transfer_internal.returned | 1.0.0 | A devolução de um P2P foi concluída, e o ledger reverteu a transação original. |
transfer_internal.return_failed | 1.0.0 | O ledger recusou a devolução de um P2P. Nada se moveu, e o P2P pode ser devolvido de novo. |
Deduplicação
Deduplique por(ce-source, ce-id) e mantenha os consumidores idempotentes. Dois eventos também precisam de uma chave de negócio:
transfer_incoming.chargeback: o worker de TED IN e um operador podem anunciar cada um o mesmo chargeback, com dois ids. Deduplique portenantId,transferIdestatus.transfer.reconciliation_resolved: uma resolução de operador pode chegar duas vezes.convergedOntoExistingResolutionmarca a cópia que encontrou a resolução já gravada. Deduplique portenantId,transferId,statusereconciliationStatus, não por esse marcador.
Contratos de payload
Os valores são strings decimais, por exemplo"1500.00". Os timestamps são strings RFC 3339 em UTC. Os campos marcados com ? são opcionais. tenantId fica vazio no modo single-tenant.
// payment_initiation.created
interface PaymentInitiationCreated {
paymentInitiationId: string
tenantId: string
organizationId?: string
ledgerId: string
senderAccountId: string
recipientAccountId?: string
recipientIspb: string
amount: string
feeAmount: string
totalAmount: string
transferType: string
status: string
purpose?: string
expiresAt: string
createdAt: string
}
// transfer.initiated
interface TransferInitiated {
transferId: string
paymentInitiationId: string
tenantId: string
organizationId?: string
ledgerId: string
senderAccountId: string
recipientAccountId?: string
amount: string
feeAmount: string
totalAmount: string
transferType: string
status: string
confirmationNumber: string
controlNumber: string
midazTransactionId?: string
signingArtifactId?: string
createdAt: string
}
// transfer.processing_started
interface TransferProcessingStarted {
transferId: string
tenantId: string
transferType: string
status: string
controlNumber: string
statusPath: string
processingStartedAt: string
}
// transfer.completed
interface TransferCompleted {
transferId: string
initiationId: string
tenantId: string
organizationId?: string
ledgerId: string // on a P2P between ledgers, the payer's ledger
senderAccountId: string
recipientAccountId?: string
midazTransactionId: string
confirmationNumber: string
status: string
transferType: string // TED_OUT, P2P, or CROSS_CORE
amount: string
feeAmount: string
totalAmount: string
packageAppliedId?: string
completedAt: string
// TED OUT only
source?: "str0008r1" | "reconciliation" | "manual"
controlNumber?: string
clearingControlNumber?: string
messageSequence?: string
settledAt?: string
// P2P between ledgers only
recipientLedgerId?: string
ledgerGroupId?: string
}
// transfer.rejected
interface TransferRejected {
transferId: string
tenantId: string
transferType: string // TED_OUT or CROSS_CORE
status: string
failureCode: string // BTF-4005 on a cross-core TED
failureMessage: string
errorCategory: string
midazCancelled: boolean
midazTransactionId?: string
rejectedAt: string
// TED OUT only
source?: "dispatch" | "str0008r1" | "reconciliation"
rejectedBy?: "jd" | "bacen"
settlementRejectionCode?: string
controlNumber?: string
clearingControlNumber?: string
messageSequence?: string
}
// transfer.reconciliation_required
interface TransferReconciliationRequired {
transferId: string
tenantId: string
transferType: string
status: string
reconciliationStatus: string
controlNumber?: string
counterpartySystem: string
failureClass: string
failureCode: string
errorCategory: string
reason: string
reconciliationEnqueuedAt: string
}
// transfer.reconciliation_resolved
interface TransferReconciliationResolved {
transferId: string
tenantId: string
status: string
transferType: string
reconciliationStatus: string
resolution: string
reasonCategory: string
attempts: number
jdResponseCode?: string
controlNumber?: string
jdSequenceNumber?: string
clearingControlNumber?: string
// operator resolution only
actor?: string
operatorReason?: string
evidenceReference?: string
convergedOntoExistingResolution?: boolean
resolutionAuthorizedBy?: string
// resolution manual_repost only
previousCompensationTransactionId?: string
compensationTransactionId?: string
}
// transfer.reconciliation_exhausted
interface TransferReconciliationExhausted {
transferId: string
tenantId: string
status: string
transferType: string
reconciliationStatus: string
resolution: string
reasonCategory: string
attempts: number
maxAttempts: number
holdPreserved: boolean
jdResponseCode?: string
controlNumber?: string
jdSequenceNumber?: string
}
// transfer.reconciliation_failed
interface TransferReconciliationFailed {
transferId: string
tenantId: string
status: string
reconciliationStatus: string
resolution: string
reasonCategory: string
attempts: number
errorCategory: string
jdResponseCode?: string
controlNumber?: string
jdSequenceNumber?: string
}
// transfer.reconciliation_manual_retry_requested
interface TransferReconciliationManualRetryRequested {
transferId: string
tenantId: string
status: string
transferType: string
reconciliationStatus: string
operatorReason: string
previousAttempts: number
requestId?: string
requeuedAt: string
}
// transfer.scope_repaired
interface TransferScopeRepaired {
transferId: string
tenantId: string
ledgerId: string
status: string
transferType: string
actor: string
operatorReason: string
evidenceReference?: string
requestId?: string
repairedAt: string
}
// transfer_incoming.completed
interface TransferIncomingCompleted {
transferId: string
tenantId: string
status: string
transferType: string // TED_IN, TED_IN_STR0005 to TED_IN_STR0051, or CROSS_CORE_IN
amount: string
feeAmount: string
grossAmount: string
controlNumber: string // empty on CROSS_CORE_IN
messageSequence: string // empty on CROSS_CORE_IN
repairedBy: string
}
// transfer_incoming.chargeback
interface TransferIncomingChargeback {
transferId: string
tenantId: string
status: string
transferType: string
// absent when an operator closes the chargeback
chargebackCode?: string
messageSequence?: string
controlNumber?: string
}
// transfer_incoming.undeliverable
interface TransferIncomingUndeliverable {
undeliverableId: string
tenantId: string
jdIncomingMessageId: string
rejectionReason: string
rejectionCategory: string
controlNumber: string
messageSequence: string
grossAmount: string
senderISPB: string
}
// transfer_incoming.return_requested, returned, return_rejected, return_manual_review
interface TransferIncomingReturn {
transferId: string // the return, a TED_OUT
originalTransferId: string // the TED IN that it returns
tenantId: string
organizationId?: string
transferType: string
status: string
controlNumber: string
amount: string // the gross amount that leaves your institution
returnReasonCode: string
requestedVia: string
externalReference?: string
clearingControlNumber?: string
reversalTransactionId?: string
reconciliationReasonCode?: string
reconciliationReasonClass?: string
revertFailureClass?: string
failureCode?: string
rejectionCause?: "not_found" | "str_refused" | "jd_refused" | "local_verdict" | "operator"
occurredAt: string
}
// transfer_outgoing.devolution_notified
interface TransferOutgoingDevolutionNotified {
transferId: string
tenantId: string
codDevTransf: string
chargebackCode: string
senderISPB: string
recipientISPB: string
amount: string
controlNumber: string
transferStatus: string
transferType: string
feeRetained: boolean
feeRefunded: boolean
feeRefundedAmount?: string
via: string
}
// transfer_internal.returned, return_failed
interface TransferInternalReturn {
transferId: string // the return, a P2P
originalTransferId: string
tenantId: string
organizationId: string
ledgerId: string // the ledger of the debited account
recipientLedgerId?: string // between ledgers only: the ledger of the credited account
amount: string
reversalTransactionId?: string
requestedVia: string
revertFailureClass?: string
failureCode?: string
occurredAt: string
}

