KashierDevelopersKashier Developers
Accept payments

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

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

KeyDescription
AuthorizationThe 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-keyYou 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 your merchantRedirect URL afterward.
  • Embed — render sessionUrl inside 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.messageEmitted whenWhat you do
iframeLoadedThe checkout is loaded and its pay button is ready.Drop your own loading state.
paymentSuccessThe payment succeeded.Show your success state.
iframeHideThe customer closed or dismissed the checkout.Remove your overlay and re-enable the page.
urlRedirectionThe 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.messagePayloadMeaning
contentLoadednullThe 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.
closeIframenullThe customer closed the checkout. Tear down your overlay.
success / failureGateway dataRaw card-form outcome callbacks.
merchantStoreRedirectFull gateway response plus redirectUrlThe 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

curl --location 'https://test-api.kashier.io/v3/payment/sessions/:sessionId/payment' \
  --header 'Authorization: YOUR_TEST_SECRET_KEY'

Headers

KeyDescription
AuthorizationThe 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

On this page