Direct Charge (Complete Flow)
This guide shows you how to go from creating a payment → completing it → verifying it.
If you follow this exactly, your integration will work.
⚠️ Important
- A payment is NOT successful until confirmed
- Always use webhooks OR transaction status to verify final state
- The initial API response only tells you what to do next
Step 1: Create a Payment
Send a request to initiate the charge.
curl -X POST "https://api.modempay.com/h2h/v1/payments" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"data": {
"amount": 10,
"network": "afrimoney",
"account_number": "7012345"
}
}'
Step 2: Handle the Response
You will receive a response like this:
{
"transactionId": "cos-212q2mbrg8z6m",
"next_step": {
"requiresAuthorization": true,
"auth_mode": "confirm",
"openExternal": true,
"launch_url": "https://pay.wave.com/..."
},
"payment_intent_id": "8178ffbf..."
}
Now follow the correct path based on next_step.
Step 3: Complete the Payment (3 Possible Flows)
✅ Case 1: External Authorization (Wave, etc)
"openExternal": true
👉 Action:
- Redirect user to
launch_url - User completes payment externally
👉 Next:
- Wait for webhook or check status
❗ Do NOT call confirm endpoint
✅ Case 2: Manual Confirmation (Afrimoney, USSD)
"auth_mode": "confirm",
"openExternal": false
👉 Action:
- Show instructions to user (
confirmation_steps) - Ask user to confirm after completing payment
👉 Then call:
POST /payments/confirm/:transactionId
👉 Next:
- Wait for webhook or check status
✅ Case 3: PIN / OTP Required (Qmoney|APS)
"auth_mode": "pin"
👉 Action:
- Collect PIN/OTP from user
👉 Then call:
POST /payments/finalize/:transactionId
{
"pin": "123456"
}
👉 Response will contain updated payment status
Step 4: Verify Payment Status (CRITICAL)
This is where most integrations fail.
✅ Option 1: Webhook (Recommended)
- Listen for payment updates
- Mark payment as successful only when status =
completed
✅ Option 2: Polling
GET /transactions/:transactionId
Check:
"status": "completed"
Payment Status Values
| Status | Meaning |
|---|---|
| pending | Payment initiated |
| processing | In progress |
| completed | ✅ SUCCESS |
| failed | ❌ Failed |
| cancelled | User cancelled |
| abandoned | User did nothing |
Full Flow Summary
-
Create payment
-
Check
next_step -
Follow correct flow:
- Redirect → external
- Confirm → manual
- Finalize → PIN
-
Wait for webhook OR poll
-
Only mark success when
status = completed