Skip to content

Web Checkout (KPG-2)

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.

Tip

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

Access Information

For Sandbox Access

Signup from https://test-web.khalti.com/#/join/merchant as a merchant.

For Production Access

Please visit https://admin.khalti.com

Test Credentials for sandbox environment

Test Khalti ID for 9800000000 9800000001 9800000002 9800000003 9800000004 9800000005

Test MPIN 1111

Test OTP 987654

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>"  
}  

Tip

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

API Endpoints

API Endpoints

Sandbox

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

Production

https://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
}

Note

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"
}