Skip to main content

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 currency you 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_id a 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 single transaction_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. See a live breakdown for any amount via preview: true on Create Charge, or read fee_details from any charge response.

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/paystack force-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_details instead of hardcoding a percentage.