# Payload

> Os eventos que a Rapid envia por webhook: headers, campos de cada corpo, exemplos completos e a diferença entre os formatos v2 e legacy.

Página: https://doc.rapidchargeback.com/canais/webhook/payload/

A Rapid envia `HTTP POST` com `Content-Type: application/json` para a URL configurada. O corpo é um objeto JSON e o campo `event` (também no header `X-Webhook-Event`) diz o que aconteceu.

## Eventos

| Evento | Produto | Quando dispara | Corpo |
|---|---|---|---|
| `chargeback_alert.received` | Alerta | Um alerta foi recebido e associado à sua empresa | [Alerta recebido](#evento-chargeback_alertreceived) |
| `dispute.fraud.revoke_access` | Disputa | Chegou uma disputa de **fraude** (Visa 10.4 / Mastercard 4837) e a bandeira exige que você corte o acesso do portador | [Revogação de acesso](#evento-disputefraudrevoke_access) |

A mesma URL recebe todos os eventos: use `event` (ou o header) para rotear. Se você só trata um deles, responda `200` para os demais mesmo sem processar.

Existem **dois formatos**, definidos pela Rapid na sua conta:
- **`v2`**: padrão para contas novas. Descrito nesta página (headers, assinatura, corpo).
- **`legacy`**: contas migradas do sistema anterior. Mesmo corpo e headers do sistema antigo, **sem assinatura**. Descrito na seção [Formato legacy](#formato-legacy) no fim da página. O formato `legacy` vale **apenas** para `chargeback_alert.received`: os outros eventos saem sempre em `v2`, mesmo nessas contas.

Para saber/alterar o formato da sua conta, fale com o suporte da Rapid.

## Método e headers (formato `v2`)

```
POST https://seu-sistema.com/webhooks/rapid
Content-Type: application/json
X-Webhook-Signature: sha256=<hmac_hex>
X-Webhook-Timestamp: 1790000000
X-Webhook-Event: chargeback_alert.received
X-Webhook-Reference-Id: <alert_id>
```

- `X-Webhook-Signature`: HMAC-SHA256 de `${X-Webhook-Timestamp}.${body}` com a sua chave de assinatura. Ver [Autenticação](https://doc.rapidchargeback.com/canais/webhook/autenticacao/).
- `X-Webhook-Timestamp`: quando a Rapid assinou, em segundos desde a epoch. Entra na assinatura (anti-replay) e deve ser conferido contra uma janela de tolerância de 5 minutos.
- `X-Webhook-Event`: tipo do evento (ver [Eventos](#eventos)). Use para roteamento.
- `X-Webhook-Reference-Id`: ID de referência do evento: `alert_id` em `chargeback_alert.received`, `dispute_id` em `dispute.fraud.revoke_access`. Permite deduplicação sem parsear o body.

> Os headers `clientid`/`clientkey` **não** são enviados no formato `v2`: quem autentica a entrega é a assinatura. Eles seguem indo apenas no formato `legacy` (ver [Formato legacy](#formato-legacy)).

---

## Evento `chargeback_alert.received`

### Estrutura do corpo

| Campo | Tipo | Descrição | Obrigatório |
|---|---|---|---|
| `event` | string | `chargeback_alert.received` | Sim |
| `alert_id` | string (UUID) | ID único do alerta na Rapid, use para chamar os endpoints de consulta e atualização de status | Sim |
| `provider_alert_id` | string | ID do alerta no sistema do provedor. Útil para cross-referência em caso de suporte direto com o provedor | Sim |
| `provider` | string | Origem do alerta: `ethoca_alerts` ou `verifi_rdr` | Sim |
| `amount` | number \| null | Valor da transação disputada (pode vir `null` quando o provedor não informa) | Sim |
| `currency` | string | Código ISO 4217 com 3 letras maiúsculas | Sim |
| `card_last4` | string | Últimos 4 dígitos do cartão | Sim |
| `card_bin` | string | BIN do cartão (6-8 dígitos) | Sim |
| `transaction_date` | string | Data da transação original (ISO 8601, `"2026-04-01T00:00:00.000Z"`) | Sim |
| `descriptor` | string | Nome exibido na fatura do portador | Sim |
| `arn` | string | Acquirer Reference Number | Não |
| `caid` | string | Card Acceptor ID | Não |
| `auth_code` | string | Código de autorização da transação | Não |
| `alert_type` | string | Tipo do alerta (ex: `fraud`, `dispute`) | Não |
| `reason_code` | string | Código do motivo da disputa | Não |
| `issuer` | string | Banco emissor do cartão | Não |
| `installment_number` | number \| null | Parcela atual | Não |
| `installment_count` | number \| null | Total de parcelas | Não |
| `status` | string | Status inicial do alerta. Sempre `pending` no recebimento | Sim |
| `received_at` | string | Quando a Rapid recebeu o alerta (ISO 8601) | Sim |
| `expires_at` | string \| null | Prazo para resposta (ISO 8601), aplicável apenas a Ethoca | Não |
| `merchant` | object \| null | Dados do merchant associado (veja abaixo); `null` se o alerta ainda não foi associado | Sim |

#### Objeto `merchant`

| Campo | Tipo | Descrição |
|---|---|---|
| `id` | string (UUID) | ID do merchant na Rapid |
| `name` | string | Nome do merchant |

---

### Exemplo de payload

```json
{
  "event": "chargeback_alert.received",
  "alert_id": "00000000-0000-0000-0000-000000000099",
  "provider_alert_id": "2UBOD4MKAI42RPXEYU4UVQPS",
  "provider": "ethoca_alerts",
  "amount": 150.00,
  "currency": "USD",
  "card_last4": "4242",
  "card_bin": "424242",
  "transaction_date": "2026-04-01T00:00:00.000Z",
  "descriptor": "LOJA EXEMPLO",
  "arn": "74537119547024600128228",
  "caid": "123456789",
  "auth_code": "123456",
  "alert_type": "fraud",
  "reason_code": "4853",
  "issuer": "Chase Bank",
  "installment_number": null,
  "installment_count": null,
  "status": "pending",
  "received_at": "2026-04-14T10:00:00Z",
  "expires_at": "2026-04-15T10:00:00Z",
  "merchant": {
    "id": "00000000-0000-0000-0000-000000000001",
    "name": "Minha Loja"
  }
}
```

---

## Evento `dispute.fraud.revoke_access`

Disparado quando a Rapid recebe uma disputa de **fraude**. As bandeiras exigem que o lojista tente revogar o produto ou serviço entregue ao portador e tenha processo para evitar reincidência (Visa Core Rules §10.4.4.3). Quanto mais rápido o corte, menor o prejuízo: trate este evento de forma automática se possível.

O campo `merchant` diz **qual das suas lojas** vendeu: a entrega é sempre no webhook único da empresa, você roteia internamente.

### Estrutura do corpo

| Campo | Tipo | Descrição | Obrigatório |
|---|---|---|---|
| `event` | string | `dispute.fraud.revoke_access` | Sim |
| `dispute_id` | string (UUID) | ID da disputa na Rapid. Use como chave de idempotência; a disputa aparece no painel, em Disputas | Sim |
| `merchant` | object \| null | Loja associada (`id`, `name`); `null` se a disputa ainda não foi associada | Sim |
| `network` | string | Bandeira: `visa`, `mastercard`, … | Sim |
| `condition` | string \| null | Condição/reason da bandeira (ex.: `10.4`, `4837`) | Não |
| `transaction_id` | string \| null | ID da transação na rede, quando informado pela adquirente | Não |
| `customer_ref` | string \| null | Identificador do cliente que você enviou na transação (`account_id`), quando existir | Não |
| `order_ref` | string | Referência do pedido: número do pedido, seu ID externo ou, na falta deles, o `dispute_id` | Sim |
| `reason` | string | Sempre `fraud_dispute_received` | Sim |
| `is_account_takeover` | boolean | `true` quando há indício de conta tomada (dispositivo e IP divergem do histórico do cliente) | Sim |
| `required_actions` | string[] | Ações exigidas: `revoke_access`, `prevent_reoccurrence` e, em conta tomada, `re_authenticate` | Sim |
| `citation` | object | Regra que fundamenta a exigência (`section`, `visa_id`, `page`, `quote_en`, `ruleset_version`) | Sim |
| `emitted_at` | string | Quando a Rapid emitiu o evento (ISO 8601) | Sim |
| `deadline_hint` | string | Prazo de resposta da disputa (ISO 8601) ou `as_soon_as_possible` quando não há prazo conhecido | Sim |

### Exemplo de payload

```json
{
  "event": "dispute.fraud.revoke_access",
  "dispute_id": "00000000-0000-0000-0000-0000000000d1",
  "merchant": {
    "id": "00000000-0000-0000-0000-000000000001",
    "name": "Minha Loja"
  },
  "network": "visa",
  "condition": "10.4",
  "transaction_id": "ch_3Qx0000000",
  "customer_ref": "acct-8842",
  "order_ref": "PED-5078",
  "reason": "fraud_dispute_received",
  "is_account_takeover": false,
  "required_actions": ["revoke_access", "prevent_reoccurrence"],
  "citation": {
    "section": "10.4.4.3",
    "visa_id": "0030642",
    "page": 634,
    "quote_en": "An Acquirer must ensure that its Merchant attempts to revoke provision of goods or services from the Cardholder after a Dispute category 10 (Fraud) Dispute and that the Merchant has a process in place to prevent reoccurrence by the Cardholder.",
    "ruleset_version": "visa-core-rules-2026-04-18"
  },
  "emitted_at": "2026-09-30T14:25:00.000Z",
  "deadline_hint": "2026-10-14T14:20:00.000Z"
}
```

### Confirmando o que você fez (opcional)

Responder `200` já encerra a entrega. Se quiser registrar o que foi feito, retorne no corpo um JSON com os campos abaixo. Ele aparece no painel, na disputa, como confirmação da sua integração. Chave desconhecida invalida o corpo inteiro (a entrega continua válida, só não registra a confirmação).

| Campo | Tipo | Descrição |
|---|---|---|
| `status` | string | `done`, `partial`, `refused`, `not_applicable` ou `accepted` |
| `actions_taken` | string[] | Quais das `required_actions` você executou |
| `revoked_at` | string | Quando o acesso foi cortado (ISO 8601) |
| `note` | string | Observação livre, até 500 caracteres |

```json
{
  "status": "done",
  "actions_taken": ["revoke_access", "prevent_reoccurrence"],
  "revoked_at": "2026-09-30T14:25:03Z",
  "note": "conta suspensa e cartao bloqueado para novas compras"
}
```

**Idempotência:** a Rapid emite **um** evento por disputa (`dispute_id` é único). Retentativas repetem o mesmo `dispute_id`, então trate pela chave em vez de contar chamadas. Se não conseguirmos entregar, a disputa aparece no painel com a pendência de revogação, e o cliente confirma manualmente ali.

---

## Resposta esperada

Sua aplicação deve retornar um dos seguintes códigos para confirmar o recebimento:

| Código | Significado |
|---|---|
| `2xx` | Sucesso. `200`, `201`, `202` e `204` valem igual; o corpo é opcional |

Qualquer outro código (incluindo `4xx` e `5xx`) é tratado como falha e dispara retentativa. Cadastre a URL final: um `301`, `302` ou `303` na sua URL conta como falha (ver [Redirecionamento](https://doc.rapidchargeback.com/canais/webhook/retries-e-logs/#redirecionamento)). Ver [Retries e logs](https://doc.rapidchargeback.com/canais/webhook/retries-e-logs/).

Em `dispute.fraud.revoke_access` o corpo do `200` pode trazer a confirmação do que você executou (ver [acima](#confirmando-o-que-você-fez-opcional)). Nos demais eventos o corpo é ignorado.

---

## Campos que podem evoluir

Novos campos podem ser adicionados ao payload no futuro. Sua aplicação deve **ignorar campos desconhecidos** em vez de falhar. Nunca altere ou remova campos ao processar, apenas leia.

---

## Formato legacy

Contas migradas do sistema anterior recebem o **mesmo POST de antes**. Headers: `Content-Type: application/json`, `x-source: rapid`, `clientid`, `clientkey`, e **sem** `X-Webhook-Signature`, `X-Webhook-Event` ou `X-Webhook-Reference-Id`.

| Campo | Tipo | Descrição |
|---|---|---|
| `alert_id` | string | **ID do alerta no provedor** (não é o UUID da Rapid). É o valor a usar em `POST /chargeback-alert/get` e no alias `POST /chargeback-alert/update/status` |
| `merchant` | string | Nome do merchant |
| `provider` | string | `ethoca` ou `verifi-rdr` |
| `descriptor` | string | Nome na fatura do portador |
| `transaction_date` | string | Data da transação (ISO 8601) |
| `currency` | string | ISO 4217 |
| `amount` | number \| null | Valor da transação |
| `card_number` | string \| null | `BIN******LAST4`, ou `null` quando o provedor não informou BIN e final |
| `created_at` | string | Quando a Rapid recebeu o alerta |
| `arn` | string \| null | Acquirer Reference Number |
| `authorization_code` | string \| null | Código de autorização |
| `issuer` | string \| null | Banco emissor |
| `type` | string \| null | Tipo do alerta |
| `global` | boolean | `true` para alerta internacional |
| `reason_code`, `status_code`, `mcc`, `tier`, `caid` | string \| null | Campos do provedor, quando existirem |
| `installment_number`, `total_installment_count` | number \| null | Parcelamento |

Não há campo `event`, `status` nem `expires_at` neste formato. Retentativas, timeout e logs são os mesmos do `v2`.
