# Stripe idempotency_error: same key, different params means a client bug

## The symptom

`400` with `type: 'idempotency_error'` and a message like "Keys for idempotent requests can only be used with the same parameters they were first used with." Your retry logic may be looping on it.

## Confirm the cause

This error means: the key was seen before, but this request's parameters differ from the first request that used it. Stripe compares the full parameter set. Common triggers:

- A key built from `orderId` only, reused after the order changed (new amount, new customer).
- A static or hardcoded key shared across different operations.
- A key from a *different logical operation* recycled by copy-paste.

Check your logs: find the first request that used the key and diff the parameters.

## The fix

Do not retry with the same key. It will fail identically forever. Two cases:

1. **It was a retry of the same operation but something changed the params.** Fix the key generation: the key must be stable for one logical operation and change when the operation's real inputs change. Good pattern: `payment-attempt:{orderId}:{attemptNumber}` or a UUID minted once per attempt and stored with the attempt.

2. **It was genuinely a new operation.** Mint a fresh key. A brand-new random key per request silences the error but also throws away duplicate protection, so scope deliberately: one key per logical operation, reused across retries of that operation only.

Note the TTL: Stripe prunes keys after about 24 hours. A retry the next day under the same key is treated as a new request, which is correct behavior, not a bug.

## Verify the fix

Replay the failing request with a fresh key and confirm it succeeds. Then simulate a double-submit (same key, same params twice) and confirm the second returns the cached response without creating a duplicate. Grep your key-generation code: every call site should derive the key from the operation identity, never from a constant.
