Confirm Charge
Once a Direct Charge is initiated, some networks may require additional authorization from the customer before the payment can be completed. Modem Pay provides endpoints to confirm these charges depending on the auth_mode returned in the payment response.
1. auth_mode: "confirm" without openExternal
For networks where auth_mode is "confirm" and openExternal is false (e.g., Afrimoney in-app or USSD confirmation):
-
Endpoint:
POST/payments/confirm/:reference
:referenceis thetransactionIdreturned in the payment response. -
Flow:
- Your system should display a confirmation button or action for the user to indicate that they have completed the payment via their provider (app or USSD).
- Once the user confirms, your system calls the endpoint to notify Modem Pay.
- Modem Pay will eventually check the payment status with the provider (every ~30 minutes), but using this endpoint speeds up the confirmation process.
-
Example Request:
curl -X POST "https://api.modempay.com/h2h/v1/payments/confirm/ZPMZR_RMC" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"
- Example Response:
{
"message": "ok",
"confirmation": "started"
}
If you want to poll for the latest payment status (for example, to update your UI after confirmation), you can call:
curl -X GET "https://api.modempay.com/h2h/v1/transactions/:reference"
Replace :reference with the transactionId from your payment. This endpoint returns the current status and details of the transaction.
Response:
{
"id": "bb270a1f-e0a4-4a3d-bba6-e4046e09d5d0",
"payment_intent_id": "05bf5898-de54-480c-b822-64c18e3c1a03",
"amount": 100,
"currency": "GMD",
"source": "online",
// status can be: "pending", "processing", "completed", "failed", "cancelled", "abandoned"
"status": "processing",
"transaction_reference": "RVMGQVWLU",
"reference": "RVMGQVWLU",
"payment_method": "afrimoney",
"risk_score": {},
"payment_method_id": "d8ec7405-0485-47aa-b58e-ab6d173ba4ed",
"customer": null,
"customer_name": null,
"customer_phone": null,
"customer_email": null,
"payment_account": ".... 4725",
"metadata": {},
"payment_metadata": {},
"type": "payment",
"custom_fields_values": {},
"payment_link_id": null,
"account_id": "199bf17b-0b5a-45c0-a5b0-1d29f5f173c9",
"business_id": "120c298f-b736-49c1-8220-8a8c84a5d8f3",
"test_mode": false,
"failure_reason": null,
"transaction_fee": 0,
"transaction_fee_type": "business",
"coupon": null,
"discount": null,
"sub_total": null,
"requires_auth": true,
"auth_length": 0,
"auth_mode": "confirm",
"launch_url": "",
"openExternal": false,
"notes": null,
"edited": false,
"paid_date": null,
"createdAt": "2025-11-10T09:32:55.769Z",
"updatedAt": "2025-11-10T09:32:58.191Z"
}
2. auth_mode: "confirm" with openExternal: true
For networks where openExternal is true (e.g., Wave live mode):
- The user should be redirected to the provided
launch_url. - The user completes the authorization on the external site or app.
- Modem Pay will automatically detect when the payment is confirmed and send a webhook event notifying your system of the completed payment.
No manual confirmation endpoint call is needed in this case.
3. auth_mode: "pin"
For networks requiring a PIN/OTP:
-
The response includes
auth_length, which specifies the number of digits for the OTP. -
Your system must collect the PIN from the user and send it to the following endpoint:
-
Endpoint: POST
/payments/finalize/:reference -
Request Body:
{
"pin": "123456"
}
- Example Request:
curl -X POST "https://api.modempay.com/h2h/v1/payments/finalize/0.0cakoss683op" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"pin": "123456"
}'
- Example Response:
{
"id": "bb270a1f-e0a4-4a3d-bba6-e4046e09d5d0",
"payment_intent_id": "05bf5898-de54-480c-b822-64c18e3c1a03",
"amount": 100,
"currency": "GMD",
"source": "online",
// status can be: "pending", "processing", "completed", "failed", "cancelled", "abandoned"
"status": "completed",
"transaction_reference": "RVMGQVWLU",
"reference": "RVMGQVWLU",
"payment_method": "qmoney",
"risk_score": {},
"payment_method_id": "d8ec7405-0485-47aa-b58e-ab6d173ba4ed",
"customer": null,
"customer_name": null,
"customer_phone": null,
"customer_email": null,
"payment_account": ".... 4725",
"metadata": {},
"payment_metadata": {},
"type": "payment",
"custom_fields_values": {},
"payment_link_id": null,
"account_id": "199bf17b-0b5a-45c0-a5b0-1d29f5f173c9",
"business_id": "120c298f-b736-49c1-8220-8a8c84a5d8f3",
"test_mode": false,
"failure_reason": null,
"transaction_fee": 1,
"transaction_fee_type": "business",
"coupon": null,
"discount": null,
"sub_total": null,
"requires_auth": true,
"auth_length": 0,
"auth_mode": "confirm",
"launch_url": "",
"openExternal": false,
"notes": null,
"edited": false,
"paid_date": null,
"createdAt": "2025-11-10T09:32:55.769Z",
"updatedAt": "2025-11-10T09:32:58.191Z"
}
Notes
- Using these confirmation flows ensures that payments are validated faster than waiting for provider polling intervals.
- Always use the
transactionIdfrom the initial Charge response as:reference. - Webhook notifications will also provide updates when the payment status changes.