> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Eventos do TED JD

> CloudEvents emitidos pelo plugin Bank Transfer para TED OUT, TED IN, P2P, TED entre cores, devoluções e conciliação.

O plugin Bank Transfer emite 21 fatos de negócio JSON como CloudEvents 1.0 em modo binário de conteúdo via Kafka. Os mesmos fatos alimentam os [webhooks](https://docs.lerian.studio/pt/interfaces/ted-jd/ted-webhooks.md) dele.

## 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` |

Defina `STREAMING_ENABLED=true` e as [variáveis de streaming](https://docs.lerian.studio/pt/interfaces/ted-jd/ted-environment-variables.md#streaming-outbox). 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](https://docs.lerian.studio/pt/reference/interfaces/ted-jd/retrieve-transfer.md).

## 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](https://docs.lerian.studio/pt/reference/interfaces/ted-jd/initiate-transfer.md) 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](https://docs.lerian.studio/pt/interfaces/ted-jd/ted-cross-core.md) 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](https://docs.lerian.studio/pt/interfaces/ted-jd/ted-in.md#customer-credits), 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](https://docs.lerian.studio/pt/interfaces/ted-jd/ted-in.md#return-a-received-transfer) 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 por `tenantId`, `transferId` e `status`.
* **`transfer.reconciliation_resolved`**: uma resolução de operador pode chegar duas vezes. `convergedOntoExistingResolution` marca a cópia que encontrou a resolução já gravada. Deduplique por `tenantId`, `transferId`, `status` e `reconciliationStatus`, 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.

```typescript theme={null}
// 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
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.