Skip to main content
ZBD handles real-value transactions for games. Every such request carries an idempotency key — if the same request arrives again with the same key, ZBD returns the original result instead of creating a second payment. The key is generated by the client, once per purchase intent, and reused on every retry of that intent rather than regenerated each attempt. Player identifiers deserve the same care, though ZBD imposes no format on them: how you generate the player IDs you send us is your call. We recommend time-ordered, random IDs (UUIDv7) — unique across services, sortable, unguessable, and free of personal data. This page explains why both matter and what to implement.

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-Key HTTP 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 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.randomUUID grade sources), rather than Math.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.

Do / Don’t