Skip to main content

πŸ’³ Embedded Hosted Checkout

πŸ’³

Embedded Hosted Checkout

Seamless payment integration without redirects

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.

🎯

Live Demo

Experience the embedded checkout in action

Apple Pay Setup Required

Before using Apple Pay with embedded checkout, you must complete the domain verification process:

Request domain whitelisting and Apple verification setup:

πŸ“§Contact:itsupport@hesabe.com

Request to whitelist your merchant domain for Apple Pay integration

βœ… Once whitelisted, Hesabe will provide an Apple Domain Verification Value

πŸ“„Domain Verification File Path:

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

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

πŸš€ Implementation Steps​

πŸ”Security Note:

All payment data must be encrypted using Hesabe's encryption library before sending to the API endpoint. Make sure to store merchant credentials like ivkey, secret key, accessCode, merchant code in environment variables

1

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>
2

Create Payment Container

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

<div id="hesabe-payments"></div>

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

3

Create Checkout Request

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

Sample Checkout 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: 2.0, // API version (always 2.0)
orderReferenceNumber: '0494994949', // Your order reference
currency: 'KWD', // Currency code (always KWD)
embeddedPayment: 'true' // Enable embedded mode
};

// Continue next steps - Refere example below

πŸ“Š API Parameters​

🏷️ ParameterπŸ“ DescriptionRequiredType
merchantCode
Your unique merchant identifier from Hesabeβœ… YesNumeric
amount
Payment amount (must be greater than zero)βœ… YesNumeric
paymentType
Always pass 0 for embedded checkoutβœ… YesNumeric
responseUrl
URL to redirect after successful paymentβœ… YesString [200]
failureUrl
URL to redirect after payment failureβœ… YesString [200]
version
API version (always 2.0)βœ… YesString
orderReferenceNumber
Your internal order reference for trackingβœ… YesString
currency
Currency code (always KWD)βœ… YesString
embeddedPayment
Enable embedded checkout (always 'true')βœ… YesString
webhookUrl
Your endpoint for receiving payment status OptionalString
4

Handle API Response

After sending the encrypted request, you'll receive a response containing the session token:

Sample API Response:
{
"status": true,
"code": 200,
"message": "Authentication success!",
"response": {
"data": "eyJkYXRhIjoiOWU1YTk2MGRlOWE1YzlhYmI0M2ZhZDUyMmZhYjU..."
}
}
βœ…Success Response:

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

5

Initialize Payment Form

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

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

// Payment configuration object
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
};

// Initialize the Hesabe payment form
hesabePayment.init(config);

βš™οΈ Configuration Parameters​

⚠️

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 URLs.

πŸ”§ ParameterπŸ“„ DescriptionRequiredType
environment
Environment setting: "sandbox" or "production"βœ… YesString
paymentTypes
Array of payment methods: ["knet","card","applepay"]βœ… YesArray
sessionID
Session token from checkout API responseβœ… YesString
debug
Debug mode: true for development, false for productionβœ… YesBoolean
callback
Function to handle payment results. If you are not passing callback, users are redirected to your specified URLs. OptionalFunction

🎨 Payment Interface Preview​

Embedded Payment Options

Hesabe Embedded Payment Options

πŸ“ Complete Implementation Examples​


<!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>
<p>Review your order</p>
</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>
<p class="item-description">Noise-cancelling, Bluetooth 5.0</p>
</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>
<p class="item-description">Fitness tracking, GPS enabled</p>
</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>
<p class="item-description">Waterproof, 12-hour battery</p>
</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>

🎯 Ready to Launch Your Integration​

πŸš€

Transform Your Checkout Experience

Increase conversions with seamless embedded payments

⚑No Page Redirects

Keep customers on your site throughout the entire payment process

🎨Seamless Brand Experience

Maintain your website's look and feel during checkout

🎊 Congratulations!

You've successfully implemented Hesabe's embedded checkout solution. Your customers can now enjoy a smooth, secure payment experience without ever leaving your website.

πŸ’³ Multiple Payment Methods
πŸ”’ Bank-Level Security
πŸ“ˆ Higher Conversions