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
Verfiy your domain with Hesabe Payment Gateway
Request domain whitelisting and Apple verification setup
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
Include Hesabe SDK Script
Add the Hesabe embedded payment script to your HTML header:
<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:
<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
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 belowHere's an checkout transaction parameters details
| Field | Type | Description | Required |
|---|---|---|---|
amount | Numeric | Total amount | Yes |
responseUrl | Alphanumeric | Redirect URL on success | Yes |
failureUrl | Alphanumeric | Redirect URL on failure | Yes |
merchantCode | Numeric | Assigned by Hesabe | Yes |
version | Alphanumeric | 3.0 | Yes |
orderReferenceNumber | String | Your reference / order ID | Yes |
paymentType | Numeric | 0 - ( Embedded Checkout ) | Yes |
embeddedPayment | Boolean | true | Yes |
currency | String | KWD | Yes |
Additional Checkout API Parameters
Optional parameters that allow you to include extra data or customize the checkout flow in your API request
| Field | Type | Description | Required |
|---|---|---|---|
name | String | Customer Name | Optional |
mobile_number | Numeric (8) | Customer Mobile Number ( Without country code ) | Optional |
email | String | Customer Email Address | Optional |
webhookUrl | String | Your endpoint for receiving payment status | Optional |
variable1 | Alphanumeric | Custom user parameter which will be included in the response when it returns | Optional |
variable2 | Alphanumeric | Custom user parameter which will be included in the response when it returns | Optional |
variable3 | Alphanumeric | Custom user parameter which will be included in the response when it returns | Optional |
variable4 | Alphanumeric | Custom user parameter which will be included in the response when it returns | Optional |
variable5 | String | Custom user parameter which will be included in the response when it returns | Optional |
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:
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
| Field | Type | Description | Required |
|---|---|---|---|
environment | String | "sandbox" or "production" | Yes |
paymentTypes | Array | ["knet","card","applepay"] | Yes |
sessionID | String | Session token from checkout API response | Yes |
debug | Boolean | true in development, false in production | Yes |
callback | Alphanumeric | Function to handle payment results. If you are not passing callback, users are redirected to your Success or Failure URLs | Optional |
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
Complete Implementation Example
Here is the sample HTML for Embedded Payments
<!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>