Skip to content

Create an order

POST
/Transactions/SubmitOrderRequest
curl --request POST \
--url https://cybqa.pesapal.com/pesapalv3/api/Transactions/SubmitOrderRequest \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "id": "example", "currency": "KES", "amount": 1, "description": "example", "callback_url": "example", "cancellation_url": "example", "notification_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "billing_address": { "email_address": "example", "phone_number": "example", "first_name": "example", "middle_name": "example", "last_name": "example", "country_code": "example", "line_1": "example", "line_2": "example", "city": "example", "state": "example", "postal_code": "example", "zip_code": "example" }, "branch": "example", "redirect_mode": "TOP_WINDOW", "account_number": "example", "subscription_details": { "start_date": "01-01-2027", "end_date": "01-01-2028", "frequency": "DAILY" } }'

Creates an order and returns a redirect_url to send the customer to.

Adding account_number and subscription_details turns the same request into a recurring payment. There is no separate subscriptions endpoint.

Submitting an id that has been used before returns the original order, at its original amount, with no error. Generate a fresh id for every attempt.

Unknown fields are silently ignored rather than rejected, so a misspelled field name produces no error and simply has no effect.

Media typeapplication/json
object
id
required

Your own reference, which must be unique. Values between 51 and 150 characters fail with a generic decline that does not mention length.

string
<= 50 characters
currency
required

Validated against a lookup table. Acceptance at submission does not guarantee a customer can complete a payment in that currency.

string
<= 3 characters
Allowed values: KES UGX TZS RWF ZMW MWK ZWL BWP ZAR NGN GHS ETB EGP MAD XAF XOF BIF SOS CDF AOA MZN NAD LSL SZL USD GBP EUR JPY CHF CAD AUD CNY INR AED SAR
amount
required
One of:
number
description
required

Shown to the customer. No maximum length was enforced.

string
callback_url
required

Plain HTTP is accepted.

string
cancellation_url
string
notification_id
required

An ipn_id from registerIpn.

string format: uuid
billing_address
required

The object is mandatory on an order, but every field within it is optional. An empty object is accepted.

object
email_address
string
<= 60 characters
phone_number
string
first_name
string
<= 50 characters
middle_name
string
<= 50 characters
last_name
string
<= 50 characters
country_code

ISO 3166-1 alpha-2, for example KE.

string
<= 3 characters
line_1
string
line_2
string
city
string
state
string
postal_code
string
zip_code
string
branch
string
<= 30 characters
redirect_mode
string
Allowed values: TOP_WINDOW PARENT_WINDOW
account_number

Your identifier for a subscriber. Send with subscription_details.

string
<= 50 characters
subscription_details
object
start_date
required

Format dd-MM-yyyy. ISO 8601 is rejected. Must be in the future.

string
end_date
required

Format dd-MM-yyyy. The range is not validated, so an end date before the start date is accepted.

string
frequency
required

Case insensitive.

string
Allowed values: DAILY WEEKLY MONTHLY QUARTERLY YEARLY

Returned for both success and failure.

Media typeapplication/json
One of:
object
order_tracking_id
required

Pesapal’s identifier for the order. Required by most other operations.

string format: uuid
merchant_reference

The id that was sent.

string
redirect_url

Send the customer here to pay.

string
error
null
status
string
Example
{
"error": {
"error_type": "api_error"
}
}