Developer guide

Integrating a payment gateway in Qatar: a developer’s guide

Updated September 2026

Most payment integrations fail in the same four places: the redirect back from 3-D Secure, the webhook nobody verified, the duplicate charge from a retried request, and the currency arithmetic. None of them are Qatar-specific, but all of them cost you real money in Qatari Riyal.

This guide is the shape of a payment integration, what each model costs you in effort, and the things worth getting right the first time.

Three integration models

Unless you have a specific reason and the compliance appetite to match, embedded checkout is the right default for most businesses. You keep your checkout design and you keep card data out of your systems.

ModelHow it worksTrade-off
Hosted checkoutYou redirect the customer to the provider’s page and they come back after payingFastest to ship and the lightest compliance burden; least control over the look
Embedded checkoutThe provider’s component renders inside your page, card data never touches your serverYour branding, most of the compliance benefit; a little more front-end work
Server-to-serverYour backend posts the payment request directly to the provider’s APIFull control; you take on far more compliance scope and 3-D Secure handling

The flow, end to end

  • Your server creates an order or payment session with the amount, currency and a reference of your own
  • The provider returns a session identifier or a redirect URL
  • The customer authenticates: 3-D Secure for cards, an approval in a banking or wallet app for local methods
  • The customer is returned to your success or failure URL
  • Separately, the provider sends a webhook to your server with the authoritative result
  • Your server verifies the webhook and only then marks the order paid

The redirect back to your site is a convenience for the customer, not a source of truth. A customer who closes the tab after paying never hits your success URL. Treat the webhook, or a server-side status call, as the only thing that can mark an order paid.

Webhooks: verify, then act

A webhook endpoint is a public URL that anyone on the internet can POST to. If you act on the body without verifying it, you have built a way for strangers to mark orders paid.

A typical scheme sends a timestamp and a signature computed over the timestamp and the raw request body using a shared secret. Three rules follow from that, and they are the ones most often broken:

  • Compute the signature over the RAW body bytes, before any JSON parsing or re-serialisation. Re-encoding changes whitespace and key order, and your signature will never match.
  • Compare signatures with a constant-time comparison, not string equality
  • Reject webhooks with an old timestamp so a captured request cannot be replayed later

Idempotency and duplicate charges

Networks time out. Your customer double-clicks. Your own retry logic fires. Any of these can send the same payment request twice, and without protection the customer is charged twice.

Two defences, and you want both. On the way out, send an idempotency key with each payment request, derived from your own order reference, so the provider recognises a repeat and returns the original result instead of creating a second charge. On the way in, make webhook handling idempotent: store the event identifier and ignore one you have already processed. Webhooks are delivered at least once, not exactly once, so duplicates are normal traffic, not an error.

Working in Qatari Riyal

  • Never hold money in a floating point type. Use integer minor units or a decimal type all the way through.
  • Decide once where rounding happens, and apply it in one place. Rounding in both the cart and the payment request is how a one-baisa mismatch becomes a failed reconciliation.
  • Send the currency code explicitly on every request rather than relying on an account default
  • Show the customer the total in QAR, including delivery and any fees, before the payment step. This is also what underwriting looks for.
  • If you display prices in another currency for convenience, be explicit about which currency will actually be charged.

Model the states properly

The most common data-modelling mistake is a boolean called paid. Payments are a state machine, and the intermediate states are where the money is. At minimum you need: created, pending customer action, authorised, captured or settled, failed, refunded, and partially refunded.

Pending deserves particular care. A local payment method waiting on a customer approval in their banking app can sit in pending for minutes. Pending is not failure, and it is not success. Do not release goods on it, and do not cancel the order because of it. Reconcile it against the provider on a schedule and let it resolve.

Testing before you go live

  • Use the provider’s test environment with test credentials, never live keys, and never a real card to “just check”
  • Test the failure paths, not only the happy path: a declined card, an abandoned 3-D Secure step, a customer who closes the tab after paying
  • Replay a webhook to confirm your handler is idempotent
  • Send a webhook with a bad signature and confirm you reject it
  • Test a partial refund, not only a full one
  • Confirm your reconciliation report matches the provider’s settlement file for a full day before you launch

What Rapid Gateway gives you

Rapid Gateway provides hosted and embedded checkout, a test mode with separate keys so you can exercise the whole flow without moving real money, signed webhooks, and a merchant portal that shows transactions, settlements and refunds with exports for reconciliation.

If you are integrating from Qatar, apply and tell us what you are building. Onboarding includes integration help rather than a link to a documentation site.

Frequently asked questions

Should I use hosted or embedded checkout?

Embedded checkout is the right default for most businesses: you keep your own checkout design while card data stays out of your systems. Hosted checkout is fastest to ship. Server-to-server gives full control but takes on substantially more compliance scope.

Why should I not trust the redirect back from the payment page?

Because a customer who pays and then closes the tab never reaches your success URL. The webhook, or a server-side status check, is the only authoritative result. The redirect is a convenience for the customer.

How do I verify a payment webhook?

Compute the signature over the raw request body bytes, before any JSON parsing, using the shared secret and the supplied timestamp. Compare with a constant-time comparison and reject old timestamps so a captured request cannot be replayed.

How do I avoid double charging a customer?

Send an idempotency key derived from your own order reference with each payment request, and make your webhook handler idempotent by storing processed event identifiers. Webhooks are delivered at least once, so duplicates are normal.

What does a pending payment mean?

It usually means the customer has been asked to approve the payment in their banking or wallet app and has not finished yet. It is neither success nor failure. Do not release goods and do not cancel; reconcile it against the provider until it resolves.

Does Rapid Gateway have a test mode?

Yes. Test mode uses separate keys so you can run the full flow, including webhooks and refunds, without moving real money.

Build against a gateway with humans behind it

Apply now and get sandbox access, API keys and integration help as part of onboarding.

Get started