KashierDevelopersKashier Developers
Direct API integration

Kiosk & cash payments

Basata kiosk codes, Aman installment-at-kiosk, and the generic Cash mark-as-paid operation

Overview

Kashier has three payment methods in this family, each with a different completion mechanism:

MethodpaymentMethod.typeHow it completes
BasatabasataYou generate a payment reference code; the customer pays it at a Basata outlet, and Basata notifies Kashier.
AmanamanThe customer completes an OTP-verified installment purchase through Aman.
CashcashInternal "mark-as-paid" bookkeeping operation — no external provider call, no real-time authorization.

Looking for Contact, valU, Octo, Souhoola, Mogo, Tru, or Forsa?

Those are BNPL/installment providers, not cash or kiosk methods, even though Contact's name suggests otherwise. See Installment plans → BNPL providers.

Basata: generate payment code

Generates a payment code for the Basata payment method.

EndpointValue
TEST-URLhttps://test-fep.kashier.io/v3/orders
LIVE-URLhttps://fep.kashier.io/v3/orders
MethodPOST

Headers

EndpointRequiredValue
Kashier-HashYesHMAC-SHA256 hash calculated based on the path and API key
Content-TypeYesapplication/json
curl --location 'https://test-fep.kashier.io/v3/orders' \
  --header 'Kashier-Hash: your_generated_hash' \
  --header 'Content-Type: application/json' \
  --data '{
  "apiOperation": "GENERATE_CODE",
  "paymentMethod": {
      "type": "BASATA",
      "basata": {
          "mobileNumber": "01001001001"
      }
  },
  "order": {
      "reference": "PM-89451648984",
      "amount": 10.00,
      "currency": "EGP"
  },
  "interactionSource": "ECOMMERCE",
  "reconciliation": {
      "webhookUrl": "https://your-call-back-url.com",
      "merchantRedirect": "https://your-call-back-url.com"
  },
  "merchantId": "MID-XXXXX-XXXX"
}'

Body description

ParameterTypeRequiredDescription
apiOperationStringYesMust be set to 'GENERATE_CODE'
paymentMethod.typeStringYesMust be set to 'BASATA'
paymentMethod.basata.mobileNumberStringYesCustomer's mobile number
order.referenceStringYesUnique order reference ID (can be generated using a timestamp)
order.amountNumberYesTransaction amount
order.currencyStringYesCurrency code (e.g., 'EGP')
interactionSourceStringYesSource of interaction (typically 'ECOMMERCE')
reconciliation.webhookUrlStringYesURL for webhook notifications
reconciliation.merchantRedirectStringYesURL to redirect the customer after the transaction
merchantIdStringYesYour merchant ID provided by Kashier

Response structure

This 00 / SUCCESS means the code was generated, not that the customer paid

GENERATE_CODE does not call Basata at all — Kashier generates the reference code and its expireAt itself on this leg, and the transactionResponseCode: "00" / "Approved" below is produced locally by that generator. The order is created with status INITIATED, not paid. The customer still has to take the reference code to a Basata outlet. Treat the completion webhook (event: pay, status: SUCCESS) as the authoritative "customer has paid" signal — never this response.

{
  "response": {
      "apiOperation": "GENERATE_CODE",
      "operation": "generate_code",
      "currency": "EGP",
      "result": "SUCCESS",
      "status": "SUCCESS",
      "authorizationNumber": "",
      "authentication": {},
      "paymentMethod": {
          "type": "BASATA",
          "basata": {
              "mobileNumber": "01001001001",
              "referenceCode": "21496319",
              "expireAt": "2025-04-06T13:05:45.007Z"
          }
      },
      "metaData": {
          "termsAndConditions": {
              "ip": "156.210.51.26"
          },
          "merchantWebhook": "https://your-website.com/paymentWebhook"
      },
      "reconciliation": {
          "webhookUrl": "https://your-call-back-url.com",
          "merchantRedirect": "https://your-call-back-url.com?&signature=",
          "redirect": false
      },
      "merchantId": "MID-21232-888",
      "order": {
          "amount": 10,
          "currency": "EGP",
          "callbackURL": "https://your-call-back-url.com",
          "systemOrderId": "e5f15beb-c922-42a2-b6ba-015f5a435a20",
          "reference": "test12d34"
      },
      "amount": 10,
      "totalRefundedAmount": 0,
      "totalCapturedAmount": 0,
      "totalAuthorizedAmount": 0,
      "merchantRedirectUrl": "https://your-call-back-url.com?&signature=",
      "apiKeyId": "64e630f515427000134fd486",
      "method": "basata",
      "creationDate": "2025-04-06T14:05:44.981Z",
      "orderId": "e5f15beb-c922-42a2-b6ba-015f5a435a20",
      "provider": "basata",
      "merchantOrderId": "test12d34",
      "orderReference": "TEST-ORD-193390011",
      "interactionSource": "ECOMMERCE",
      "device": {
          "ipAddress": "156.210.51.26"
      },
      "transactionId": "TX-212328882424",
      "transactionResponseCode": "00",
      "transactionResponseMessage": {
          "en": "Approved"
      }
  },
  "messages": {
      "en": "Approved"
  },
  "status": "SUCCESS",
  "showCaptcha": false
}

Key response fields

ParameterDescription
response.resultResult of the operation ('SUCCESS' or error)
response.paymentMethod.basata.referenceCodeThe generated Basata reference code
response.paymentMethod.basata.expireAtExpiration time for the reference code
response.transactionIdUnique transaction ID
response.order.systemOrderIdSystem-generated order ID

Authentication is done via the Kashier-Hash header. The hash is calculated using HMAC-SHA256 with your API key and a specific path format.

Hash calculation

const path = `/?payment=${merchantId}.${order.reference}.${order.amount}.${order.currency}`;
const hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, apikey).update(path);
const hash = hmac.finalize().toString(CryptoJS.enc.hex);

This is the standard payment hash — see Request hashing for the full recipe and the other signed-string forms.

Using the Postman collection

Prerequisites

  • Postman application installed

  • Your Kashier merchant ID

  • Your Kashier API key

Setup

  1. Import the provided Postman collection JSON file

  2. Update the collection variables:

  • merchantId: your merchant ID

  • apikey: your API key

  • The collection already includes pre-defined values for test-fep and live-fep

Execution

  1. Select the "Generate Basata Code" request

  2. The pre-request script will automatically:

  • Generate a unique order reference

  • Create the request body

  • Calculate the authentication hash

  1. Send the request to generate a Basata code

Variables

VariableDescription
test-fepTest environment base URL
live-fepProduction environment base URL
merchantIdYour merchant ID
apikeyYour API key
hashCalculated authentication hash (auto-generated)
paymentRequestJSON request body (auto-generated)

Error handling

The API may return error responses with appropriate HTTP status codes and error messages. Common error scenarios include:

  • Invalid authentication (incorrect hash)

  • Missing required parameters

  • Invalid parameter values

  • System errors

Error responses will include a status field with a value other than "SUCCESS" and detailed error messages.

Aman: installment at kiosk

Aman is an installment-at-kiosk method: instead of a static reference code, the customer completes an OTP-verified installment purchase through Aman. Use paymentMethod.type: "aman" for the order's payment method, the same way you'd use basata or cash.

An Aman payment progresses through five steps, each a separate apiOperation against the order:

StepapiOperationWhat happens
Initiate purchaseinitiate_purchaseStarts the Aman flow for the order.
Send OTPsend_otpAman sends a one-time password to the customer.
PaypayThe customer's OTP is submitted and the purchase completes.
ReconcilereconcileKashier confirms the transaction status with Aman.
RefundrefundReverses a completed Aman transaction.

Aman's purchase result is keyed on Aman's own numeric result code: ResultID === 0 means success, and any other value is a failure. The transactionResponseCode returned to you mirrors that ResultID (or a fallback default code) rather than the standard 00/k_* dictionary used by card and Basata payments.

After a successful pay or reconcile, the order's payment-method data is enriched with the installment details Aman returns:

FieldMeaning
transactionIdAman's transaction reference
cardNumberCard used for the installment
firstInstallmentDateDate of the first installment
lastInstallmentDateDate of the last installment
adminFeesAdministrative fee charged by Aman

As with Basata, treat the completion webhook (event: pay, status: SUCCESS) as the authoritative "customer has paid" signal, not any intermediate response.

Cash: mark-as-paid (synthetic)

paymentMethod.type: "cash" — generic Cash — is not a reference-code rail like Basata, and it makes no external call to any provider. It's an internal bookkeeping operation: submitting a pay request with paymentMethod.type: "cash" debits your merchant balance and immediately writes a transaction with a hard-coded transactionResponseCode: "00" / "Approved" response.

Not a real-time authorization

Cash's SUCCESS response is synthetic — Kashier does not contact any external processor to authorize it. Unlike Basata, Aman, or a card payment, there is no real settlement-risk signal here: a Cash payment request always returns success. Use it only to record a payment you already collected through some other channel — not as a way to accept a real-time cash payment.

Contact and other BNPL providers

Contact (paymentMethod.type: "contact") is not a cash/kiosk method despite the superficial similarity — in Kashier it's a BNPL/installment provider with its own multi-step flow (categories, balance validation, tenure selection, OTP, pay, refund). See Installment plans → BNPL providers for Contact alongside Octo, Souhoola, Mogo, Tru, and Forsa.

On this page