๐ Quick API Integration Guide for Khalti ePayment Checkout
Khalti provides a seamless ePayment platform that enables merchants to accept digital payments easily. This guide walks you through the quick integration steps for the latest Khalti ePayment Checkout API.
๐ง How It Works
- User visits your website to make a purchase.
- A unique
purchase_order_id
is generated on your backend. - You make a payment initiation request to Khalti with required details.
- User is redirected to the Khalti ePayment portal.
- Upon successful payment, user is redirected back to your
return_url
. - Optionally verify payment using the Payment Lookup API.
- Provide service to the user only after payment is confirmed.
โ๏ธ Getting Started
- โ No SDK required โ just HTTP requests.
- โ Use any language or framework that supports HTTP POST.
- ๐งโ๐ผ You must have a Khalti Merchant Account.
- ๐ Use sandbox credentials for testing.
๐งช Sandbox Login OTP: 987654
๐งช Test Khalti IDs:
9800000000
to 9800000005
๐งช Test MPIN: 1111
๐ API Authorization
All requests require an authorization header:
Authorization: Key <LIVE_SECRET_KEY>
- Use keys from
test-admin.khalti.com
for sandbox - Use keys from
admin.khalti.com
for production
๐ Step 1: Initiate Payment Request
๐ก Endpoint
- Sandbox:
https://dev.khalti.com/api/v2/epayment/initiate/
- Production:
https://khalti.com/api/v2/epayment/initiate/
๐ Request Headers
Authorization: Key <YOUR_SECRET_KEY>
Content-Type: application/json
๐งพ Sample Request Body
{
"return_url": "https://yourwebsite.com/payment/",
"website_url": "https://yourwebsite.com/",
"amount": 1300,
"purchase_order_id": "order001",
"purchase_order_name": "Premium Subscription",
"customer_info": {
"name": "John Doe",
"email": "john@example.com",
"phone": "9800000001"
},
"amount_breakdown": [
{ "label": "Base Price", "amount": 1000 },
{ "label": "VAT", "amount": 300 }
],
"product_details": [
{
"identity": "sku123",
"name": "Subscription Plan",
"total_price": 1300,
"quantity": 1,
"unit_price": 1300
}
]
}
โ Sample Success Response
{
"pidx": "bZQLD9wRVWo4CdESSfuSsB",
"payment_url": "https://test-pay.khalti.com/?pidx=bZQLD9wRVWo4CdESSfuSsB",
"expires_in": 1800
}
๐ Redirect the user to the
payment_url
๐ Step 2: Handle Payment Callback
After user completes or cancels the payment, they will be redirected to your return_url
with these query parameters:
โ Sample Callback URL (Success)
https://yourwebsite.com/payment/?pidx=bZQLD9wRVWo4CdESSfuSsB
&transaction_id=4H7AhoXDJWg5WjrcPT9ixW
&status=Completed
&amount=1300
&purchase_order_id=order001
&purchase_order_name=Premium Subscription
โ Sample Callback URL (Canceled)
https://yourwebsite.com/payment/?status=User canceled
โ Step 3: Verify Payment with Lookup API
๐ก Endpoint
POST /epayment/lookup/
๐ Request
{ "pidx": "bZQLD9wRVWo4CdESSfuSsB" }
๐ Sample Response
{
"status": "Completed",
"transaction_id": "TXN123",
"total_amount": 1300
}
Status | Action |
---|---|
Completed | โ Provide the service |
Pending | ๐ Wait and contact Khalti |
User canceled | โ Do not provide service |
Refunded/Expired | โ Do not provide service |
๐จ Error Handling
๐ Invalid Token
{ "detail": "Invalid token.", "status_code": 401 }
โ Not Found (Wrong PIDX)
{ "detail": "Not found.", "error_key": "validation_error" }
๐งช Test it with cURL
curl --location 'https://dev.khalti.com/api/v2/epayment/initiate/' \
--header 'Authorization: Key <your_test_secret_key>' \
--header 'Content-Type: application/json' \
--data-raw '{
"return_url": "http://example.com/",
"website_url": "http://example.com/",
"amount": 1000,
"purchase_order_id": "order001",
"purchase_order_name": "Test Product",
"customer_info": {
"name": "Test Bahadur",
"email": "test@khalti.com",
"phone": "9800000001"
}
}'
โ Final Tips
- Always verify payments using Lookup API after redirection.
- Do not rely on callback alone.
- Payment links expire after 60 minutes.
- Only process orders with status: Completed.
Happy integrating! ๐ง
Need help? Contact Khalti Support or refer to the official documentation.