Why idempotency keys
An idempotency key is a unique string the client sends with a request so that a retry can’t create a second payment. Without one, a request that fails after the payment goes through but before the client hears back is indistinguishable from one that never landed — so the client retries, and the player is charged twice. The cost of getting it wrong: duplicate charges, refund and chargeback fees, support tickets, store-rating damage, and duplicated in-game currency that breaks the game economy.Idempotency key: requirements
- Format: UUIDv4 (122 random bits) or equivalent; max 255 chars. Sent as the
Idempotency-KeyHTTP header. - One key per purchase intent. Generate it when the player confirms the purchase, persist it locally, and reuse it on every retry until a final response arrives.
- New intent = new key. Buying a second gem pack is a new purchase and gets a new key.
- Never derive keys from timestamps alone, counters, or player ID + item ID — two legitimate identical purchases would collide.
- Send one on every state-changing request: payments, refunds, payouts, and in-game reward grants.
Player ID generation (recommended)
Player IDs are generated on your side and sent to ZBD with each request. ZBD accepts whatever format you use — the guidance here is what we’d suggest if the choice is still open. A good player ID combines a timestamp (creation date-time) with cryptographically secure randomness. The time component keeps IDs sortable and index-friendly; the random component guarantees uniqueness across servers and makes IDs unguessable. Suggested standard: UUIDv7 (RFC 9562)
Example:
0192a4f3-7c1e-7b2a-9f4d-3e8c1a6b5d20
Optionally add a readable type prefix for logs and support: usr_0192a4f37c1e7b2a9f4d3e8c1a6b5d20.
Recommendations
- Generate server-side with a CSPRNG (e.g.
crypto.randomUUIDgrade sources), rather thanMath.random()or sequential counters. - Keep personal data out of the ID — no email, username, device ID, or game account handle. IDs appear in logs, URLs, and receipts.
- Treat IDs as immutable and never reused, even after account deletion.
- An ID is an identifier, not a secret. Don’t use it as an auth token or password substitute; authorize every request separately.
- Avoid exposing raw sequential DB keys externally — they leak player counts and enable enumeration.