Hosted Checkout

Integrate Hesabe's payment gateway directly into your website with our embedded checkout solution. Provide customers with a smooth, secure payment experience while maintaining complete control over the user journey.

Implementation Steps

Experience the embedded checkout in action

Get a hands-on view of how the embedded checkout flow works.

This demonstration allows you to understand the user journey, explore available payment options, and see how transactions are processed seamlessly with in your application

View Embedded Checkout demo Click here

Apple Pay Setup

Before using Apple Pay with embedded checkout, you must complete all the apple pay integration steps

If you do not wish to include Apple Pay, Skip Steps [ 2 - 5 ] and move directly to Step 6

Enable Apple Pay Payment Gateway Service With Hesabe

Request Support Team To Enable Payment Gateway Service With Apple Pay

Contact Hesabe Merchant Support Team:support@hesabe.com

Verfiy your domain with Hesabe Payment Gateway

Request domain whitelisting and Apple verification setup

Contact Hesabe IT Team:itsupport@hesabe.com

Once whitelisted, Hesabe will provide an Apple Domain Verification File

This file needs to be added on your website’s hosting server in the following path:

Domain Verification File Path

[MerchantWebsite]/.well-known/apple-developer-merchantid-domain-association.txt

Include Hesabe SDK Script

Add the Hesabe embedded payment script to your HTML header:

checkout.html
<script src="https://unpkg.com/@hesabe-pay/embedded-hosted-checkout@latest/cdn/hesabe-payments.min.js"> </script>

Create Payment Container

Add a div element with the required ID where the payment form will be rendered:

checkout.html
 <div id="hesabe-payments"></div>

Important Note

Keep the ID exactly as "hesabe-payments" - this is required for proper initialization.

Create Checkout Request

Prepare your payment data and send an encrypted POST request to the Hesabe checkout endpoint:

Refer Hesabe Checkout API Guides

You can follow the Hesabe Request Handler guide to get started.

Sample Payload

checkout.html
 let data = {
    merchantCode: '842217',           // Sandbox merchant code
    amount: 2,                        // Payment amount (numeric)
    paymentType: 0,                   // Always 0 for embedded checkout
    responseUrl: 'https://sandbox.hesabe.com/customer-response?id=842217',
    failureUrl: 'https://sandbox.hesabe.com/customer-response?id=842217',
    version: 3.0,                     // API version (always 3.0)
    orderReferenceNumber: '0494994949', // Your order reference
    currency: 'KWD',                  // Currency code (always KWD)
    embeddedPayment: 'true'           // Enable embedded mode
};

// Continue next steps -  Refer example below

Here's an checkout transaction parameters details

FieldTypeDescriptionRequired
amount
NumericTotal amountYes
responseUrl
AlphanumericRedirect URL on successYes
failureUrl
AlphanumericRedirect URL on failureYes
merchantCode
NumericAssigned by HesabeYes
version
Alphanumeric3.0Yes
orderReferenceNumber
StringYour reference / order IDYes
paymentType
Numeric0 - ( Embedded Checkout )Yes
embeddedPayment
BooleantrueYes
currency
StringKWDYes

Additional Checkout API Parameters

Optional parameters that allow you to include extra data or customize the checkout flow in your API request

FieldTypeDescriptionRequired
name
StringCustomer NameOptional
mobile_number
Numeric (8)Customer Mobile Number ( Without country code )Optional
email
StringCustomer Email AddressOptional
webhookUrl
StringYour endpoint for receiving payment statusOptional
variable1
AlphanumericCustom user parameter which will be included in the response when it returnsOptional
variable2
AlphanumericCustom user parameter which will be included in the response when it returnsOptional
variable3
AlphanumericCustom user parameter which will be included in the response when it returnsOptional
variable4
AlphanumericCustom user parameter which will be included in the response when it returnsOptional
variable5
StringCustom user parameter which will be included in the response when it returnsOptional

Read more about Hesabe Webhook URL

You can follow the Hesabe Webhook Request guide to get started.

Sample API Response

After sending the encrypted request, you'll receive a response and make sure to decrypt it to get the session token

 {
    "status": true,
    "code": 200,
    "message": "Authentication success!",
    "response": {
        "data": "eyJkYXRhIjoiOWU1YTk2MGRlOWE1YzlhYmI0M2ZhZDUyMmZhYjU..."
    }
}

The response.data field contains session token needed for payment initialization.

Initialize Payment Form

Configure and initialize the Hesabe payment form with the session token:

checkout.html
const paymentResult = (result) => {
    console.log(result && result.status , "status")
    console.log(result && result.method , "method")
    console.log(result && result.data,'transaction result data'); 
}

let config = {
    environment: "sandbox",           // "sandbox" or "production"
    paymentTypes: ["knet","card","applepay"], // Available payment methods
    sessionID: response.data,         // Session token from API response
    debug: true,                      // Set to false in production
    callback: paymentResult           // Optional: callback function
};

hesabePayment.init(config);

Configuration Parameters

Initialize the Hesabe payment form with following parameters

FieldTypeDescriptionRequired
environment
String"sandbox" or "production"Yes
paymentTypes
Array["knet","card","applepay"]Yes
sessionID
StringSession token from checkout API responseYes
debug
Booleantrue in development, false in productionYes
callback
AlphanumericFunction to handle payment results. If you are not passing callback, users are redirected to your Success or Failure URLsOptional

Payment Method Limitations

KNET and AMEX Redirect Behavior

These payment methods do not support embedded payments and will redirect customers to external pages

Card and Apple Pay Callback Support

These methods support embedded payments and return results through callbacks.

Without a callback, users are redirected to your specified Success or Failure URLs

For Any Technical Assistance

If you encounter any issues or need support during setup or integration, please contact our technical team for assistance.

Hesabe IT Support

Email address:itsupport@hesabe.com

Complete Implementation Example

Here is the sample HTML for Embedded Payments

demo.html
  <!DOCTYPE html>
  <html lang="en">
  <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">

      <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.6.0/axios.min.js"></script>

      <!-- Include your Hesabe Script -->
      <script src="https://unpkg.com/@hesabe-pay/embedded-hosted-checkout@latest/cdn/hesabe-payments.min.js"></script>

      <title>Checkout - Your Order</title>

      <style>
          /* Reset and base styles */
          * {
              margin: 0;
              padding: 0;
              box-sizing: border-box;
          }

          body {
              font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
              min-height: 100vh;
              line-height: 1.6;
              color: #333;
              padding: 1 !important;
          }

          .container {
              max-width: 1350px;
              margin: 0 auto;
              padding: 10px;
          }

          /* Header */
          .checkout-header {
              text-align: center;
              margin-bottom: 40px;
              background: rgba(255, 255, 255, 0.95);
              padding: 30px;
              border-radius: 15px;
              backdrop-filter: blur(10px);
              box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
          }

          .checkout-header h1 {
              color: #2c3e50;
              font-size: 2.5rem;
              font-weight: 700;
              margin-bottom: 10px;
          }

          .checkout-header p {
              color: #7f8c8d;
              font-size: 1.1rem;
          }

          /* Main content layout */
          .checkout-content {
              display: flex;
              gap: 30px;
              align-items: flex-start;
          }

          .col-6 {
              flex: 1;
              min-height: 500px;
              width: 50%;
          }
          /* Cart Items Styles */
          .cart-item {
              display: flex;
              align-items: center;
              padding: 20px 0;
              border-bottom: 1px solid rgba(0, 0, 0, 0.1);
              transition: all 0.3s ease;
          }

          .cart-item:hover {
              background: rgba(52, 152, 219, 0.05);
              border-radius: 10px;
              padding: 20px 15px;
          }

          .cart-item:last-child {
              border-bottom: none;
          }

          .item-image {
              margin-right: 15px;
              flex-shrink: 0;
          }

          .item-image img {
              width: 80px;
              height: 80px;
              object-fit: cover;
              border-radius: 10px;
              box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
          }

          .item-details {
              flex: 1;
              margin-right: 15px;
          }

          .item-details h3 {
              color: #2c3e50;
              font-size: 1.1rem;
              font-weight: 600;
              margin-bottom: 5px;
          }

          .item-description {
              color: #7f8c8d;
              font-size: 0.9rem;
              margin-bottom: 10px;
          }

          .quantity-controls {
              display: flex;
              align-items: center;
              gap: 10px;
          }

          .qty-btn {
              width: 30px;
              height: 30px;
              border: none;
              border-radius: 50%;
              background: #3498db;
              color: white;
              cursor: pointer;
              display: flex;
              align-items: center;
              justify-content: center;
              transition: all 0.3s ease;
              font-weight: 600;
          }

          .qty-btn:hover {
              background: #2980b9;
              transform: scale(1.1);
          }

          .quantity {
              font-weight: 600;
              color: #2c3e50;
              min-width: 20px;
              text-align: center;
          }

          .item-price {
              text-align: right;
              flex-shrink: 0;
          }

          .price {
              font-size: 1.2rem;
              font-weight: 700;
              color: #27ae60;
          }

          /* Order Summary */
          .order-summary {
              margin-top: 25px;
              padding-top: 20px;
              border-top: 2px solid rgba(0, 0, 0, 0.1);
          }

          .summary-row {
              display: flex;
              justify-content: space-between;
              margin-bottom: 10px;
              font-size: 1rem;
          }

          .summary-row.total {
              font-size: 1.3rem;
              font-weight: 700;
              color: #2c3e50;
              margin-top: 15px;
              padding-top: 15px;
              border-top: 2px solid #3498db;
          }

          /* Callback Status Display */
          .callback-status {
              position: fixed;
              top: 20px;
              right: 20px;
              padding: 15px 20px;
              border-radius: 8px;
              color: white;
              font-weight: 600;
              z-index: 1000;
              max-width: 400px;
              word-wrap: break-word;
          }

          .callback-status.success {
              background: #27ae60;
          }

          .callback-status.error {
              background: #e74c3c;
          }

          .callback-status.cancelled {
              background: #f39c12;
          }

          .callback-status.timeout {
              background: #9b59b6;
          }

          /* Debug Console */
          .debug-console {
              background: #2c3e50;
              color: #ecf0f1;
              padding: 15px;
              border-radius: 8px;
              margin-top: 20px;
              font-family: 'Courier New', monospace;
              font-size: 12px;
              max-height: 200px;
              overflow-y: auto;
          }

          .debug-console h3 {
              color: #3498db;
              margin-bottom: 10px;
          }

          .debug-log {
              margin-bottom: 5px;
          }

          .debug-log.error {
              color: #e74c3c;
          }

          .debug-log.success {
              color: #27ae60;
          }

          .debug-log.warning {
              color: #f39c12;
          }

          @media (max-width: 768px) {
              .checkout-content {
                  flex-direction: column;
                  gap: 20px;
              }
              
              .checkout-header h1 {
                  font-size: 2rem;
              }
              
              
              .callback-status {
                  position: relative;
                  top: auto;
                  right: auto;
                  margin-bottom: 20px;
              }
          }
          .cart-section{
              width: 100% !important;
          }
          .payment-section{
              width: 100% !important;
          }
      </style>
  </head>
  <body>
  <div class="container">
  <!-- Header -->
  <header class="checkout-header text-center mb-4">
      <h1>Embedded Demo Checkout</h1>
      <div>Review your order</div>
  </header>

  <!-- Callback Status Display -->
  <div id="callbackStatus" style="display: none;"></div>

  <!-- Checkout Content -->
  <div class="row checkout-content">
      
      <!-- Cart Items Section (Left Column) -->
      <div class="col-sm-12 col-md-6 cart-section">
      <div class="section-card">
          <h2>Order Summary</h2>

          <!-- Cart Item 1 -->
          <div class="cart-item">
          <div class="item-image">
              <img src="https://images.unsplash.com/photo-1505740420928-5e560c06d30e" alt="Premium Wireless Headphones">
          </div>
          <div class="item-details">
              <h3>Premium Wireless Headphones</h3>
              <div class="item-description">Noise-cancelling, Bluetooth 5.0</div>
          </div>
          <div class="item-price">
              <span class="price" id="price-1">45.500 KWD</span>
          </div>
          </div>

          <!-- Cart Item 2 -->
          <div class="cart-item">
          <div class="item-image">
              <img src="https://images.unsplash.com/photo-1523275335684-37898b6baf30" alt="Smart Watch Pro">
          </div>
          <div class="item-details">
              <h3>Smart Watch Pro</h3>
              <div class="item-description">Fitness tracking, GPS enabled</div>
          </div>
          <div class="item-price">
              <span class="price" id="price-2">89.750 KWD</span>
          </div>
          </div>

          <!-- Cart Item 3 -->
          <div class="cart-item">
          <div class="item-image">
              <img src="https://images.unsplash.com/photo-1572569511254-d8f925fe2cbb" alt="Portable HeadPhone">
          </div>
          <div class="item-details">
              <h3>Portable HeadPhone</h3>
              <div class="item-description">Waterproof, 12-hour battery</div>
          </div>
          <div class="item-price">
              <span class="price" id="price-3">20.250 KWD</span>
          </div>
          </div>

          <!-- Order Summary -->
          <div class="order-summary mt-3">
          <div class="summary-row">
              <span>Subtotal:</span>
              <span id="subtotal">155.500 KWD</span>
          </div>
          <div class="summary-row">
              <span>Shipping:</span>
              <span id="shipping">2.500 KWD</span>
          </div>
          <div class="summary-row">
              <span>Tax:</span>
              <span id="tax">7.775 KWD</span>
          </div>
          <div class="summary-row total">
              <span>Total:</span>
              <span id="total">165.775 KWD</span>
          </div>
          </div>
      </div>
      </div>

      <!-- Payment Gateway Section (Right Column) -->
      <div class="col-sm-12 col-md-6 payment-section">
      <div id="hesabe-payments"></div>
      </div>
  </div>

  </div>

  <script>

          // Sample credentials (REPLACE with actual secure ones)
          const secretKey = 'PkW64zMe5NVdrlPVNnjo2Jy9nOb7v1Xg'; // 32 chars for AES-256
          const ivKey = '5NVdrlPVNnjo2Jy9'; // 16 chars for AES
          const accessCode = 'c333729b-d060-4b74-a49d-7686a8353481';
          const environment = 'sandbox'; // or 'production'


          async function fetchMPGSSession() {

              try {

                  let data = {
                      merchantCode: "842217",
                      amount: 165.775,
                      paymentType: 0,
                      responseUrl: 'https://sandbox.hesabe.com/customer-response?id=842217',  // Sandbox URL
                      failureUrl: 'https://sandbox.hesabe.com/customer-response?id=842217', // Sandbox URL
                      version: 2.0,
                      orderReferenceNumber: "08894994949",
                      currency: 'KWD',
                      embeddedPayment: true
                  };

                  let postUrl = environment === 'production' ? 'https://api.hesabe.com/checkout' : 'https://sandbox.hesabe.com/checkout' 

                  console.log("Payload-details", data)

                  console.log("postUrl", postUrl)
                  
                  let encrypted_results = await customHesabeUtils.encrypt(JSON.stringify(data), secretKey, ivKey);

                  const response = await axios.post(postUrl, { data: encrypted_results }, {
                      headers: {
                          accessCode: accessCode,
                          'Content-Type': 'application/json'
                      }
                  });

                  if (response && response.status === 200) {
                      let response_object = response.data;
                      let decrypted_results = await customHesabeUtils.decrypt(response_object, secretKey, ivKey);
                      let data_results = JSON.parse(decrypted_results);

                      if (data_results && data_results.response && data_results.response.data) {
                          let token_data = data_results.response.data;
                          loadConfig(token_data);
                          console.log(data_results)
                      }
                  }
              } catch (error) {
                  console.log(error)
                  let errorMessage = 'Failed to initialize payment form';
                  if (error && error.response) {
                      try {
                          let error_object = error.response.data;
                          let error_message = await customHesabeUtils.decrypt(error_object, secretKey, ivKey);
                          errorMessage = error_message?.response?.message || error_message;
                          console.log('error', "Decrypted error message:", error_message);
                      } catch (decryptError) {
                          console.log('error', "Failed to decrypt error message:", decryptError);
                      }
                  } else {
                      customHesabeUtils.log('error', "Request error:", error);
                      errorMessage = error.message || errorMessage;
                  }
              }
          }

          //Enhanced payment result callback
          const paymentResult = (result) => {
              console.log(result && result.status , "status")
              console.log(result && result.method , "method")
              console.log(result && result.data,'data'); 
          }

          function loadConfig(token_data) {
              let config = {
                  environment: "sandbox", // or "production"
                  paymentTypes: ["knet","card","applepay"],
                  sessionID: token_data,
                  debug: true,
                  // callback: paymentResult //Optional - your callback function
              };
              // Initialize the Hesabe payment form
              hesabePayment.init(config);
          }

          // Initialize when DOM is ready
          document.addEventListener("DOMContentLoaded", async function () {
              await fetchMPGSSession();
          });

      </script>
  </body>
  </html>