This document lists the required details that need to be sent for each of our collection corridors.
GHS mobile collections
To initiate a GHS mobile collection, please use the following details (phone_number and mobile_provider used below are examples):
"input_currency": "GHS",
"payin_methods": [
{
"type": "GHS::Mobile",
"ux_flow": "ussd_popup",
"in_details": {
"phone_number": "+2339999999", // E.164 international format
"mobile_provider": "vodafone" // Mandatory. One of 'airtel', 'tigo', 'mtn', 'vodafone'
}
}
],
For Collection transactions with mtn
as mobile_provider
and ussd_menu_approval
as ux_flow
, the out_details
will be:
"out_details": {
"style": "ussd_menu_approval",
"menu_option": "6",
"requires_pin": true,
"dialing_number": "*170#"
}
And human readable instructions can be found in the payin_methods[0].instructions
hash in the following format:
(example instructions for GHS Mobile payments)
"instructions": {
'ussd_menu_approval': '\\nDial *170# to access mobile money menu.\\nSelect option 6 (My Wallet) and send.\\nChoose option 3 to check "my approvals".\\nChoose the transaction to approve and send.\\nConfirm transaction by choosing option1 (Yes) and send.\\nEnter mobile money pin and send.\\nYou will receive a new message on your mobile phone about the transaction.\\n'
}
Once the transaction is created, instructions for completing payment will be sent to the specified phone number.
Once the funds have been successfully received from the sender, payin_method.paid_in
and transaction.paid_in
webhooks will be sent out.
Collections requiring OTPs
Collections with ux_flow: otp_verified_ussd_popup
require that the sender validate an OTP sent to their phone number when the transaction is created. The collection process is handled asynchronously.
For such transactions, the details would look like:
"input_currency": "GHS",
"payin_methods": [
{
"type": "GHS::Mobile",
"ux_flow": "otp_verified_ussd_popup",
"in_details": {
"phone_number": "+233548689440" // E.164 international format
"mobile_provider": "mtn"
}
}
]
Once the transaction is created, an OTP will be sent to the phone_number
specified in the payload. The response would look like:
"payin_methods": [
{
"id": "7334d150-41f8-4710-858b-e16a96df0c71",
"type": "GHS::Mobile",
"ux_flow": "otp_verified_ussd_popup",
"state": "initial",
"in_details": {
"phone_number": "+233548689440", // E.164 international format
"mobile_provider": "mtn"
},
}
When the OTP is sent, a payin_method.incomplete
webhook is sent out:
{
"webhook": "ddef6199-6171-43ba-bbb5-29fb06c9df9f",
"event": "payin_method.incomplete",
"object": {
"id": "7334d150-41f8-4710-858b-e16a96df0c71",
"type": "GHS::Mobile",
"ux_flow": "otp_verified_ussd_popup",
"state": "incomplete",
"state_reason_details": {
"code": "23",
"category": "user_action_required",
"messages": [
"User action required",
"OTP verification required",
"OTP verification required"
],
"description": "This transaction is awaiting OTP verification by the user."
},
"in_details": {
"phone_number": "+233548689440", // E.164 international format
"mobile_provider": "mtn",
"otp": "170270"
},
"transaction_id": "8421a8b4-0107-4d54-85bc-e0c2747b68b8",
"transaction_external_id": "TRANSACTION-d68069bc-898f-45f5-88cf-5e7d8e537c70"
}
}
In order to validate the OTP, send a PATCH request for the PayinMethod with the OTP in the payload:
PATCH /v1/payin_methods/9b25ca43-1812-46b2-ae0c-57acefec0a34
{
"in_details": {
"phone_number": "+233123456789" // E.164 international format
"mobile_provider": "mtn",
"otp": "123456"
}
}
If the OTP matches the one sent to the sender’s phone number, the collection process starts, otherwise you get a validation error:
{
"id": "9b25ca43-1812-46b2-ae0c-57acefec0a34",
"type": "GHS::Mobile",
"ux_flow": "otp_verified_ussd_popup",
"in_details": {
"phone_number": "+233123456789" // E.164 international format
"mobile_provider": "mtn",
"otp": "123456"
},
"errors": {
"otp": [
{
"error": "invalid"
}
]
}
}
When the collection process starts, a payin_method.pending
webhook is sent out:
{
"webhook": "ddef6199-6171-43ba-bbb5-29fb06c9df9f",
"event": "payin_method.pending",
"object": {
"id": "7334d150-41f8-4710-858b-e16a96df0c71",
"type": "GHS::Mobile",
"ux_flow": "otp_verified_ussd_popup",
"state": "pending",
"state_reason_details": {
"code": "14",
"category": "pending",
"messages": [
"Pending",
"Pending status update",
"Pending status update"
],
"description": "This transaction is awaiting a status update from the provider."
},
"in_details": {
"otp": "170270",
"type": "payin",
"app_id": "898e347d-9391-4180-b0ef-3c67df0d8e50",
"method": "mobile",
"ux_flow": "otp_verified_ussd_popup",
"currency": "GHS",
"nth_provider": 0,
"phone_number": "+233548689440", // E.164 international format
"mobile_provider": "mtn"
},
"transaction_id": "8421a8b4-0107-4d54-85bc-e0c2747b68b8",
"transaction_external_id": "TRANSACTION-d68069bc-898f-45f5-88cf-5e7d8e537c70"
}
}
XOF mobile collections
To initiate a XOF mobile collection, please use the following details (phone_number
used below are examples):
At the moment, we only support collections in:
- Senegal(Orange) - this requires the sender to request an OTP auth code via USSD
#144#391*ORANGE_MONEY_PIN_CODE#
. The auth code retrieved should be included in the otp
parameter in in_details
. Uses ussd_voucher
in ux_flow
parameter.
- Ivory Coast(Orange) - this requires the sender to request an OTP auth code via USSD
#144*82#
. The auth code retrieved should be included in the otp
parameter in in_details
. Uses ussd_voucher
in ux_flow
parameter.
- Ivory Coast(MTN) - On receipt of collection request, Sender dials a USSD code
*133#
& selects option 1 (Validate withdrawal & payment) 2. Sender selects option to confirm 3. Sender enters secret code to confirm withdrawal 4. Sender receives sms that confirms debit is completed. Uses ussd_popup
in ux_flow
parameter
"input_currency": "XOF",
"payin_methods": [
{
"type": "XOF::Mobile",
"ux_flow": "ussd_voucher",
"in_details": {
"phone_number": "+221123456700", // E.164 international format
"mobile_provider": "orange",
"country": "SN", // "SN" for Senegal, "CI" for Ivory Coast
"otp": "123456"
}
}
],
Or in MTN
"input_currency": "XOF",
"payin_methods": [
{
"type": "XOF::Mobile",
"ux_flow": "ussd_popup",
"in_details": {
"phone_number": "+2250506369100", // E.164 international format
"mobile_provider": "mtn",
"country": "CI", // "SN" for Senegal, "CI" for Ivory Coast
}
}
],
If the payin method details are valid, you get back an initial
response.
{
"id": "1625c534-6db4-4f3a-adf2-62a8bec89080",
"type": "XOF::Mobile",
"ux_flow": "ussd_voucher",
"state": "initial",
"in_details": {
"otp": "1234",
"phone_number": "+221771234700", // E.164 international format
"mobile_provider": "orange",
"country": "SN"
},
"out_details": {
"style": "info"
},
"instructions": {}
}
The collection process is handled asynchronously.
When the collection process starts, a payin_method.pending
webhook is sent:
{
"webhook": "ddef6199-6171-43ba-bbb5-29fb06c9df9f",
"event": "payin_method.pending",
"object": {
"id": "1625c534-6db4-4f3a-adf2-62a8bec89080",
"type": "XOF::Mobile",
"ux_flow": "ussd_voucher",
"state": "pending",
"state_reason_details": {
"code": "14",
"category": "pending",
"messages": [
"Pending",
"Pending status update",
"Pending status update"
],
"description": "This transaction is awaiting a status update from the provider."
},
"in_details": {
"otp": "1234",
"ux_flow": "ussd_voucher",
"phone_number": "+221771234700", // E.164 international format
"mobile_provider": "orange",
"country": "SN"
},
"out_details": {
"style": "info"
},
"instructions": {
},
"transaction_id": "0d59466a-dc2f-4aca-bad1-d4a98da37697",
"transaction_external_id": "510c4e28-fe33-4c06-bd79-49d52d5b3094"
}
}
Once the funds have been successfully received from the sender, a payin_method.paid_in
webhook is sent:
{
"webhook": "ddef6199-6171-43ba-bbb5-29fb06c9df9f",
"event": "payin_method.paid_in",
"object": {
"id": "1625c534-6db4-4f3a-adf2-62a8bec89080",
"type": "XOF::Mobile",
"ux_flow": "ussd_voucher",
"state": "success",
"state_reason_details": {
"code": "0",
"category": "paid",
"messages": [
"Success",
"Success",
"Success"
],
"description": "The transaction was successfully completed."
},
"in_details": {
"otp": "1234",
"ux_flow": "ussd_voucher",
"phone_number": "+221771234700", // E.164 international format
"mobile_provider": "orange",
"country": "SN"
},
"out_details": {
"style": "info"
},
"instructions": {
},
"transaction_id": "0d59466a-dc2f-4aca-bad1-d4a98da37697",
"transaction_external_id": "510c4e28-fe33-4c06-bd79-49d52d5b3094"
}
}
If there was an issue with the collection, a payin_method.error
webhook is sent:
{
"webhook": "ddef6199-6171-43ba-bbb5-29fb06c9df9f",
"event": "payin_method.error",
"object": {
"id": "10bcee73-2c39-4c0d-9e00-7540c4d34a91",
"type": "XOF::Mobile",
"ux_flow": "ussd_voucher",
"state": "error",
"state_reason_details": {
"code": "412",
"category": "invalid_user_data_error",
"messages": [
"User Error",
"Invalid user details",
"Invalid mobile number"
],
"description": "Mobile details are invalid. Please update the mobile details. You can also cancel this transaction."
},
"in_details": {
"otp": "1234",
"ux_flow": "ussd_voucher",
"phone_number": "+221771234709", // E.164 international format
"mobile_provider": "orange",
"country": "SN"
},
"out_details": {
"style": "info"
},
"instructions": {
},
"transaction_id": "b83f38d6-fc4c-49de-b512-f45ac914bbea",
"transaction_external_id": "9b5f3c64-9b6b-41b8-9658-168999961b70"
}
}
NGN Bank collections
To initiate NGN bank collection, please use the following details (phone_number
used below is an example):
"input_currency": "NGN",
"payin_methods": [
{
"type": "NGN::Bank",
"ux_flow": "bank_transfer",
"in_details": {
"phone_number": "+234787221236", // E.164 international format
}
}
],
You will receive bank transfer information in the out_details
:
"out_details": {
"style": "bank_transfer",
"amount": 0,
"currency": "NGN",
"bank_code": "bank code",
"bank_name": "bank name",
"created_at": "created at",
"account_name": "account name",
"account_number": "account number",
"account_reference": "account reference"
}
And human readable instructions can be found in the payin_methods[0].instructions
hash in the following format:
(instructions for NGN Bank payment)
"instructions": {
"bank_transfer": "\\nTransfer the exact amount specified to the provided virtual account number.\\nMake sure to complete the payment within one day from the time you receive these instructions.\\n"
}
Once the funds have been successfully received from the sender, payin_method.paid_in
and transaction.paid_in
webhooks will be sent out.