⚙️
DusuPay API Documentation
  • Introduction
  • Getting Started
    • Registration
    • Error Handling
    • Authentication
    • Merchant Account Credentials
      • Generate Secret Key
      • Regenerate Security Keys
    • Supported Countries/Regions
    • Transaction Limits
    • Sandbox Test Accounts
    • DusuPay Public Keys
  • Utility Functions
    • Balance Inquiry
    • Payment Options
    • Payout Bank Codes
    • Mobile Money Operator Prefixes
    • Handling Notifications/Callbacks
      • Callback Events
    • Transaction Status Verification
  • Funds Collection
    • Getting Started
    • Mobile Money Collection
      • Mobile Money - Direct Charge
      • Mobile Money - Hosted Page
    • NGN Bank Transfers
    • ZAR Bank Collections
    • Card Payments
      • Hosted Payment Page
      • Direct Card Payment (S2S)
  • Payouts/Disbursements
    • Getting Started
    • Mobile Money Payouts
    • Bank Account Transfers
  • Callbacks
    • HMAC Signature Verification
    • RSA Signature Verification
  • Appendix
    • Merchant Account Transfers
    • Availing Payout Funds
    • Sub Account Transfers
    • Funds Settlement
    • Transaction Audit Logs
    • Cross Currency Transactions
Powered by GitBook
On this page
  • Overview
  • Step 1: Obtain the required data for the payment request
  • Step 2: Handle the payment instructions webhook
  • Step 3: Authorize the transaction (Optional)
  • Step 4: Handle the final status webhook
  1. Funds Collection
  2. Mobile Money Collection

Mobile Money - Direct Charge

This is one of the ways to process payments using Mobile Money. The section below will guide you through the process of accepting Mobile Money using the direct API method.

PreviousMobile Money CollectionNextMobile Money - Hosted Page

Last updated 8 months ago

Overview

The currently supported mobile money channels are listed (to be updated from time to time). Test mobile money phone numbers are also described in section. We equally recommend that you go through the section to have a high-level understanding of the funds collection process.

Step 1: Obtain the required data for the payment request

The table below describes the request parameters that are used for the collection/charge request. Most/all will be collected from the paying customer.

Parameter
Type
Required
Description

merchant_reference

String

true

The unique reference for this request. It must be at least 8 characters long. Alternatively, the value auto can be passed, and a unique reference will be created for you by the API

transaction_method

String

true

The transaction method to be used. This will be MOBILE_MONEY for this request

currency

String

true

The 3-character ISO currency code for the request currency

amount

Number

true

The amount being requested

provider_code

String

true

msisdn

String

true

The phone number from which the payment is being requested. This should be sent in international format e.g. 256777000001 for Ugandan numbers

customer_name

String

false

The name of the customer

customer_email

String

false

The email of the customer

description

String

true

The description/narration for the transaction. Between 10-30 characters

charge_customer

Boolean

false

Whether or not the customer should bear the charge for the transaction. By default, this is false to mean that the merchant bears the charge

allow_final_status_change

Boolean

false

After collecting the necessary mobile money payment information from your customer, prepare your request payload as demonstrated below.

{
	"merchant_reference": "auto",
	"transaction_method": "MOBILE_MONEY",
	"currency": "UGX",
	"amount": 4000,
	"provider_code": "mtn_ug",
	"msisdn": "256777000001",
	"customer_email": "johndoe@gmail.com",
	"customer_name": "JOHN DOE",
	"description": "Test Collection",
	"charge_customer": false,
	"allow_final_status_change": true
}

POST https://sandboxapi.dusupay.com/collections/initialize

The request is sent as a JSON body as demonstrated by the sample request below. Sample responses (acknowledgement and failure) are also shared.

curl -X POST "https://sandboxapi.dusupay.com/collections/initialize" \
   -H 'Content-Type: application/json' \
   -H "x-api-version: 1" \
   -H "public-key: your-public-key" \
   -d '{
        "merchant_reference": "auto",
        "transaction_method": "MOBILE_MONEY",
        "currency": "UGX",
        "amount": 5000,
        "provider_code": "mtn_ug",
        "msisdn": "256777000001",
        "customer_email": "johndoe@gmail.com",
        "customer_name": "JOHN DOE",
        "description": "Test Collection",
        "charge_customer": false,
        "allow_final_status_change": true
    }'
{
    "code": 202,
    "status": "accepted",
    "message": "Request Accepted",
    "data": {
        "internal_reference": "DUSUPAYSTPDKZ6MLY5WPQ",
        "merchant_reference": "MCTREF9WVCPGFRHYCWSK"
    }
}
{
    "code": 400,
    "status": "error",
    "message": "256752000001 is not a valid MTN Mobile Money Uganda (mtn_ug) phone number",
    "data": {}
}

Step 2: Handle the payment instructions webhook

If the request in step 1 is successful and responds with an acknowledgement (HTTP code 202), you should listen and handle the payment instructions webhook/callback. This will be sent to the collection callback URL that's configured on your merchant account. The callback is sent as a JSON POST request and the payload will help you determine the next course of action. The tabs below show the two possible payload structures.

{
    "event": "transaction.processing",
    "payload": {
        "id": 27594,
        "merchant_reference": "MCTREF9WVCPGFRHYCWSK",
        "internal_reference": "DUSUPAYSTPDKZ6MLY5WPQ",
        "transaction_type": "COLLECTION",
        "request_currency": "UGX",
        "transaction_amount": 5000,
        "transaction_currency": "UGX",
        "transaction_charge": 150,
        "transaction_account": "256777000001",
        "charge_customer": false,
        "total_credit": 4850,
        "provider_code": "mtn_ug",
        "request_amount": 5000,
        "customer_name": "JOHN DOE",
        "transaction_status": "PROCESSING",
        "status_message": "Transaction Initiated successfully. Approve Payment by entering the PIN",
        "authorization": {
            "mode": "NONE",
            "required_parameters": []
        },
        "payment_instructions": "<p>You will receive a prompt on the mobile number <b>256777000001</b>.<br/> Enter your PIN to authorize your payment of <b>UGX 5,000</b></p>"
    }
}
{
    "event": "transaction.processing",
    "payload": {
        "id": 27594,
        "merchant_reference": "MCTREF9WVCPGFRHYCWSK",
        "internal_reference": "DUSUPAYSTPDKZ6MLY5WPQ",
        "transaction_type": "COLLECTION",
        "request_currency": "GHS",
        "transaction_amount": 500,
        "transaction_currency": "GHS",
        "transaction_charge": 150,
        "transaction_account": "233545503456",
        "charge_customer": false,
        "total_credit": 350,
        "provider_code": "mtn_gh",
        "request_amount": 500,
        "customer_name": "JOHN DOE",
        "transaction_status": "PROCESSING",
        "status_message": "Transaction Initiated successfully. OTP sent",
        "authorization": {
            "mode": "OTP",
            "required_parameters": [
                {
                    "parameter_name": "otp"
                }
            ]
        },
        "payment_instructions": "<p>Authorize Payment using the OTP sent to <b>233545503456</b>.</p>"
    }
}

Pay close attention to the authorization.mode parameter. When the value is NONE, the merchant should simply display the instructions in the payment_instructions parameter. In this scenario, the customer should expect a PIN approval prompt from the telecom. If the mode is OTP, it means the OTP has been sent to the phone number and the merchant needs to call another endpoint to submit the OTP and authorize the transaction to proceed as described in step 3 below.

Step 3: Authorize the transaction (Optional)

If the payment instructions webhook in step 2 above is sent, the transaction status being PROCESSING and the authorization mode is OTP, this means the OTP has been set to the customer's phone number. The merchant therefore needs to collect the OTP from the customer and submit it in order to verify the phone number and authorize the transaction to proceed.

The parameter authorization.required_parameters holds an object array of the parameters the merchant should obtain and submit. In every object, parameter_name is the name of the parameter that's going to carry the required value (OTP in this case). Form the payload as demonstrated in the sample request below.

POST https://sandboxapi.dusupay.com/collections/authorize

curl -X POST "https://sandboxapi.dusupay.com/collections/authorize" \
   -H 'Content-Type: application/json' \
   -H "x-api-version: 1" \
   -H "public-key: your-public-key" \
   -d '{
        "internal_reference": "DUSUPAYSTPDKZ6MLY5WPQ",
        "otp": "012345"
    }'

If OTP verification is successful, a PIN prompt will be sent to the mobile money phone number in the request for the customer to approve the transaction. If the customer has sufficient balance for the transaction and is eligible to transact, the request will be successful otherwise the API will send an appropriate error message as shared by the telecom.

Step 4: Handle the final status webhook

{
    "event": "transaction.completed",
    "payload": {
        "id": 20760,
        "merchant_reference": "MCTREFT2WMNWZ23SBN6Y",
        "internal_reference": "DUSUPAYRMGRXNNYBWATKJ",
        "transaction_type": "COLLECTION",
        "request_currency": "UGX",
        "transaction_amount": 2000000,
        "transaction_currency": "UGX",
        "transaction_charge": 60000,
        "transaction_account": "256787008803",
        "charge_customer": false,
        "total_credit": 1940000,
        "provider_code": "mtn_ug",
        "request_amount": 2000000,
        "customer_name": "JOHN DOE",
        "transaction_status": "COMPLETED",
        "status_message": "Transaction Completed Successfully"
    }
}
{
      "event": "transaction.failed",
      "payload": {
        "id": 26609,
        "merchant_reference": "MCTREFNRFRTQA6SCWT5X",
        "internal_reference": "DUSUPAYWYUF8CR3ZRCGYU",
        "transaction_type": "COLLECTION",
        "request_currency": "UGX",
        "transaction_amount": 2000000,
        "transaction_currency": "UGX",
        "transaction_charge": 0,
        "transaction_account": "256777000002",
        "charge_customer": false,
        "total_credit": 0,
        "provider_code": "mtn_ug",
        "request_amount": 2000000,
        "customer_name": "JOHN DOE",
        "transaction_status": "FAILED",
        "status_message": "Balance Insufficient for the transaction"
      }
    }

The provider code as obtained from the payment options

Whether or not the final transaction status can be altered as described . By default, this is true to mean DusuPay will alter the final transaction status under the circumstances described.

Every merchant account is expected to have configured a callback/webhook URL for collections. For all collections that transition to the final state (COMPLETED, FAILED or CANCELLED), a JSON POST request will be made to the callback URL. Sample callback payloads (request bodies) are shared below. Be sure to check out to see how you should verify the signature(s) in the request headers and how to respond.

here
this
Getting Started
Handling Notifications
list
here