curl -X POST https://api.khaime.com/api/v1/payments/sessions \
-H "X-API-Key: pk_sandbox_your_key" \
-H "Content-Type: application/json" \
-d '{
"product_id": 501,
"currency": "USD",
"customer": {
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Doe"
}
}'
curl -X POST https://api.khaime.com/api/v1/payments/sessions \
-H "X-API-Key: pk_sandbox_your_key" \
-H "Content-Type: application/json" \
-d '{
"product_id": 501,
"currency": "USD",
"subscription_frequency_key": "monthly",
"customer": {
"email": "jane@example.com"
}
}'
curl -X POST https://api.khaime.com/api/v1/payments/sessions \
-H "X-API-Key: pk_sandbox_your_key" \
-H "Content-Type: application/json" \
-d '{
"product_id": 501,
"currency": "USD",
"return_type": "url",
"success_url": "https://myapp.com/success",
"cancel_url": "https://myapp.com/checkout",
"customer": {
"email": "jane@example.com"
}
}'
Payments
Create Payment Session
Create a payment session for single-product checkout
POST
/
payments
/
sessions
curl -X POST https://api.khaime.com/api/v1/payments/sessions \
-H "X-API-Key: pk_sandbox_your_key" \
-H "Content-Type: application/json" \
-d '{
"product_id": 501,
"currency": "USD",
"customer": {
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Doe"
}
}'
curl -X POST https://api.khaime.com/api/v1/payments/sessions \
-H "X-API-Key: pk_sandbox_your_key" \
-H "Content-Type: application/json" \
-d '{
"product_id": 501,
"currency": "USD",
"subscription_frequency_key": "monthly",
"customer": {
"email": "jane@example.com"
}
}'
curl -X POST https://api.khaime.com/api/v1/payments/sessions \
-H "X-API-Key: pk_sandbox_your_key" \
-H "Content-Type: application/json" \
-d '{
"product_id": 501,
"currency": "USD",
"return_type": "url",
"success_url": "https://myapp.com/success",
"cancel_url": "https://myapp.com/checkout",
"customer": {
"email": "jane@example.com"
}
}'
Intro
Create a payment session for a single product in your Khaime catalog. Returns atoken for embedded checkout or a payment_url for redirect-based checkout.
| Response Field | Use Case |
|---|---|
token | Pass to <KhaimeCheckout /> for embedded checkout |
payment_url | Redirect users to Khaime-hosted checkout page |
POST /payments/sessions and POST /payments/intents are aliases — both work for single-product checkout. For multi-item carts, use Create Payment Intent instead.Context
Use this endpoint for single-product catalog-backed checkout. For different use cases, see:| Use Case | Endpoint |
|---|---|
| Single product purchase | This endpoint (/payments/sessions) |
| Multi-item cart (physical products with shipping) | Commerce Payment Intent |
| Multi-item cart (digital products, gift cards) | Commerce Payment Intent |
| Products outside Khaime catalog (WooCommerce, custom) | Create Charge |
Need Multi-Item Cart Checkout?
For carts with multiple products, shipping addresses, or digital product bundles, use the Commerce Payment Intent endpoint which supports
cart arrays and delivery_details.subscription_frequency_key (see Subscriptions).
Payment outcomes are confirmed via webhooks. Do not poll for status.
Request
Request body
integer
required
ID of an existing, published Khaime product owned by your business. Must match your API key’s environment (sandbox key → sandbox products, live key → live products).
string
required
3-letter ISO currency code the customer pays in (e.g.,
USD, NGN, EUR).integer
Override amount in smallest currency unit (cents/kobo). If omitted, the product’s catalog price is used.
object
required
string
Set to make this a recurring payment (e.g.,
monthly, yearly). See Subscriptions for valid keys.string
Alternative to
subscription_frequency_key when the product has named plans configured.object
{ "enabled": true } takes only the first installment of a product sold in installments and opens an installment plan. The response is then the Installment Checkout response instead of a session. See Installments.string
Set to
"url" to receive only a redirect URL instead of a token. Default returns a token for embedded checkout.string
Where the customer lands after completing payment via redirect flow.
string
Redirect URL if the customer abandons the payment.
object
Custom key-value pairs attached to the payment.
Response
{
"success": true,
"message": "Payment intent created successfully",
"data": {
"intent_id": "intent_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"token": "eyJpbnRlbnRfaWQiOiJpbnRlbnRfYTFiMmMzZDQt...",
"payment_url": "https://pay.khaime.com/checkout?data=eyJhbW91bnQ...",
"expires_at": "2026-01-16T22:00:00.000Z",
"amount": 5320,
"currency": "USD",
"status": "pending",
"payment_type": "one_time",
"fee_details": {
"base_product_price": 5000,
"transaction_fee": 320,
"total_amount": 5320,
"customer_pays_fees": true,
"is_international": false
},
"product": {
"id": 501,
"title": "Premium Plan",
"description": "Monthly premium access",
"type": "digital"
},
"customer": {
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Doe"
}
}
}
Accepting Payments
Once you receive thetoken from the API, you need to render a payment form for your customer. There are two ways to do this:
Option 1: Embedded Checkout (Recommended)
Embed the checkout directly in your app for the best user experience. Your customers stay on your site throughout the payment flow.1
Install @khaime/react
Install the Khaime React SDK in your project:
npm install @khaime/react
yarn add @khaime/react
pnpm add @khaime/react
See the full React SDK documentation for detailed setup instructions and all available options.
2
Render the Checkout Component
Import
KhaimeCheckout and pass the token from the API response:import { KhaimeCheckout } from '@khaime/react';
function CheckoutPage({ token }) {
return (
<KhaimeCheckout
token={token}
onSuccess={(result) => {
console.log('Payment successful!');
window.location.href = '/order-confirmation';
}}
onError={(error) => {
console.error('Payment failed:', error.message);
}}
/>
);
}
3
Handle the Result
The
onSuccess callback is called when payment completes. Use it to redirect to a confirmation page or update your UI.onSuccess={(result) => {
// result.success is true
// Redirect or show confirmation
router.push('/thank-you');
}}
Always verify the payment on your backend via webhooks before fulfilling orders. The frontend callback is for UI purposes only.
Full Example
import { KhaimeCheckout } from '@khaime/react';
import { useState, useEffect } from 'react';
export default function CheckoutPage() {
const [token, setToken] = useState<string | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
// Call your backend to create a payment intent
fetch('/api/create-checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
productId: 501,
currency: 'USD',
}),
})
.then((res) => res.json())
.then((data) => {
setToken(data.token);
setLoading(false);
})
.catch((err) => {
setError('Failed to load checkout');
setLoading(false);
});
}, []);
if (loading) return <div>Loading checkout...</div>;
if (error) return <div>{error}</div>;
if (!token) return <div>Something went wrong</div>;
return (
<div className="max-w-md mx-auto p-6">
<h1 className="text-2xl font-bold mb-6">Complete Your Purchase</h1>
<KhaimeCheckout
token={token}
onSuccess={(result) => {
window.location.href = '/thank-you';
}}
onError={(error) => {
alert(error.message);
}}
/>
</div>
);
}
React SDK Reference
See all available props and customization options for
KhaimeCheckoutOption 2: Redirect Checkout
If you don’t want to embed the checkout, redirect your customer to Khaime’s hosted checkout page.// Simply redirect to the payment_url from the API response
window.location.href = response.data.payment_url;
pay.khaime.com and be redirected back to your success_url when done.
For redirect checkout, make sure to set
success_url and cancel_url in your API request so the customer returns to your site after payment.Response Fields
| Field | Type | Description |
|---|---|---|
intent_id | string | Khaime’s identifier for this payment session. |
token | string | Opaque token for embedded checkout. Pass directly to @khaime/react. |
payment_url | string | Khaime-hosted checkout page URL for redirect flow. |
expires_at | string | Session expires 30 minutes from creation. |
amount | integer | Total amount in smallest currency unit. |
currency | string | Currency code. |
fee_details | object | Breakdown of product price and transaction fees. |
Showing the fee to the customer
Whenfee_details.customer_pays_fees is true, the transaction fee is added to what the customer pays. If you render your own order summary, show fee_details.transaction_fee as a separate line before the customer pays, with fee_details.total_amount (equal to amount) as the total. It’s best practice for transparency — see Fees. When customer_pays_fees is false, the merchant absorbs the fee: show the product price as the total and no fee line.
Error Codes
| Status | Error Code | Cause |
|---|---|---|
422 | VALIDATION_FAILED | Schema validation failed (missing required fields, invalid values). |
400 | VALIDATION_MISSING_FIELD | product_id, currency, or customer.email missing. |
404 | PRODUCT_NOT_FOUND | Product doesn’t exist or doesn’t match your API key’s environment. |
400 | PAYMENT_CURRENCY_UNSUPPORTED | Currency isn’t supported. |
400 | PAYMENT_INTENT_FAILED | Error during session creation. |
Confirming Payment Status
Never trust frontend callbacks alone for order fulfillment. Always verify payments server-side.
- Listen for
payment.succeededandpayment.failedevents - Verify the webhook signature
- Fulfill the order or handle the failure
curl -X POST https://api.khaime.com/api/v1/payments/sessions \
-H "X-API-Key: pk_sandbox_your_key" \
-H "Content-Type: application/json" \
-d '{
"product_id": 501,
"currency": "USD",
"customer": {
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Doe"
}
}'
curl -X POST https://api.khaime.com/api/v1/payments/sessions \
-H "X-API-Key: pk_sandbox_your_key" \
-H "Content-Type: application/json" \
-d '{
"product_id": 501,
"currency": "USD",
"subscription_frequency_key": "monthly",
"customer": {
"email": "jane@example.com"
}
}'
curl -X POST https://api.khaime.com/api/v1/payments/sessions \
-H "X-API-Key: pk_sandbox_your_key" \
-H "Content-Type: application/json" \
-d '{
"product_id": 501,
"currency": "USD",
"return_type": "url",
"success_url": "https://myapp.com/success",
"cancel_url": "https://myapp.com/checkout",
"customer": {
"email": "jane@example.com"
}
}'
Notes
/payments/sessionsand/payments/intentsare aliases for the same endpoint.- This endpoint is for single-product purchases only. For multi-item carts (physical or digital), use Create Payment Intent.
- For products outside Khaime’s catalog, use Create Charge instead.
- Payment sessions expire after 30 minutes.
- Always verify payments via webhooks before fulfilling orders.
Related
Commerce Payment Intent
Multi-item cart checkout with shipping and digital products
Digital Cart Checkout
Guide for digital product multi-item carts
