---
title: "Create each charge with an idempotency key · Agent Wranglers"
url: https://agentwranglers.se/playbook/payments/amounts-and-orders/idempotent-charge-creation
updated: 2026-10-20
licence: "All rights reserved"
---

# Create each charge with an idempotency key

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Required
- Chapter: [Amounts and orders](https://agentwranglers.se/playbook/payments/amounts-and-orders)
- Rule: Send an idempotency key, built from your own stable IDs, on every provider request that creates a payment, a refund or a payout.
- How: A request can time out after the provider has charged the card. A retry with the same key returns the first result instead of charging again. Build the key from the order and attempt, such as `order-ord_8f2k-attempt-1`, and reuse it for every retry of that request. Make a new key only when the amount or payment method changes. Providers forget keys after a while, after 24 hours at Stripe. After that, look the payment up by your order ID instead of retrying. The server side of the same idea is [idempotency keys](https://agentwranglers.se/playbook/api-design/reliability/idempotency-keys), and the attack test is [race conditions](https://agentwranglers.se/playbook/adversarial-testing/abuse-and-limits/race-conditions).
- Check: In a test, make the provider call time out after the request was sent, then retry. The provider shows one payment, and the order shows one charge.

Example:

```js
const idempotencyKey = `order-${order.id}-attempt-${order.attempt}`
const intent = await withRetries(() => stripe.paymentIntents.create(
  { amount: order.totalMinor, currency: order.currency.toLowerCase(), metadata: { orderId: order.id } },
  { idempotencyKey },
))
```

```python
idempotency_key = f"order-{order.id}-attempt-{order.attempt}"
intent = with_retries(lambda: stripe.PaymentIntent.create(
    amount=order.total_minor,
    currency=order.currency.lower(),
    metadata={"order_id": order.id},
    idempotency_key=idempotency_key,
))
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers payments playbook: https://agentwranglers.se/playbook/payments/amounts-and-orders/idempotent-charge-creation`.

- Previous: [Move orders through a fixed set of states](https://agentwranglers.se/playbook/payments/amounts-and-orders/payment-state-machine)
- Next: [Keep one open payment per order](https://agentwranglers.se/playbook/payments/amounts-and-orders/one-open-payment-per-order)
- [Amounts and orders](https://agentwranglers.se/playbook/payments/amounts-and-orders)
