Payment sessions
Create sessions that keep payment data out of query strings
Kashier's payment sessions make transactions more secure and efficient. With a single API call, you can create payments without exposing sensitive data in query strings, and session history tracking lets you monitor every action in real time. This page walks through creating a session, sending the customer to pay, and confirming the result.
Step 1: Create a payment session
| Endpoint | Value |
|---|---|
| TEST-URL | https://test-api.kashier.io/v3/payment/sessions |
| LIVE-URL | https://api.kashier.io/v3/payment/sessions |
| Method | POST |
curl --location 'https://test-api.kashier.io/v3/payment/sessions' \
--header 'Authorization: YOUR_TEST_SECRET_KEY' \
--header 'api-key: YOUR_TEST_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"expireAt": "2030-01-28T17:27:32.359Z",
"maxFailureAttempts": 3,
"paymentType": "credit",
"amount": "100.00",
"currency": "EGP",
"order": "8f64saf6sa4",
"merchantRedirect": "https://your-website.com/redirect",
"display": "en",
"type": "one-time",
"allowedMethods": "card,wallet",
"redirectMethod": null,
"iframeBackgroundColor": "#FFFFFF",
"metaData": {
"customKey": "customValue",
"displayNotes": {"key": "value"}
},
"merchantId": "MID-XXXX-XXX",
"failureRedirect": false,
"brandColor": "#FF5733",
"defaultMethod": "card",
"description": "Payment for order ORD123456",
"manualCapture": false,
"customer": {
"email": "[email protected]",
"reference": "894321"
},
"saveCard": "optional",
"retrieveSavedCard": true,
"interactionSource": "ECOMMERCE",
"enable3DS": true,
"serverWebhook": "https://your_webhook_url",
"notes": "Special handling required"
}'Two values to fill in before you send
merchantId is required and the panel cannot guess it. Save your test merchant ID next to your keys in the banner above and it is substituted into the MID-XXXX-XXXX placeholder automatically. Until you do, the panel treats the placeholder as an unfilled parameter and keeps Send disabled rather than firing a request the API is certain to reject.
Change order as well. It is your own reference for the payment and Kashier rejects a duplicate order reference for the same merchant (ERR_ORD_02), so leaving the placeholder in place collides with everyone else who left it alone.
Headers
| Key | Description |
|---|---|
| Authorization | The Authorization is a secret key that is used to identify the merchant. You can obtain it from Kashier's dashboard. Learn more about Authorization. |
| api-key | You can obtain your api-key from the merchant dashboard under the Integrations section. Please note that the API key is different for the live and test environments, so make sure to use the correct one for each. |
Full parameter and response reference → Create payment session.
Step 2: Send the customer to pay
Note
sessionUrl is the URL that will be used to redirect the customer to the payment page. You can use it as the src attribute in a link or <iframe>.
The response to the create call includes a sessionUrl. You have two options for getting the customer to it:
- Redirect — send the customer's browser straight to
sessionUrl. Kashier handles the checkout UI and returns them to yourmerchantRedirectURL afterward. - Embed — render
sessionUrlinside your own page in an iframe instead of redirecting away:
<iframe src="https://payments.kashier.io/session/67adc07584f10c00121f6739?mode=test"></iframe>This embed flow was formerly documented as the "Payment UI Builder".
Note
The legacy documentation page hosted an interactive test builder that generated a checkout from the fields below. Use the create payment session call with these fields to build your checkout.
Merchant details
- Merchant ID
- API key
- Secret key
Order details
- Order ID — unique order reference between merchant and Kashier
- Amount
- Currency
Payment method
Select the payment methods to enable:
- Card
- Wallet
- Bank installment
- Buy now pay later
Redirect settings
- Redirect URL
- Redirect method — Get or Post
- Redirect failure — True or False
Display settings
- Display language — English or Arabic
- Display mode — Test or Live
- Brand color — e.g.
#00bcbc
Getting the result out of an embedded checkout
When you embed rather than redirect, the customer never leaves your page, so there is no redirect landing you can read the outcome from. The checkout talks back to the page that hosts it with window.postMessage. Add a message listener on your page and switch on e.data.message.
What you receive depends on how you embedded it.
If you embed with Kashier's checkout script, the script sits between the checkout and your page and re-emits a small, clean set:
e.data.message | Emitted when | What you do |
|---|---|---|
iframeLoaded | The checkout is loaded and its pay button is ready. | Drop your own loading state. |
paymentSuccess | The payment succeeded. | Show your success state. |
iframeHide | The customer closed or dismissed the checkout. | Remove your overlay and re-enable the page. |
urlRedirection | The checkout is ready to return to your redirect URL. | Nothing. The script redirects the top window for you — it builds an auto-submitting form when redirectMethod is post, and otherwise replaces the location. |
If you render sessionUrl in your own <iframe>, as in the snippet above, there is no script in between and you receive the checkout page's own messages directly:
e.data.message | Payload | Meaning |
|---|---|---|
contentLoaded | null | The checkout DOM is ready. |
paymentSuccess | {} | The payment succeeded. |
urlRedirection | { redirectUrl, redirectMethod } | The checkout wants the top window sent to redirectUrl. With no script in between, performing this redirect is your job. |
closeIframe | null | The customer closed the checkout. Tear down your overlay. |
success / failure | Gateway data | Raw card-form outcome callbacks. |
merchantStoreRedirect | Full gateway response plus redirectUrl | The 3DS result coming back from the challenge. |
A minimal listener for the raw-iframe case:
window.addEventListener('message', (e) => {
switch (e.data?.message) {
case 'contentLoaded':
// checkout is ready — hide your spinner
break;
case 'paymentSuccess':
// show a provisional success state, then confirm server-side
break;
case 'closeIframe':
// customer dismissed the checkout — remove your overlay
break;
case 'urlRedirection':
window.location.replace(e.data.params.redirectUrl);
break;
}
});Never treat paymentSuccess as settlement
paymentSuccess arrives from the browser and can be forged, replayed, or simply lost if the customer closes the tab. Confirm every payment server-side — from your webhook or by calling Verify the result — before you release goods. The same goes for the redirect query string, whose signature you must validate.
Test mode only ever offers card and wallet
Outside live mode the checkout ignores allowedMethods and forces the method list to card and wallet. bank_installments, fawry and the rest cannot be exercised in the sandbox at all. So a method working in test tells you nothing about live, and a method being missing in test does not mean your account is misconfigured — verify method availability against your live account.
Step 3: Verify the result
| Endpoint | Value |
|---|---|
| TEST-URL | https://test-api.kashier.io/v3/payment/sessions/:sessionId/payment |
| LIVE-URL | https://api.kashier.io/v3/payment/sessions/:sessionId/payment |
| Method | GET |
curl --location 'https://test-api.kashier.io/v3/payment/sessions/:sessionId/payment' \
--header 'Authorization: YOUR_TEST_SECRET_KEY'Headers
| Key | Description |
|---|---|
| Authorization | The Authorization is a secret key that is used to identify the merchant. You can obtain it from Kashier's dashboard. Learn more about Authorization. |
Full parameter and response reference → Get payment session.
Next steps
Webhooks
Get server-to-server notifications instead of polling for the result.
Refunds
Make full or partial refund requests against an order.
Currency conversion
Look up live exchange rates for cross-currency pricing.
Product catalog
Build itemized payment links and checkout pages from products instead of a flat amount.