Skip to main content
Droplinked does not currently accept an Idempotency-Key request header. Sending one has no effect — it is not read, not stored, and not honoured. Retry safety comes from the mechanisms below instead. This is stated plainly because assuming a header that does not exist is the most expensive wrong assumption a payments integration can make.

Where duplicate-charge protection actually lives

Droplinked derives a deterministic idempotency key for the outbound PSP call, anchored on the internal order id. A network blip, a deploy bounce, or an internal retry therefore re-sends the same key to the provider and gets the provider’s cached response back — the same payment intent, and no second authorisation on the buyer’s card. The anchor is the order id, not the cart id and not the payment-intent id. A cart can be forked into several checkout attempts; an order cannot. A new key is minted only when a buyer explicitly re-attempts after a declined authorisation — which is the case where a fresh intent is what you want.

Per-endpoint retry safety

Natural dedupe keys elsewhere on the platform

Several surfaces dedupe on a natural identifier rather than a supplied key. Where one exists, it is documented on the endpoint’s own page. Examples:
  • Wallet registration dedupes on merchantId : network : lowercased address.
  • Agentic intent recording dedupes on a caller-supplied intentId.
  • Brand-attestation requests dedupe on (shopSlug, PENDING) — re-submitting returns the existing request id rather than a duplicate-conflict error.

What you should do

  1. Generate your own correlation id per logical operation and keep it in your logs. You will need it to reconcile a timeout, because the API will not dedupe for you.
  2. Never retry POST /v2/orders blind. On a timeout, read back the order by cart before creating another.
  3. Retry 429 and 503; do not retry 400, 401, 403, 404. Back off using Retry-After — remembering it is in milliseconds, see Rate limits.
  4. Treat the webhook as the source of truth for “paid”. Not the intent response, not the redirect return.
Refund scope, stated precisely. POST /v2/orders/:orderId/refund is merchant-only (a customer token is rejected) and today it services Bonum-paid orders: the use case verifies the order belongs to the caller’s shop, is CONFIRMED, and was paid via Bonum before reversing it. It is not a universal cross-PSP refund route. Refunds for other providers are handled through that provider’s own tooling — ask before you build a refund flow against this endpoint.