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

# Idempotencia

> Como usar Idempotency-Key en SimplePay para reintentar writes sin duplicar checkouts, links, holds, bookings, recursos o refunds.

La idempotencia permite reintentar una operacion cuando hay timeouts, errores de red o procesos duplicados sin crear multiples objetos de negocio.

SimplePay acepta el header `Idempotency-Key` en operaciones write.

```http request theme={"theme":{"light":"github-light","dark":"github-dark"}}
Idempotency-Key: order_1001_checkout_v1
```

## Cuando usarlo

Usalo en:

* `POST /v1/hosted-checkout/sessions`
* `POST /v1/payment-links`
* `POST /v1/refunds`
* `POST /v1/products`
* `POST /v1/customer-hub/customers` y demas writes `/v1/customer-hub/*`
* `POST /v1/bookable-payments/setup`
* `POST /v1/bookable-payments/holds`
* `POST /v1/bookable-payments/holds/{id}/payment`
* `POST /v1/bookable-payments/bookings`
* Cualquier create, update o lifecycle mutation Bookable.

## Buenas keys

| Operacion         | Ejemplo                                 |
| ----------------- | --------------------------------------- |
| Checkout de orden | `order_1001_checkout_v1`                |
| Link de pago      | `invoice_2026_0007_payment_link_v1`     |
| Sync de customer  | `customer_platform_user_abc_sync_v1`    |
| Hold Bookable     | `tour_2026_07_10_0900_hold_user_abc_v1` |
| Booking refund    | `booking_bkg_123_refund_full_v1`        |

## Malas keys

Evita keys aleatorias si tu backend puede reintentar el mismo trabajo desde cero.

```txt bad theme={"theme":{"light":"github-light","dark":"github-dark"}}
random_uuid_each_retry
Date.now()
Math.random()
```

Usa keys deterministicas derivadas de tu entidad de negocio.

## Patron recomendado

<Steps>
  <Step title="Crea una entidad local pendiente">
    Por ejemplo `orders.status = pending_payment`.
  </Step>

  <Step title="Genera una key deterministica">
    Usa el ID local y una version de operacion: `order_1001_checkout_v1`.
  </Step>

  <Step title="Llama SimplePay">
    Incluye `Idempotency-Key` y guarda el ID que responde SimplePay.
  </Step>

  <Step title="Reintenta con la misma key">
    Si hay timeout, repite exactamente la misma operacion con la misma key.
  </Step>
</Steps>

```ts idempotent-checkout.ts theme={"theme":{"light":"github-light","dark":"github-dark"}}
const idempotencyKey = `${order.id}_checkout_v1`;

const response = await fetch("https://api.simplepay.mx/v1/hosted-checkout/sessions", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SIMPLEPAY_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": idempotencyKey,
  },
  body: JSON.stringify({
    currency: "mxn",
    success_url: order.successUrl,
    cancel_url: order.cancelUrl,
    client_reference_id: order.id,
    line_items: order.items.map((item) => ({
      name: item.name,
      amount: item.amountMinor,
      quantity: item.quantity,
    })),
  }),
});
```

<Warning>
  No reutilices la misma key para operaciones semanticamente distintas. Si
  cambias monto, producto o cliente, incrementa la version de la key.
</Warning>
