How Payments Work
TakeTheme supports nine payment methods: Cash on Delivery, custom manual methods (bank transfer, wallet, anything you define), and seven online gateways — Kashier, Paymob, PayTabs, PayPal, Stripe, Tabby, and Tamara.
Every gateway connects with your own merchant account. Funds settle directly to you; TakeTheme never holds them. Credentials are stored per store and are never shared between stores.
This page covers the rules that are the same everywhere. The provider pages cover what is specific to each one.
The two checkout flows
Which flow a shopper goes through depends only on the payment method they pick.
Manual flow — COD and custom manual methods
- Shopper submits the checkout.
- The order is created immediately, with payment status Unpaid.
- You collect the money later (courier hands over cash, customer transfers to your bank).
- You mark the order paid from the dashboard.
The order exists from the first moment, so it appears in your Orders list even though nothing has been paid.
Online flow — every gateway
- Shopper submits the checkout.
- TakeTheme creates a payment session at the gateway and redirects the shopper to it. No order exists yet.
- Shopper pays on the gateway's page.
- The gateway calls TakeTheme's webhook. The order is created at this point, already marked Paid.
- Shopper is returned to your store's success page.
This is called deferred order creation, and it has one consequence worth internalising:
If a shopper reaches the gateway and doesn't pay, no order is created — there is nothing to cancel or clean up. Those attempts show up under Abandoned checkouts, not Orders.
Payment statuses
| Status | Meaning |
|---|---|
| Unpaid | No money collected. Normal starting state for COD and manual orders. |
| Authorized | Payment claimed but not confirmed. Only produced by the payment-screenshot flow — you still have to approve it. |
| Paid | Full amount collected. |
| Partially paid | Items were added to an already-paid order, so a balance is outstanding. |
| Partially refunded | Some of the collected amount was refunded. |
| Refunded | The whole collected amount was refunded. |
| Voided | An authorization was released without taking money. |
| Failed | The gateway declined the payment. |
| Expired | The payment session timed out before the shopper paid. |
Payment status is independent of order status, fulfillment status, and delivery status — see Order lifecycle.
Authorize vs. capture
TakeTheme does not offer a manual authorize-then-capture workflow. Every online gateway is configured to capture funds automatically when the shopper completes payment. There is no "capture now" button, and no authorization that expires unclaimed.
The single exception is a manual payment where you asked for a payment screenshot: that lands as Authorized until you approve it.
Refunds
Refunding an order in the dashboard updates the payment record, the order timeline, your analytics, and (optionally) restocks inventory. It does not send money back through the gateway. No refund call is made to Kashier, Paymob, PayTabs, PayPal, Stripe, Tabby, or Tamara.
To actually return the funds, issue the refund in your gateway's own dashboard, then record it in TakeTheme so your reporting matches.
What TakeTheme does enforce:
- Only Paid or Partially refunded payments can be refunded. Unpaid, failed, voided, and already fully-refunded payments are rejected.
- You can never refund more than was collected. The check runs at write time, so two staff members refunding at once cannot both slip through — the second attempt fails.
- Zero and negative amounts are rejected, so a refund can never turn into a charge.
- The same item and quantity cannot be refunded twice.
- Refunding everything sets Refunded; refunding part of it sets Partially refunded.
Each refund records a refund method. Leave it as original to record it against the method the customer paid with, or pick another (for example, refunding a card order as store credit or cash).
Shipping is refunded only when you explicitly tick it, and is recorded separately from the item amounts.
Voids
A void releases an authorization without taking money. It applies only to payments in Authorized state — in practice, manual orders awaiting screenshot approval.
Voids happen in one of two ways:
- You void the payment directly.
- You cancel the order. Cancelling automatically voids an authorized payment. If the order was already paid and you tick "refund remaining amount", the still-captured balance is refunded instead. See Cancellations.
A payment can only be voided once.
Handling fees and order limits
COD and custom manual methods can charge a fee and enforce order-total limits. Both are applied at checkout, before the order is created — a shopper outside the limits cannot place the order at all.
| Setting | COD | Custom manual |
|---|---|---|
| Fee | Fixed amount (COD handling fee) | Fixed or percentage of the total |
| Maximum order total | Maximum COD order amount | Maximum order amount |
| Minimum order total | — | Minimum order amount |
Limits are compared against items + shipping + tax (the total before the handling fee is added). Leave a limit empty for no limit.
If the total is over the maximum, checkout fails with ORDER_TOTAL_EXCEEDS_MAX_ALLOWED_AMOUNT; under the minimum, ORDER_TOTAL_IS_BELOW_MIN_ALLOWED_AMOUNT.
Online gateways have no fee or limit settings.
Currency
Orders are placed in your store currency, set under store settings.
Once a store has at least one order, the currency can no longer be changed (CURRENCY_LOCKED_HAS_ORDERS). Historical orders, analytics, and payment records would otherwise silently change meaning. Set your currency correctly before you go live.
Two gateways have their own currency handling:
- PayTabs carries its own
currencycredential (EGP or SAR) alongside a region. It must match your store currency, or the gateway will reject or convert the charge. - Stripe receives amounts in the smallest unit (cents) and is card-only.
Multiple methods at once
You can enable as many methods as you like — they all appear at checkout, each with its own logo and name (localized into Arabic and French on the storefront).
Custom manual methods are unlimited: create one per bank account, wallet, or offline arrangement, each with its own instructions, fee, and limits.
Settings you'll find on every gateway
| Setting | What it does |
|---|---|
| Send payment confirmation email | Emails the customer when payment is recorded. Active. |
| Notify on payment failures (emails) | Emails the addresses you list when a checkout fails at the gateway. Active. |
| Auto mark orders as paid | Not currently enforced. A confirmed payment webhook always marks the order paid, whether this is on or off. |
Provider-specific settings (environment, saved cards, COD limits) are documented on each provider's page.
Where webhooks arrive
Each gateway confirms payment by calling a TakeTheme endpoint. You normally never touch these — connecting the gateway is enough — but you'll need the URL when a provider dashboard asks you to register one.
| Provider | Endpoint | Signature verified |
|---|---|---|
| Kashier | POST /v1/payment/webhook/kashier | Yes — always |
| Paymob | POST /v1/payment/webhook/paymob | Only if an HMAC secret is configured |
| PayTabs | POST /v1/payment/webhook/paytabs | Yes — always, request rejected otherwise |
| Stripe | POST /v1/webhooks/stripe | Yes, when a webhook secret is set |
| PayPal | POST /v1/webhooks/paypal | Yes, when a webhook ID is set |
| Tabby | — | No endpoint (see BNPL) |
| Tamara | — | No endpoint (see BNPL) |
Webhook deliveries are idempotent: providers retry until they get a 200, and a repeat delivery for an already-successful payment is acknowledged and ignored rather than double-counting revenue or re-creating the order.
Every incoming webhook is logged, so support can tell you whether a provider actually called and what it sent.
Troubleshooting
"I saved my credentials and the gateway stopped working."
Read endpoints mask stored secrets as ••••1234. Retype the full secret when you change it — never edit around the masked value. A value that starts with bullets is treated as "keep the existing one", so a partial edit can leave a stale key in place.
"The shopper paid but there's no order." For online gateways the order is created by the webhook. Check the provider's webhook/IPN configuration first. Contact support with the provider's transaction reference — the incoming webhook log will show whether the call arrived.
"My refund isn't showing in my gateway account." Expected — see Refunds. TakeTheme records the refund; you issue it in the gateway.
"The COD fee isn't being charged." The fee is applied at checkout, so it only affects orders placed after you saved the setting. Existing orders are unchanged.