Standard Checkout
Initiate Payment Checkout
Overview
The Standard Checkout API allows merchants to initiate payment transactions. This endpoint creates a new checkout session and returns a redirect URL for customers to complete their payment through a hosted checkout page.
Endpoint
POST /v2/checkout/initiate
Authentication
All requests to this endpoint must include the following header:
Header: x-access-token
Value: <your_access_token>
The access token must be included in the request headers for authentication. Invalid or expired tokens will result in an authentication error.
Request Parameters
Submit a JSON payload with the following fields:
| Field | Type | Required | Max Length | Description |
|---|---|---|---|---|
merchant_transaction_id | String | Yes | 64 | Unique transaction ID (UUID recommended) for idempotency |
amount | Integer | Yes | - | Transaction amount |
payer_name | String | Yes | 100 | Customer's full name |
payer_email | String | Yes | 100 | Customer's email address |
payer_msisdn | String | Yes | 25 | Customer's phone number with country code (e.g., 254718192689) |
service_code | String | Yes | 32 | Service/product code (must be valid and active) |
account_number | String | Yes | 50 | Merchant's account number in the payment gateway |
expires_in | Integer | Yes | - | Session expiry duration in minutes |
narration | String | Yes | 255 | Transaction description/purpose |
callback_url | String | Yes | 500 | Webhook URL for payment notifications (must be HTTPS) |
redirect_url | String | Yes | 500 | URL to redirect customer after payment completion |
Request Example
cURL
curl -X POST https://sandbox.api.gateway.lipad.io/v2/checkout/initiate \
-H "Content-Type: application/json" \
-H "x-access-token: your_access_token_here" \
-d '{
"merchant_transaction_id": "5eb251eb-93c3-4e9b-a530-a39a3b300871",
"amount": 1000,
"payer_name": "John Doe",
"payer_email": "[email protected]",
"payer_msisdn": "25470000000",
"service_code": "DEMCHE1",
"account_number": "25470000000",
"expires_in": 60,
"narration": "Checkout redirect test",
"callback_url": "",
"redirect_url": ""
}'
Successful Response
Status Code: 200 OK
When the checkout is successfully created, the API returns a JSON object with the following fields:
{
"merchant_transaction_id": "5eb251eb-93c3-4e9b-a530-a39a3b300871",
"checkout_reference": "CYGCTLY3ZI8H9ZD609QTZ",
"currency": "KES",
"amount": 1000,
"expires_at": "2026-04-29T11:35:33.008Z",
"redirect_url": "https://sandbox.pay.lipad.io/checkout/CYGCTLY3ZI8H9ZD609QTZ"
}
Response Fields
| Field | Type | Description |
|---|---|---|
merchant_transaction_id | String | Your original transaction ID (for tracking) |
checkout_reference | String | Unique checkout session identifier from payment gateway |
currency | String | Transaction currency code (e.g., "KES") |
amount | Integer | Transaction amount in base units |
expires_at | String (ISO 8601) | Session expiration timestamp in UTC |
redirect_url | String | Hosted checkout page URL where customer completes payment |
Error Response
Status Code: 400 Bad Request or other 4xx/5xx depending on error
When a request fails, the API returns an error object:
{
"status_code": 172,
"status_description": "Invalid Service Code",
"message": "Request declined"
}
Error Response Fields
| Field | Type | Description |
|---|---|---|
status_code | Integer | Error code indicating the type of failure |
status_description | String | Short description of the error |
message | String | Additional details about the error |
Status Query
GET /v2/checkout/status/{{merchant_transaction_id}}
cURL
curl --location 'https://sandbox.api.gateway.lipad.io/v2/checkout/status/5eb251eb-93c3-4e9b-a530-a39a3b300871' \
--header 'x-access-token:your-access-token'
Success Response
Same as under callbacks
Error Response
{
"status_code": 120,
"status_description": "Transaction not found",
"message": "Checkout reference 5eb251eb-93c3-4e9b-a530-a39a3b30087 not found"
}
Callback
After the customer completes payment, you will receive a notification at your configured callback_url.
Success Callback Example
{
"amount": "1000",
"checkout_reference": "CYGCTLY3ZI8H9ZD609QTZ",
"currency": "KES",
"merchant_transaction_id": "5eb251eb-93c3-4e9b-a530-a39a3b300871",
"narration": "Checkout redirect test",
"payments": [
{
"event": "successful_payment",
"amount": "1000.00",
"extra_data": {},
"client_code": "DEMO",
"country_code": "KEN",
"payer_msisdn": "25470000000",
"payment_date": "2026-04-29T10:40:55.006Z",
"service_code": "DEMCHE1",
"currency_code": "KES",
"account_number": "25470000000",
"payment_status": 700,
"transaction_id": "10644",
"payer_narration": "Checkout redirect test",
"charge_request_id": "7845",
"external_reference": "5eb251eb-93c3-4e9b-a530-a39a3b300871",
"receiver_narration": "Payment processed successfully",
"payment_method_code": "MPESA_KEN",
"payer_transaction_id": "GBR1FNEAGOTV",
"payment_account_reference": "GBR1FNEAGOTV"
}
],
"status": 801,
"timestamp": "2026-04-29T10:40:55.449Z"
}
Callback Fields
| Field | Type | Description |
|---|---|---|
amount | String | Payment amount received |
checkout_reference | String | Checkout session reference |
currency | String | Currency code (e.g., "KES") |
merchant_transaction_id | String | Your original transaction ID |
narration | String | Transaction description |
payments | Array | Array of payment records |
status | Integer | Overall transaction status (801 = successful) |
timestamp | String (ISO 8601) | When payment was processed |
Payment Record Fields
| Field | Type | Description |
|---|---|---|
event | String | Event type (e.g., "successful_payment") |
amount | String | Payment amount with decimal places |
extra_data | Object | Additional payment data |
client_code | String | Client identifier |
country_code | String | Country code (e.g., "KEN") |
payer_msisdn | String | Customer phone number |
payment_date | String (ISO 8601) | Payment timestamp |
service_code | String | Service code |
currency_code | String | Currency code |
account_number | String | Merchant account number |
payment_status | Integer | Payment status code (700 = successful) |
transaction_id | String | Internal transaction ID |
payer_narration | String | Payer's description of payment |
charge_request_id | String | Charge request identifier |
external_reference | String | External reference (merchant transaction ID) |
receiver_narration | String | Receiver's description of payment |
payment_method_code | String | Payment method used (e.g., "MPESA_KEN") |
payer_transaction_id | String | Payer's transaction reference |
payment_account_reference | String | Payment account reference |
Integration Flow
Follow these steps to integrate the Standard Checkout API:
Step 1: Collect Customer Information
Gather the customer's details and order information on your application.
Step 2: Generate Unique Transaction ID
Create a unique merchant_transaction_id for each checkout (UUID recommended):
Step 3: Initiate Checkout
Call the /v2/checkout/initiate endpoint with all required fields.
Step 4: Handle Response
- Success: Redirect the customer to the
redirect_url - Error: Display error message and allow customer to retry
Step 5: Customer Completes Payment
Customer is redirected to hosted checkout page to enter payment details.
Step 6: Receive Webhook Notification
Your callback_url receives payment status notification.
Step 7: Update Order Status
Fetch status after receiving callback. (Do not rely on callbacks alone). Process the payment notification and update your database accordingly.
Step 8: Fulfill Order
Once payment is confirmed, proceed with order fulfillment.
Status Codes
Checkout Status Codes
| Status | Description |
|---|---|
| 801 | Full payment received - Complete. |
| 802 | Partial Payment received - Incomplete. |
| 803 | Unpaid i.e failed payments, no payments. |
| 820 | Expired with no payments. |
| 840 | Payment reversed. |
| 841 | Payment refunded. |
| 850 | Jammed. |
| 851 | Pending. |
Payment Status Codes
| Status | Description |
|---|---|
| 700 | Successful payment made. |
| 701 | Failed payment made |
| 702 | Payment was Reversed |
| 703 | Payment is Pending Processing |
| 704 | Payment is Jammed. Requires manual intervention to continue processing |
| 705 | Payment is Refunded |
| 706 | Payment has been accepted for processing by operator |
| 707 | Payment is being reprocessed |
| 708 | Payment is pending approval (maker-checker payments) |
Error Response Codes
| Status Code | Status Message | Comment |
|---|---|---|
| 176 | CHARGE POSTED SUCCESSFULLY | This is the success code for posting a charge request. |
| 173 | GENERIC SUCCESS | GENERIC SUCCESS |
| 174 | GENERIC FAILURE | GENERIC FAILURE |
| 172 | GENERIC VALIDATION FAILURE | This is the generic code to be returned for generic validations. |
| 132 | Invalid Credentials. Authentication failed | Invalid Credentials. Authentication failed |
| 131 | Authentication was a success | Authentication was a success |
| 120 | INVOICE ACCOUNT NUMBER NOT SPECIFIED | This is the error code for when the invoice account number is not specified. |
| 110 | INVALID CUSTOMER MSISDN | This is the error code for a failed msisdn |
| 109 | CUSTOMER MSISDN MISSING | Missing Payer MSISDN |
| 115 | INVALID CURRENCY CODE | Currency error |
Troubleshooting
Issue: "Invalid Service Code"
Error: Status code 172
Causes:
- Service code doesn't exist
- Service code is disabled
- Service code doesn't belong to your account
Solution: Verify the service code with your account manager
Issue: "Unauthorized"
Error: Status code 401
Causes:
- Missing x-access-token header
- Invalid or expired token
Solution: Check your access token and ensure it's correctly included in the header
Issue: "Webhook Not Received"
Causes:
- Callback URL is not publicly accessible
- Server is behind a firewall
- Webhook handler is returning error status
Solution:
- Ensure callback URL is HTTPS and publicly accessible
- Ensure webhook handler returns 200 status
- Check server logs for errors
Issue: "Duplicate Webhooks"
Cause: Webhook delivery retries
Solution: Implement idempotency using merchant_transaction_id to safely handle duplicate callbacks