# First integration

> From zero to the first alert answered: credentials, webhook with validated signature, first transaction and the status callback, with ready-to-run commands.

Página: https://doc.rapidchargeback.com/en/primeira-integracao/

The shortest path to a working integration. By the end of this guide your application receives alerts with a validated signature, sends transactions and answers alerts through the API. Each step points to the page with the full detail.

> **Using an AI assistant?** Connect the [documentation MCP](https://doc.rapidchargeback.com/en/referencia/ferramentas-para-devs/#mcp) before you start: the assistant then looks up these pages instead of guessing fields and codes.

## 1. Get the credentials

In the Rapid dashboard, under **Settings › API**, generate the `client_id` and the `client_secret`. The secret is shown **only once**: copy it right away. If you lose it, generate it again in the same place (the previous credentials stop working at that same moment).

Keep both in environment variables, never in the code:

```bash
export RAPID_CLIENT_ID="your_client_id"
export RAPID_CLIENT_SECRET="your_client_secret"
```

Details in [Authentication](https://doc.rapidchargeback.com/en/referencia/autenticacao/).

## 2. Confirm the credential works

List your company's most recent alert:

```bash
curl -u "$RAPID_CLIENT_ID:$RAPID_CLIENT_SECRET" \
  "https://api.rapidchargeback.com/api/v1/chargeback-alert/alerts?per_page=1"
```

| Response | What it means |
|---|---|
| `200` with `data` and `meta` | Correct credential. `data` may be empty if no alert has arrived yet |
| `401 UNAUTHORIZED` | Wrong `client_id` or `client_secret` |
| `403 COMPANY_BLOCKED` | The company is blocked at Rapid: contact support |

## 3. Register the webhook

Under **Settings › Webhook**, register the URL that will receive the events. It must be **HTTPS** and a **public internet address**: the dashboard rejects `http://`, `localhost` and local network IPs.

When you save, Rapid generates the **signing key** and shows it only once. Keep it in `RAPID_WEBHOOK_SECRET`.

To receive on your machine during development, expose the local server with an HTTPS tunnel (see [Best practices](https://doc.rapidchargeback.com/en/canais/webhook/boas-praticas/#use-a-public-internet-address)).

## 4. Validate the signature

Every delivery carries `X-Webhook-Signature` and `X-Webhook-Timestamp`. Your endpoint checks the signature **before** processing anything.

Copy the ready-made endpoint in your language (Node.js, Python or PHP) from [Webhook authentication](https://doc.rapidchargeback.com/en/canais/webhook/autenticacao/#examples). All three follow the same rules:

- the signature is computed over the **raw body**: do not parse it as JSON before validating
- a delivery older than 5 minutes is rejected (replay protection)
- any delivery that does not pass gets `401`

Respond `2xx` quickly and process later, in a queue: Rapid waits up to 30 seconds and, with no response, tries again. Use the `alert_id` so you do not process the same alert twice. See [Best practices](https://doc.rapidchargeback.com/en/canais/webhook/boas-praticas/).

## 5. Send the first transaction

If you use **Prevention** or **Dispute**, they work with the sales transactions you send. Each transaction says which merchant (store, brand or seller) it belongs to, through the `merchant_id`. See yours:

```bash
curl -u "$RAPID_CLIENT_ID:$RAPID_CLIENT_SECRET" \
  "https://api.rapidchargeback.com/api/v1/merchants"
```

The `id` of each item in the response is the `merchant_id` (see [List merchants](https://doc.rapidchargeback.com/en/canais/merchants/listar-merchants/)). With it, the minimal transaction:

```bash
curl -X POST https://api.rapidchargeback.com/api/v1/transactions \
  -u "$RAPID_CLIENT_ID:$RAPID_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "merchant_id": "00000000-0000-0000-0000-000000000001",
    "external_id": "TXN-2026-001",
    "transaction_id": "cob_8f2a91c4",
    "transaction_date": "2026-04-01T15:30:00Z",
    "amount": 150.00,
    "currency": "USD",
    "card_bin": "424242",
    "card_last4": "4242",
    "items": [
      { "product_description": "Assinatura Premium - Mensal", "unit_price": 150.00 }
    ]
  }'
```

- The `transaction_id` is the charge identifier in your payment gateway. It is how a future chargeback finds the transaction: without it the defense goes out with no history.
- The response is `201` with the transaction `id` at Rapid: keep it. If you lose it, you can find the transaction [by the `external_id`](https://doc.rapidchargeback.com/en/canais/transactions/consultar-transacao/#by-your-systems-id).
- If the `warnings` key comes back, the transaction was created, but fields that improve protection are missing.

All fields in [Create transaction](https://doc.rapidchargeback.com/en/canais/transactions/criar-transacao/). For volume, use [batch upload](https://doc.rapidchargeback.com/en/canais/transactions/envio-em-lote/).

## 6. Answer the first alert

When a **Mastercard** alert arrives, you have **24 hours** to answer. With the `alert_id` received in the webhook:

```bash
curl -X PATCH https://api.rapidchargeback.com/api/v1/chargeback-alert/alerts/00000000-0000-0000-0000-000000000099/status \
  -u "$RAPID_CLIENT_ID:$RAPID_CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{ "status": "account_suspended" }'
```

| Status | When to use |
|---|---|
| `notfound` | The transaction does not exist in your system |
| `account_suspended` | The transaction exists and is already resolved (refund made, access revoked) |
| `other` | The transaction exists, but is not resolved yet |

A **Visa** alert arrives with the refund already made and has no deadline. See [Rules and deadlines](https://doc.rapidchargeback.com/en/produtos/alerta/regras-e-prazos/).

## Before going to production

- [ ] Credentials and signing key in environment variables or a secrets vault
- [ ] Webhook validates the signature and the 5-minute window, and rejects with `401`
- [ ] Webhook responds `2xx` in under 30 seconds and processes in a queue
- [ ] The same `alert_id` processed twice causes no duplicate effect
- [ ] Mastercard alert answered within 24 hours, automatically or by someone on call
- [ ] Transactions with `transaction_id` filled in, if you use Dispute
- [ ] `429` handled by waiting for `Retry-After` (see [Response codes](https://doc.rapidchargeback.com/en/referencia/codigos-de-resposta/#rate-limit))

## Next steps

- [Webhook payload](https://doc.rapidchargeback.com/en/canais/webhook/payload/): every field of each event.
- [Common problems](https://doc.rapidchargeback.com/en/referencia/problemas-comuns/): what to do when something does not work.
- [Developer tools](https://doc.rapidchargeback.com/en/referencia/ferramentas-para-devs/): the documentation in your AI assistant and the Postman collection.
