Skip to content

Web Checkout (New E-Payment Version)

This documentation details the process of implementing the latest e-Payment Checkout platform released by Khalti.The latest version is accessible through pay.khalti.com

How it works?

  • User visits the merchant's website to make some purchase
  • A unique purchase_order_id is generated at merchant's system
  • Payment request is made to Khalti providing the purchase_order_id, amount in paisa and return_url
  • User is redirected to the epayment portal (eg. https://pay.khalti.com)
  • After payment is made by the user, a successful callback is made to the return_url
  • The merchant website can optionally confirm the payment received
  • The merchant website then proceeds other steps after payment confirmation

Getting Started

There is no special installation plugin or SDK required for this provided you are able to make a POST request from your web application. However, we shall come up with handy plugins in coming days.

A merchant account is required if you haven't created at.

For sandbox access
Signup from https://a.khalti.com/join/merchant/ as a merchant

For Production access
Please visit https://admin.khalti.com

API Authorization

HTTP Authorization for api requests is done using Auth Keys. Auth Key must be passed in the header for authorization in the following format

{
    "Authorization": "Key <LIVE_SECRET_KEY>"  
}  

PS : Use live_secret_key from a.khalti.com during sandbox testing and use live_secret_key from khalti.com for production environments

API Endpoints

Live
https://khalti.com/api/v2/

Sandbox
https://a.khalti.com/api/v2/

Initiating a Payment request

Every payment request should be first initiated from the merchant as a server side POST request. Upon success, a unique request identifier is provided called pidx that should be used for any future references

URL Method Authorization Format
/epayment/initiate/ POST Required application/json

JSON Payload Details

Field Required Description
return_url Yes
  • Landing page after the transaction.
  • Field must contain a URL.
website_url Yes
  • The URL of the website.
  • Field must contain a URL.
amount Yes
  • Total payable amount excluding the service charge.
  • Amount must be passed in Paisa
purchase_order_id Yes Unique identifier for the transaction generated by merchant
purchase_order_name Yes This is the name of the product.
customer_info No This field represents to whom the txn is going to be billed to.
amount_breakdown No Any number of labels and amounts can be passed.
product_details No No of set is unlimited

Sample Request Payload

{
  "return_url": "https://example.com/payment/",
  "website_url": "https://example.com/",
  "amount": 1300,
  "purchase_order_id": "test12",
  "purchase_order_name": "test",
  "customer_info": {
      "name": "Ashim Upadhaya",
      "email": "example@gmail.com",
      "phone": "9811496763"
  },
  "amount_breakdown": [
      {
          "label": "Mark Price",
          "amount": 1000
      },
      {
          "label": "VAT",
          "amount": 300
      }
  ],
  "product_details": [
      {
          "identity": "1234567890",
          "name": "Khalti logo",
          "total_price": 1300,
          "quantity": 1,
   "unit_price": 1300
      }
  ]
}

Success Response

{
   "pidx": "S8QJg2VALZGTJRkKqVxjqB",
   "payment_url": "https://test-pay.khalti.com/?pidx=S8QJg2VALZGTJRkKqVxjqB/"
}

After getting the success response, the user should be redirected to the payment_url obtained in the success response.

Error Responses

return_url is blank

{
   "return_url": [
       "This field may not be blank."
   ],
   "error_key": "validation_error"
}

return_url is invalid

{
   "return_url": [
       "Enter a valid URL."
   ],
   "error_key": "validation_error"
}

website_url is blank

{
   "website_url": [
       "This field may not be blank."
   ],
   "error_key": "validation_error"
}

website_url is invalid)

{
   "website_url": [
       "Enter a valid URL."
   ],
   "error_key": "validation_error"
}

Amount is less than 10

{
   "amount": [
       "Amount should be greater than Rs. 1, that is 100 paisa."
   ],
   "error_key": "validation_error"
}

Amount is invalid

{
   "amount": [
       "A valid integer is required."
   ],
   "error_key": "validation_error"
}

purchase_order_id is blank

{
   "purchase_order_id": [
       "This field may not be blank."
   ],
   "error_key": "validation_error"
}

purchase_order_name is blank

{
   "purchase_order_name": [
       "This field may not be blank."
   ],
   "error_key": "validation_error"
}

Amount breakdown doesn't total to the amount passed

{
   "amount": [
       "Amount Breakdown mismatch."
   ],
   "error_key": "validation_error"
}

Payment Success Callback

After the user completes the payment, the success response is obtained in the return URL specified during payment initiate. Sample of success response return URL.

  • The callback url return_url should support GET method
  • User shall be redirected to the return_url with following parameters for confirmation
    • pidx - The initial payment identifier
    • transaction_id - _The transaction identifier at Khalti after successful payment
    • amount - Amount paid in paisa
    • mobile - Payer Mobile
    • purchase_order_id - The initial purchase_order_id provided during payment initiate
    • purchase_order_name - The initial purchase_order_name provided during payment initiate
  • There is no further step required to complete the payment, however merchant can process with their own validation and confirmation steps if required
  • It's recommended that during implementation, payment lookup API is checked for confirmation after the redirect callback is received

Sample Callback Request

https://example.com/payment?pidx=EwGKrbdaYLTQ4rmWtNAMEJ
    &amount=1300
    &mobile=98XXXXX403
    &purchase_order_id=test12
    &purchase_order_name=test
    &transaction_id=MJbBJDKYziWqgvkgjxhS2W

Payment Failure Callback

If, in-case, due to some problem, user transaction does not go through, the failure response is obtained in the return URL specified during payment initiate. Sample of failure response return URL.

  • The callback url return_url should support GET method
  • User shall be redirected to the return_url with following parameters for confirmation
    • message - Failure message

Sample Callback Request

https://example.com/payment?message=Could%20not%20process%20the%20payment.

Payment Verification (Lookup)

After a callback is received, You can use the pidx provided earlier, to lookup and reassure the payment status.

URL Method Authorization Format
/epayment/lookup/ POST Required application/json

Request Data

{ "pidx": "HT6o6PEZRWFJ5ygavzHWd5" }

Success Response

{
   "pidx": "HT6o6PEZRWFJ5ygavzHWd5",
   "total_amount": 1000,
   "status": "Completed",
   "transaction_id": "GFq9PFS7b2iYvL8Lir9oXe",
   "fee": 0,
   "refunded": false
}

Failed / Pending Response

{
   "pidx": "HT6o6PEZRWFJ5ygavzHWd5",
   "total_amount": 1000,
   "status": "Pending",
   "transaction_id": "GFq9PFS7b2iYvL8Lir9oXe",
   "fee": 0,
   "refunded": false
}

Refunded Response

{
   "pidx": "HT6o6PEZRWFJ5ygavzHWd5",
   "total_amount": 1000,
   "status": "Refunded",
   "transaction_id": "GFq9PFS7b2iYvL8Lir9oXe",
   "fee": 0,
   "refunded": true
}

Expired Response

{
   "pidx": "H889Er9gq4j92oCrePrDwf",
   "total_amount": 1000,
   "status": "Expired",
   "transaction_id": null,
   "fee": 0,
   "refunded": false }

PS : Links expire in 60 minutes in production

Lookup Payload Details

Field Description --
pidx This is the payment id of the transaction.
total_amount This is the total amount of the transaction
status Completed - Transaction is success
Pending - Transaction is failed or is in pending state
Refunded - Transaction has been refunded
transaction_id This is the transaction id for the transaction.
This is the unique identifier.
fee The fee that has been set for the merchant.
refunded True - The transaction has been refunded.
False - The transaction has not been refunded.

Generic Errors

When an incorrect Authorization key is passed.

{ "detail": "Invalid token.", "status_code": 401 }

If incorrect payment_id is passed.

{ "detail": "Not found.", "error_key": "validation_error" }