Intro
Khaime is a payment orchestrator: you send one charge or session request, and Khaime picks the right gateway for the customer’s currency, converts pricing when needed, and confirms the result over webhooks.Context
Every payment starts with a Create Charge or Create Payment Intent call authenticated with your Partner API key. From there:- Currency and gateway selection is handled by Gateway Routing — the
currencyyou send determines whether Stripe, Paystack, Flutterwave, or StartButton processes the payment. - Cross-currency pricing (merchant prices in one currency, customer pays in another) is handled by Multicurrency, backed by Calculate Pricing and Get Product Pricing.
- Recurring payments layer on top of the same charge/intent request — see Subscriptions.
- Reversals go through Refunds, which acts on the
transaction_ida charge produced. - Outcomes are confirmed over webhooks (
payment.succeeded,payment.failed), and can also be polled on demand via Get Transaction.
Hows
1
Customer selects currency
Via IP auto-detection or manual selection on your storefront.
2
You create a charge
Call
POST /payments/charge with the amount, currency, and customer details. Include the customer’s country when available so fee detection and geography reports stay accurate.3
Khaime routes to a gateway
Khaime picks the gateway for the customer’s payment currency — see Gateway Routing for the exact mapping.
4
Customer pays
Via an embedded Stripe Payment Element, or a redirect to a hosted checkout page (Paystack, Flutterwave, or StartButton), depending on the resolved gateway.
5
Khaime confirms
Webhook
payment.succeeded (or payment.failed) fires with transaction details. You can also call Get Transaction at any time to check current status instead of waiting on the webhook.Gateways in the routing table
You can force
stripe or paystack explicitly via the payment_gateway field on a charge or intent request — Khaime rejects the override if it doesn’t match what the currency would resolve to. Flutterwave and StartButton cannot be forced this way; they’re selected automatically for the currencies above.
Fees
Each transaction carries a singletransaction_fee, calculated as a percentage of the amount plus a small fixed fee. Khaime doesn’t publish a fixed rate here — the exact percentage depends on currency, gateway, and any custom rate agreed for your business, so a hardcoded number would mislead as soon as it stopped matching your business’s actual rate.
Whether the customer or the merchant absorbs this fee is configurable per business (customer_pays_transaction_fee). In a marketplace, it’s the operator’s setting. See a live breakdown for any amount via preview: true on Create Charge, or read fee_details from any charge response.
Show the fee when the customer pays it
When the customer pays the transaction fee, it’s added on top of the price they saw on your product page. Show it as its own line in your order summary, before the customer pays — never fold it silently into the total.
This is best practice for three reasons:
- Trust. A total that’s higher than the advertised price, with no explanation, looks like a hidden charge and gives customers a reason to abandon the payment.
- Fewer disputes. A customer who didn’t knowingly agree to a fee is more likely to raise a chargeback against it.
- Consumer protection. Rules in many markets require the full price, including mandatory fees, to be shown before the customer commits.
- Read the fee from Khaime, don’t compute it. Rates depend on currency, gateway, and any custom rate for the business. Each intent response returns the exact amount — see the field names on Create Payment Intent, Create Product Payment Intent, Create Payment Session and Create Charge.
- Show it before the pay button. Use preview mode (
preview: trueon/payment/intent, or Preview Payment for catalog carts) to render the breakdown while the customer is still reviewing their order. Prices, Fees and Totals lists which call to use at each checkout step. - Make the total match the charge. The total you display must equal the
amountKhaime returns — that’s what the customer’s card or bank will show. - Label it plainly, e.g. “Transaction fee” or “Processing fee”, in the same currency as the rest of the summary.
- Hide the line when the merchant absorbs the fee. Then the price is the total, and showing a fee the customer doesn’t pay would only confuse them.
Whys
Khaime sits between your integration and the gateways so you don’t have to hold merchant accounts, API credentials, or compliance relationships with Stripe, Paystack, Flutterwave, and StartButton individually. You send currency and amount; Khaime resolves the rest — which gateway, which checkout flow, what the fee is — consistently across regions. Confirmation happens over webhooks rather than a required polling response because gateway confirmation (card 3DS, redirect completion, bank processing) is inherently asynchronous — a synchronous “did it work” response would either block on slow gateways or lie about final status. Get Transaction exists alongside webhooks for cases where your integration also wants to check status on demand.Why nots
- You cannot pick an arbitrary gateway per request — routing follows currency, with
stripe/paystackforce-override only. - The platform fee model is currency-based and centrally configured — it is not a per-charge negotiable field. Custom merchant fee rates exist but are configured on the business, not passed in the request, and are not published in these docs for that reason — always read
fee_detailsinstead of hardcoding a percentage.
