Use this approach when you need full control of the payment interface. Orqex resolves which countries and methods are available for your project, routes the attempt to the optimal gateway, and tells you what next action to present to the customer.
When to use this vs the hosted checkout
Hosted checkout Custom checkout Integration effort Minimal (redirect) Higher (build the UI) UI control None Full Country / method selection Orqex UI Your own UI Recommended for Quick integrations Branded or embedded flows
Step 1 - Create a payment intent
curl https://api.orqex.com/v1/payment/intents \
-H "Authorization: Bearer sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"amount": 5000,
"currency": "XOF",
"description": "Order #1024",
"return_url": "https://shop.example.com/return",
"webhook_url": "https://shop.example.com/webhooks/orqex",
"customer": {
"email": "[email protected] ",
"first_name": "Ama",
"last_name": "Mensah"
}
}'
Store the returned id (e.g. pi_a1b2c3d4e5f6). Every subsequent step is scoped to this intent.
Step 2 - List available countries
Fetch the countries your project can accept for this intent. Results are ranked by payer preference based on the customer’s location, past payments, and popularity signals.
curl https://api.orqex.com/v1/payment/intents/pi_a1b2c3d4e5f6/countries \
-H "Authorization: Bearer sk_live_xxx"
{
"data" : [
{ "code" : "CI" , "name" : "Cote d'Ivoire" , "flag" : "https://cdn.orqex.com/flags/CI.svg" },
{ "code" : "SN" , "name" : "Senegal" , "flag" : "https://cdn.orqex.com/flags/SN.svg" }
],
"meta" : { "total" : 2 , "supports_any_country" : false }
}
Display this list and let the customer select their country. Use the returned code value in the next step.
supports_any_country: true means at least one routing rule accepts any country. You can still render the ranked list - it just may be longer.
Step 3 - List payment methods for the chosen country
Fetch methods available for the selected country. Pass currency to narrow to a specific currency (useful when the project supports DCC).
curl "https://api.orqex.com/v1/payment/intents/pi_a1b2c3d4e5f6/countries/CI/methods?currency=XOF" \
-H "Authorization: Bearer sk_live_xxx"
{
"data" : [
{
"value" : "momo_mtn" ,
"label" : "MTN Mobile Money" ,
"description" : "Pay with MTN MoMo" ,
"icon_url" : "https://cdn.orqex.com/methods/momo_mtn.svg" ,
"category" : "mobile_money"
},
{
"value" : "wallet_wave" ,
"label" : "Wave" ,
"description" : "Pay with Wave" ,
"icon_url" : "https://cdn.orqex.com/methods/wave.svg" ,
"category" : "wallet"
}
]
}
Results are ranked by preference. Render the list and let the customer pick.
Step 4 - Create a payment attempt
Submit the customer’s chosen method, country, and phone number. Orqex routes to the optimal gateway and executes the capture.
curl https://api.orqex.com/v1/payment/intents/pi_a1b2c3d4e5f6/attempts \
-H "Authorization: Bearer sk_live_xxx" \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: idem_attempt_001" \
-d '{
"method_code": "momo_mtn",
"country": "CI",
"phone": { "number": "0700000000", "country": "CI" }
}'
Request body
Payment method code from the previous step (e.g. momo_mtn).
ISO 3166-1 alpha-2 country code selected by the customer.
Payer phone number. Phone number in local or international format.
Phone country (ISO 3166-1 alpha-2).
Override currency (ISO 4217). Defaults to the intent’s currency.
Response
The response is the updated payment intent with the new active_attempt. Check active_attempt.next_action.type to determine what to do next:
next_action.typeWhat to do nonePayment is processing. Poll or wait for webhook. approve_on_phoneShow the customer the dial code to approve on their phone. collect_otpPrompt the customer for an OTP, then call Step 5. redirect_to_urlRedirect the customer to next_action.url. display_payment_instructionsShow next_action.instructions to the customer.
Step 5 - Authorise (OTP / 2FA), if required
If active_attempt.next_action.type is collect_otp, submit the OTP the customer received. No attempt id is needed.
curl https://api.orqex.com/v1/payment/intents/pi_a1b2c3d4e5f6/authorize \
-H "Authorization: Bearer sk_live_xxx" \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: idem_auth_001" \
-d '{
"otp": "123456"
}'
Returns the updated payment intent. If the OTP is accepted, active_attempt.status transitions to completed or back to processing.
Step 6 - Retrieve the final state
Poll or wait for the webhook event, then retrieve the intent to confirm the outcome.
curl https://api.orqex.com/v1/payment/intents/pi_a1b2c3d4e5f6 \
-H "Authorization: Bearer sk_live_xxx"
A status of completed means the payment succeeded. See the payment lifecycle for all possible states.
Prefer webhooks over polling. Set webhook_url on the intent and react to payment.completed or payment.failed events.