Queek docs

Payments

What happens between checkout_url and orders/paid, the Idempotency-Key contract, and stores that collect through their own provider account.

Your integration never touches a payment. The Storefront API ends at checkout_url; Queek's hosted checkout takes the shopper through address, delivery and payment; a webhook tells you the order exists and then that it is paid. This page is what happens in between, so you can reason about it — not a payment API to call.

The flow, from your side

you                         Queek checkout                          you
 │  POST /store/cart/items      │                                    │
 │  POST /store/cart/validate   │                                    │
 │  redirect to checkout_url ──►│                                    │
 │                              │ order created ────── orders/create ►│
 │                              │ payment initialised                │
 │                              │ shopper pays (redirect or inline)  │
 │                              │ charge verified                    │
 │                              │ order finalised ────── orders/paid ►│
 │                              │                     orders/updated ►│
  1. Build the cart with X-Cart-Session, then POST /store/cart/validate so stock and prices are current. Every cart reply carries checkout_url.
  2. Send the shopper to checkout_url. Queek shows exactly this cart and creates the order once the shopper commits. Your orders/create webhook fires here; for an online payment payment_status is not yet paid.
  3. Payment is initialised against the store's payment provider. Checkout either redirects the shopper to the provider's hosted page or drives the provider's inline widget — the shopper never sees a Queek card form, and neither do you.
  4. The charge is verified. Whatever door reports success — the provider's browser redirect, checkout's own verify call, the provider's webhook — is only a trigger. Checkout re-queries the provider for the transaction and requires the confirmed amount and currency to equal the transaction's before anything is marked paid.
  5. The order is finalised and orders/paid fires (with orders/updated alongside it). data.payment_status is now paid and data.payment_method names how.

Confirmation is idempotent on Queek's side: a redirect and a provider webhook confirming the same reference finalise the order once. You will receive orders/paid once per order; dedupe on webhook-id regardless.

Treat orders/paid as the fact

Do not fulfil on orders/create. An order can be created and never paid, and the shopper can abandon the provider page. payment_status on orders/paid — or a later orders/updated whose data.payment_status is paid — is the signal money arrived.

When the provider's answer does not match

If the provider confirms a charge whose amount or currency is not the transaction's, the order is left unpaid and flagged for a human to reconcile. Checkout surfaces this as 409 payment_amount_mismatch; you will not receive orders/paid for that order until it is resolved by the merchant.

Offline methods

A store may also accept bank transfer or cash, depending on its settings and the delivery method. Such an order stays unpaid until the merchant confirms receipt, at which point orders/paid fires exactly as above. Read data.payment_method if the distinction matters to you.

Idempotency-Key

Idempotency-Key is the platform-wide retry contract for writes. An operation that honours it lists the header as a parameter in the reference; send a fresh random key per logical request and retry with the same key on a network failure, and the second request cannot execute twice.

Which operations

In the current reference no storefront operation lists the header yet — the cart endpoints are natural upserts and checkout_url hands the order itself to Queek. The header is optional and additive everywhere: an operation that does not list it ignores it, so sending it costs nothing and a future write that adopts it needs no change on your side.

curl -X POST https://client.usequeek.com/v1/<a write that lists the header> \
  -H "X-Client-Key: sk_live_your_key_here" \
  -H "Idempotency-Key: 7d3c4c1a-2c50-4c0f-8f0f-3a4d1a2b9c77" \
  -H "Content-Type: application/json" \
  -d '{ … }'

The contract, exactly:

SituationResult
Same key, same bodyThe stored response is replayed byte for byte, with Idempotent-Replayed: true.
Same key, different body409 idempotency_key_reuse. The key already means something else.
Same key, two requests in flightThe second waits up to 15s for the first to finish, then replays it. Past that it is 409 idempotency_key_in_progress — retry in a moment; nothing ran twice.
The first attempt failed (4xx/5xx)Nothing is stored. A retry with the same key is a real retry.
24 hours laterThe stored response has expired; the same key starts a new request.

The slot is store + caller + METHOD:path + key. The body is the fingerprint, not part of the slot — which is what makes reuse with a different body a refusal rather than a silent second execution. GET requests ignore the header; they are safe to retry as they are.

Collecting through the merchant's own account

By default Queek collects payments and settles the merchant. A store on an eligible plan, with identity verification complete, may instead collect straight into its own provider account — its own Paystack account today. The merchant enables this in the dashboard; there is nothing for you to configure.

What changes for an integrator is almost nothing:

  • The provider's hosted page is served from the merchant's own account, so the shopper sees the merchant's identity with the provider rather than Queek's.
  • Verification happens against the merchant's account, using the merchant's stored keys.
  • checkout_url, the webhooks, payment_status and payment_method are identical.

The dashboard's own errors for this feature are named in the vocabulary — you may see them quoted by a merchant, never on this API:

error.codeStatusCause
custom_gateway_forbidden403Only the store owner can change where payments are collected.
custom_gateway_plan_required403The store's plan does not include collecting into its own account.
custom_gateway_kyc_required403Identity verification is not complete.
custom_gateway_store_ineligible403A template or dev store cannot collect real payments.
custom_gateway_not_verified409No provider account has been verified yet.
custom_gateway_not_configured404The provider's keys have not been saved.
custom_gateway_verification_failed422The saved keys did not pass the verification round-trip.

Providers

ProviderStatus
PaystackLive. Also the provider a merchant can connect as their own account.
Bank transfer, cashLive, confirmed manually by the merchant.
Flutterwave, Bachs, Nomba, StripeRegistered, not yet available.

Which methods a given store offers is the merchant's setting and can change without notice. Read data.payment_method on the order rather than assuming a provider.

On this page