Accept Mobile Money Payment with APIs

Another way to accept payments is by using our Mobile Money APIs. The comprehensive guide below will walk you through the process of successfully accepting mobile money on Kora using our APIs.

Get started with accepting Mobile money using APIs

For a full and up-to-date list of supported currencies and mobile money providers, please see our overview page for Mobile Money. Here are some test mobile money numbers you can use to simulate different scenarios for mobile money payments as you integrate.

Authorization models

When initiating a mobile money charge, the auth_model returned in the response indicates the action required to complete the transaction.

The supported authorization models are:

  • OTP - This means an OTP has been sent to the customer’s phone. You are expected to collect the OTP from the customer and authorize the transaction using the authorize endpoint.
  • STK_PROMPT - This means the customer will receive a prompt on their phone and should enter their wallet PIN to authorize the payment.
  • REDIRECT - This means the customer will be redirected to complete the transaction on the telco’s page.

If the returned auth model is OTP, you should collect the OTP and call the authorize endpoint. Once the OTP is successfully validated, the authorize response body will indicate the next required action.

After OTP validation, the next auth model returned will be either STK_PROMPT or REDIRECT. You should always check the auth model in the response to determine whether the customer needs to complete an STK prompt or continue the transaction on the telco’s page.


Step 1: Collect payment data required to initiate payment

To charge a customer, you will need to collect the necessary payment information from the customer.
Here are the request parameters.

Parameter

Type

Required

Description

reference

String

True

A unique reference for the payment. The reference must be at least 8 characters long.

amount

Number

True

The amount for the charge

currency

String

True

The currency for the charge

redirect_url

String

False

A URL to which we can redirect your customer after their payment is complete

customer

Object

True

The information of the customer you want to charge

customer.name

String

False

The name of your customer

customer.email

String

True

The email of your customer

mobile_money

Object

True

Object holding the mobile money wallet details

mobile_money.number

String

True

The mobile number of the customer to be charged e.g 254700000000

notification_url

String

False

The webhook URL to be called when the transaction is complete.

merchant_bears_cost

Boolean

False

This sets who bear the fees of the transaction. If it is set to true, the merchant will bear the fee. If it is set to false, the customer will bear the fee. By default, it is false.

description

String

False

Information/narration about the transaction

metadata

Object

False

It takes a JSON object with a maximum of 5 fields/keys. Empty JSON objects are not allowed.

Each field name has a maximum length of 20 characters. Allowed characters: A-Z, a-z, 0-9, and -.

After collecting the necessary mobile money payment information from your customer, prepare your data object to look like the example shown below.

{
    "amount": 701,
    "currency": "GHS",
    "reference": "idkMain27105551011",
    "description": "Payment for a emilokan",
    "notification_url": "https://webhook.site/1c209942-1a66-4cdf-a7ab-78d9cc684ad2",
    "redirect_url": "https://webhook.site",
    "customer": {
        "name": "John Doe",
        "email": "[email protected]"
    },
    "merchant_bears_cost": true,
    "mobile_money": {
      "number": "254700000000"
    }
}

To charge the number make a POST request with the payload to our charge mobile money endpoint. Ensure to include the relevant country currency.

Endpoint - POST https://api.korapay.com/merchant/api/v1/charges/mobile-money

If the request is successful, you should receive a message with either OTP,STK_PROMPT or REDIRECT as the auth model.

Sample OTP Auth Response:

{
    "status": true,
    "code": "AA001",
    "message": "Authorization required",
    "data": {
        "amount": 701,
        "amount_expected": 701,
        "currency": "GHS",
        "fee": 1.87,
        "vat": 0.13,
        "auth_model": "OTP",
        "transaction_reference": "KPY-PAY-rYF4c5ZWioeb",
        "payment_reference": "idkMain27105551021",
        "status": "processing",
        "narration": "Payment for a emilokan",
        "message": "Token generated and sent out successfully",
        "mobile_money": {
            "number": "+254700000000"
        },
        "customer": {
            "name": "John Doe",
            "email": "[email protected]"
        }
    }
}

Sample STK_PROMPT Auth Response:

{  
    "status": true,  
    "code": "AA001",  
    "message": "Authorization required",  
    "data": {  
        "amount": 10,  
        "amount_expected": 10,  
        "currency": "KES",  
        "fee": 0.25,  
        "vat": 0.04,  
        "auth_model": "STK_PROMPT",  
        "transaction_reference": "KPY-PAY-rYF4c5ZWioeb",  
        "payment_reference": "KPY-PAY-79lsPQSqHXSz",  
        "status": "processing",  
        "narration": "Live Test Link",  
        "message": "You will receive a pin prompt on your mobile number +25470000000 for GHS 10. Kindly enter your wallet PIN to authorize the payment",  
        "mobile_money": {  
            "number": "254700000000"  
        },  
        "customer": {  
            "name": "John Doe",  
            "email": "[email protected]"
        }  
    }  
}

Step 2: Authorize mobile money transaction

The next step is based on the auth model returned in the previous response after initiating the charge. There are 2 ways of authorizing a transaction OTP and STK_PROMPT.

Authorizing an OTP transaction

After making the request to charge the number, if the status of the transaction is processing and auth_model is OTP, this means an OTP has been sent to the wallet owner's phone. You would need to collect the OTP in order to authorize the transaction.

Collect the OTP sent to the customer’s phone and make a request to our authorize endpoint with the OTP and the transaction reference.

Endpoint - https://api.korapay.com/merchant/api/v1/charges/mobile-money/authorize

curl --location 'https://api.korapay.com/merchant/api/v1/charges/mobile-money/authorize' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_KORAPAY_SECRET_KEY' \
--data '{
    "reference": "KPY-PAY-rYF4c5ZWioeb",
    "token": "123456"
}'
-X POST

If the OTP verification is successful, an STK prompt will be sent to the wallet owner's phone for him to enter his PIN.

Sample response

{
    "status": true,
    "message": "Authorization required",
    "data": {
        "amount": "10.00",
        "amount_expected": "10.00",
        "currency": "GHS",
        "fee": 1.75,
        "vat": 0.12,
        "auth_model": "STK_PROMPT",
        "transaction_reference": "KPY-PAY-rYF4c5ZWioeb",
        "payment_reference": "KPY-PAY-rYF4c5ZWioeb",
        "status": "processing",
        "message": "You will receive a prompt on mobile number. Kindly enter your wallet PIN to authorize the payment",
        "mobile_money": {
            "number": "+254700000000"
        }
    }
}
{
    "status": true,
    "message": "Authorization required",
    "data": {
        "amount": "10.00",
        "amount_expected": "10.00",
        "currency": "GHS",
        "fee": 1.75,
        "vat": 0.12,
        "auth_model": "OTP",
        "transaction_reference": "KPY-PAY-rYF4c5ZWioeb",
        "payment_reference": "KPY-PAY-rYF4c5ZWioeb",
        "status": "processing",
        "message": "The OTP you provided is invalid",
        "mobile_money": {
            "number": "+254700000000"
        },
        "attempts_left": 2
    }
}

Authorizing an STK transaction

After making the charge request, if the status of the transaction is processing and auth_model is STK_PROMPT, this means an STK_PROMPT has been sent to the wallet owner's phone.

{
"status": true,
"code": "AA001",
"message": "Authorization required",
"data": {
"amount": 10,
"amount_expected": 10,
"currency": "KES",
"fee": 0.25,
"vat": 0.04,
"auth_model": "STK_PROMPT",
"transaction_reference": "KPY-PAY-rYF4c5ZWioeb",
"payment_reference": "KPY-PAY-79lsPQSqHXSz",
"status": "processing",
"narration": "Live Test Link",
"message": "You will receive a prompt on your mobile number +254700000000. Kindly enter your wallet PIN to authorize the payment",
"mobile_money": {
"number": "254700000000"
},
"customer": {
"name": "John Doe",
"email": "[email protected]"
}
}
}

Authorizing a REDIRECT transaction

After making the charge request, if the transaction status is processing and the auth_model is REDIRECT, the customer should be redirected to complete the transaction on the telco’s page.

After the customer completes the authorization, you should verify the transaction using the transaction reference. You should also set up your webhook to receive payment updates.

{
"status": true,
"code": "AA001",
"message": "Authorization required",
"data": {
"amount": 10,
"amount_expected": 10,
"currency": "KES",
"fee": 0.25,
"vat": 0.04,
"auth_model": "REDIRECT",
"transaction_reference": "KPY-PAY-rYF4c5ZWioeb",
"payment_reference": "KPY-PAY-79lsPQSqHXSz",
"status": "processing",
"narration": "Live Test Link",
"message": "You will be redirected to complete this transaction on the telco's page",
"authorization": {
"redirect_url": "https://test.com/pay/1nq8l9s0u2"
},
"mobile_money": {
"number": "254700000000"
},
"customer": {
"name": "John Doe",
"email": "[email protected]"
}
}
}

Step 3: Verify Payment

The final step after receiving payment is to ensure that the payment was successful by making a verification request to our verification charge endpoint. The reference here should be your transaction reference.

Here's a sample request and response for verifying a mobile money payment:

curl https://api.korapay.com/merchant/api/v1/charges/:reference
-H "Authorization: Bearer YOUR_KORAPAY_SECRET_KEY"
-X GET

Sample response for a successful transaction:

{
  "status": true,
  "message": "Charge retrieved successfully",
  "data": {
    "reference": "KPY-PAY-rYF4c5ZWioeb",
    "status": "success",
    "amount": "10.00",
    "amount_paid": 0,
    "fee": 0.29,
    "currency": "GHS",
    "description": "Payment for a emilokan",
    "mobile_money": {
      "number": "+254700000000"
    },
    "customer": {
      "name": "John Doe",
      "email": "[email protected]"
    }
  }
}
{
  "status": true,
  "message": "Charge retrieved successfully",
  "data": {
    "reference": "KPY-PAY-rYF4c5ZWioeb",
    "status": "failed",
    "amount": "2000.00",
    "amount_paid": 0,
    "fee": "180.00",
    "currency": "GHS",
    "description": "Mobile money payment for a book",
    "payment_attempts": [
      {
        "reference": "KPY-CM-unEr27sJ616S",
        "status": "failed",
        "channel": "mobile_money",
        "message": "The OTP you provided is invalid"
      }
    ],
    "mobile_money": {
      "number": "+25470000000"
    }
  }
}

Step 4: Setup Webhook

You can set your application to receive a confirmation via webhooks when a mobile money payment is successful. Please visit Webhooks to see more information about the webhook request body and how to verify and handle the webhook request.

Error Responses

{ 
  "status": false,
  "message": "The OTP you provided is invalid",
  "data": null
}
{
    "status": false,
    "message": "Payment has already been completed"
    "data": {}
}