Skip to main content

Direct Charge

The Direct Charge feature in Modem Pay’s H2H integration allows you to immediately initiate a payment on a specified mobile money account. By providing network and account_number in your HostIntent, Modem Pay can attempt to process the transaction without requiring a hosted checkout or customer interaction for supported networks.

This is ideal for partners who need automated, real-time payments as part of their platform workflow.

Example Request

POST https://api.modempay.com/h2h/v1/payments

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"
}
}'

Sample Response

// for wave (production mode)
{
"transactionId": "cos-212q2mbrg8z6m",
"next_step": {
"requiresAuthorization": true,
"auth_mode": "confirm",
"auth_length": 0,
"openExternal": true,
"launch_url": "https://pay.wave.com/c/cos-212q2mbrg8z6m?a=100&c=GMD&m=Merchant"
},
"payment_intent_id": "8178ffbf-6a04-4bca-807b-ed62d0067f7c"
}

Handling Responses

Below is a sample TypeScript code illustrating how to handle a direct charge response. For detailed guidance on completing payments, such as following up on required confirmations or next steps, see the Confirm Charge documentation.

type ChargeResponse = {
transactionId: string;
next_step?: {
requiresAuthorization: boolean;
auth_mode: "confirm" | "pin";
auth_length: number;
openExternal: boolean;
launch_url?: string;
};
confirmation_steps?: string;
payment_intent_id: string;
};

const handleCharge = (chargeResponse: ChargeResponse) => {
if (chargeResponse?.next_step?.openExternal) {
// Redirect the user to the provided external URL to complete payment.
// Example: window.location.href = chargeResponse.next_step.launch_url;
} else if (
chargeResponse?.next_step?.auth_mode === "confirm" &&
!chargeResponse?.next_step?.openExternal
) {
/*
Display the instructions found in chargeResponse.confirmation_steps
and provide a button for the customer to confirm once they have completed the required steps.
*/
} else if (chargeResponse?.next_step?.auth_mode === "pin") {
/*
Present an input field for the user to enter the OTP or PIN sent to their phone.
Enforce the maximum character length specified in chargeResponse.next_step.auth_length.
After entry, provide a button to submit and finalize the payment.
*/
}
// If none of the above conditions apply, the payment is considered successful and no additional steps are required.
};

Direct Charge Responses

The responses vary depending on the network and whether the request is in test mode or live mode. Some networks may require further authorization (OTP, PIN, or app confirmation) before the payment is completed.

NetworkModeRequires ConfirmationResponse Summary
AfrimoneyTestYesmessage: "Please authorize the payment"
transactionId: "ZPMZR_RMC"
next_step: { requiresAuthorization: true, auth_mode: "confirm" }
payment_intent_id
AfrimoneyLiveYestransactionId: "SE7TMU8YQN"
next_step: { requiresAuthorization: true, auth_mode: "confirm" }
confirmation_steps: detailed instructions for app or USSD confirmation
payment_intent_id
WaveTestNostatus: "processed"
transactionId: "WGVMQBW0XQ"
message: "Payment has been processed"
payment_intent_id
WaveLiveYestransactionId: "cos-1zyr9mpqr88tw"
next_step: { requiresAuthorization: true, auth_mode: "confirm", openExternal: true, launch_url: "https://pay.wave.com/..." }
payment_intent_id
QmoneyTestYestransactionId: "0.0cakoss683op"
message: "OTP Sent Successfully"
next_step: { requiresAuthorization: true, auth_mode: "pin", auth_length: 6 }
payment_intent_id
QmoneyLiveYesSame as test mode
info

More details on completing the direct charge process can be found in the Confirm Charge section of the documentation.

Notes

  • Requires Confirmation = No only applies when the network supports immediate processing without further authorization (e.g., Wave in test mode).
  • For networks requiring additional steps (requiresAuthorization = true), partners must follow the instructions in next_step to complete the payment.
  • payment_intent_id is always returned and can be used to track the transaction or handle webhook notifications.
  • next_step.launch_url in live mode may redirect customers to the mobile money app or portal for completing the payment.
  • Test mode responses may differ slightly from live mode in messages, transaction IDs, or next-step behavior.