# Idempotency

Networks fail. Retry a create with the same request, and Weav returns the payment or checkout the first one made, never a second one. Your `external_reference_id` is the key, so there's nothing extra to send.

```http
POST /v1/payments
Authorization: Bearer wv_test_••••••••
Content-Type: application/json

{ "channel": "QR_PH", "currency": "PHP", "amount": 1250.00, "external_reference_id": "ORD-10541" }
```

## Rules

- On `POST /v1/payments` and `POST /v1/checkouts`. The rules work the same way for a checkout.
- **Same `external_reference_id` and same body:** you get the payment that request created, with the same `201` and the same fields, as it is now (so its `status` may have moved on), plus the header `Idempotent-Replayed: true`.
- **Same `external_reference_id` and a different body:** `409` with code `4090001`. A reference belongs to one payment: if a customer retries an order, send a new reference such as `ORD-10541-2`.
- **A reference that an earlier payment already has under another key:** `422` with code `4220000` (`errors` names `external_reference_id`). This happens when the first request sent an `Idempotency-Key` and the retry doesn't, or sent a different one. Retry exactly as you sent the first request, or use a new reference for a new payment.
- **Same request while the first one is still running:** `409` with code `4090002`. Wait and retry.
- A request that creates nothing (for example it fails validation) leaves the reference unused, so you can fix the cause and retry.
- Test and live mode are separate.
- A checkout's `external_reference_id` is optional. A checkout with no reference and no `Idempotency-Key` is never matched to an earlier one, so each request makes a new checkout.

```mermaid
flowchart LR
    K{Reference<br/>used before?} -->|No| N[201<br/>created]
    K -->|Yes| B{First request<br/>still running?}
    B -->|Yes| W[409, 4090002<br/>wait, then retry]
    B -->|No| S{Same body?}
    S -->|Yes| RP[201, the same one<br/>Idempotent-Replayed]
    S -->|No| CF[409, 4090001<br/>use a new reference]
```

## Your own key (optional)

To use your own key, send an `Idempotency-Key` header, such as a new UUID for each new payment and the same one for every retry of it (up to 255 characters). Weav then matches retries on that key instead, with the same rules. Use one or the other for a payment, not both: a retry without the key you sent first is a new request, and its reference is already taken (`422`).

```http
Idempotency-Key: 7d1f6c0e-2b4a-4c9e-9f3d-6a1b8e2c5f10
```
