Preview Payment
curl --request POST \
--url https://api.khaime.com/api/v1/cart-payment/preview \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.khaime.com/api/v1/cart-payment/preview"
headers = {"X-API-Key": "<api-key>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.khaime.com/api/v1/cart-payment/preview', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.khaime.com/api/v1/cart-payment/preview",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.khaime.com/api/v1/cart-payment/preview"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.khaime.com/api/v1/cart-payment/preview")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.khaime.com/api/v1/cart-payment/preview")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"status": true,
"message": "Payment preview calculated successfully",
"data": {
"preview": true,
"currency": "USD",
"cart_subtotal": 5998,
"coupon_discount": 600,
"shipping_cost": 599,
"tax_amount": 432,
"cart_total_before_fees": 6429,
"customer_pays_fees": true,
"total_fees_amount": 175,
"customer_pays_total": 6604,
"business_receives": 6429
}
}
Commerce API
Preview Payment
Preview payment breakdown before creating payment intent
POST
/
cart-payment
/
preview
Preview Payment
curl --request POST \
--url https://api.khaime.com/api/v1/cart-payment/preview \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.khaime.com/api/v1/cart-payment/preview"
headers = {"X-API-Key": "<api-key>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.khaime.com/api/v1/cart-payment/preview', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.khaime.com/api/v1/cart-payment/preview",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.khaime.com/api/v1/cart-payment/preview"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.khaime.com/api/v1/cart-payment/preview")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.khaime.com/api/v1/cart-payment/preview")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"status": true,
"message": "Payment preview calculated successfully",
"data": {
"preview": true,
"currency": "USD",
"cart_subtotal": 5998,
"coupon_discount": 600,
"shipping_cost": 599,
"tax_amount": 432,
"cart_total_before_fees": 6429,
"customer_pays_fees": true,
"total_fees_amount": 175,
"customer_pays_total": 6604,
"business_receives": 6429
}
}
Preview Payment
Returns the exact payment a Create Product Payment Intent request would produce — subtotal, discount, shipping, tax, transaction fee and total — without creating anything. Call it on your review step so the customer sees the final total before they press pay.Send the same body you’ll send to Create Product Payment Intent. Build it once, preview it, then create the intent with it. See Prices, Fees and Totals for where this fits in checkout.
Request
string
required
Your API key
Body
The body is identical to Create Product Payment Intent:product_type, cart, email, first_name, last_name, currency, and for physical products cart_unique_id and delivery_details.
- Don’t send a top-level
product_id— it’s rejected with422. The product comes fromcart. cart_unique_idfrom/cart/validateis only needed for physical products.- Required custom fields are validated, so call it on your review step, once the customer has filled them in.
Response
{
"status": true,
"message": "Payment preview calculated successfully",
"data": {
"preview": true,
"currency": "USD",
"cart_subtotal": 5998,
"coupon_discount": 600,
"shipping_cost": 599,
"tax_amount": 432,
"cart_total_before_fees": 6429,
"customer_pays_fees": true,
"total_fees_amount": 175,
"customer_pays_total": 6604,
"business_receives": 6429
}
}
| Field | Description |
|---|---|
cart_subtotal | Items before discounts |
coupon_discount | Coupon discount applied |
shipping_cost | Shipping charged to the customer |
tax_amount | Tax |
cart_total_before_fees | What the order costs before Khaime’s fee |
customer_pays_fees | true when the transaction fee is added to the customer’s total |
total_fees_amount | Khaime’s transaction fee. Returned whoever pays it. |
customer_pays_total | What the customer will be charged |
business_receives | What the business keeps after fees |
Showing the fee to the customer
Whencustomer_pays_fees is true, show total_fees_amount as its own “Transaction fee” line and customer_pays_total as the total. It’s best practice for transparency — see Fees. When customer_pays_fees is false, the merchant absorbs the fee: don’t show a fee line, because total_fees_amount is still returned but isn’t part of the customer’s total.
For a marketplace sale, whether the customer pays is the operator’s setting, inherited by its sub-merchants.
Use Case
Call this endpoint after/cart/validate to show customers a complete breakdown before they commit to payment:
// 1. Validate cart first
const cartResponse = await fetch('/api/v1/cart/validate', {
method: 'POST',
headers: {
'X-API-Key': apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify({
cart: cartItems,
currency: 'USD',
delivery_details: shippingAddress
})
});
const { cart_unique_id, total } = await cartResponse.json();
// 2. Preview payment breakdown
const previewResponse = await fetch('/api/v1/cart-payment/preview', {
method: 'POST',
headers: {
'X-API-Key': apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify({
product_id: primaryProductId,
cart_unique_id,
email: 'john@example.com',
first_name: 'John',
last_name: 'Doe',
currency: 'USD'
})
});
// 3. Show breakdown to customer before final payment
const preview = await previewResponse.json();
displayPaymentSummary(preview.data);
Errors
| Error Code | Description |
|---|---|
CART_EXPIRED | Cart ID is no longer valid |
CART_NOT_FOUND | Invalid cart ID |
PRODUCT_NOT_FOUND | Product no longer available |
Example
curl -X POST "https://api.khaime.com/api/v1/cart-payment/preview" \
-H "X-API-Key: pk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"product_id": 12345,
"cart_unique_id": "bc59bc1f-e1b0-4ee5-a9cb-b966042ce38f",
"email": "john@example.com",
"first_name": "John",
"last_name": "Doe",
"currency": "USD"
}'
