An unofficial JavaScript/Typescript client package for querying the MTN Mobile Money API
This is Typescript package that can be used in any of your favorite frameworks like vuejs, react, react-native etc. as long as they use NPM packages.
Install it as usual:
npm install --save mtn-pay
Please refer to the official MTN Mobile Money Open API docs for more details of how the API works.
According to the docs, MTN Mobile Money API is broken down into four products
- Collections
- to receive payments for goods and services using MTN Mobile Money
- Disbursements
- to send money in bulk to different recipients with just one click
- Collection Widget
- to integrate a checkout button to accept Mobile Money payments on e-commerce sites
- Remittances
- to transfer or receive funds from the diaspora to Mobile Money recipient's account in local currency
Of the above products, the Collection Widget is accessible manually and requires copy and paste (follow the link for the instructions) as opposed to the others which are accessible programmatically. Each product is subscribed to separately and you get a separate subscription key
The mtn-pay package exposes four entities you can work with:
For programmatically generating API USER ID and API USER KEY for sandbox testing.
import SandboxApiUser from 'mtn-pay/lib/sandboxApiUser';
const baseURL = "https://ericssonbasicapi2.azure-api.net/v1_0"; // or some other, check the docs
const subscriptionKey = 'your subscription key for any of the products e.g. "collection" or "disbursement"';
// check your profile at https://momodeveloper.mtn.com/developer for these keys if you subscribed to any of the products
const sandboxApiUser = new SandboxApiUser({ baseURL, subscriptionKey });
// The methods query the API so they should be 'awaited' for in an async function
const getCredentials = async () => {
const response: any = await sandboxApiUser.initialize();
const user: any = await sandboxApiUser.getUser();
const apiKey = user.apiKey;
const apiUserId = user.referenceId;
return { apiKey, apiUserId};
}
Use the SandboxApiUser to generate an API user ID and API Key when working with the sandbox. You will need these to access any of the other products. Ideally, you will use this entity before the others.
For the production environment, the API user ID and API Key are obtained through the 'Merchant Portal' as referred to in the official API docs
For getting the balance and the currency of your merchant account for a given product i.e. 'collection', 'disbursement' or 'remittance'
import Account, { IAccountConfig, AccountTypes } from 'mtn-pay/lib/account';
const accountConfig: IAccountConfig = {
subscriptionKey: '<Your subscription key for a given product whose account you want to check>',
targetEnvironment: 'sandbox or production (get this after you go live in your merchant portal)',
apiuserId: 'your production API User ID or await sandboxApiUser.getUser().referenceId',
apiKey: 'your production API key or await sandboxApiUser.getUser().apiKey',
baseURL: 'your API baseURL for the given product',
authBaseURL:'the baseURL for the /token/ endpoint for the product you subscribed for',
};
const getAccountDetails = async (accountType: string, config: IAccountConfig) => {
const account = new Account(accountType, config);
return await account.getDetails();
}
// AccountTypes {COLLECTION, DISBURSEMENT, REMITTANCE}
const getCollectionAccountDetails = async () => {
const details = await getAccountDetails(AccountTypes.COLLECTION, accountConfig);
const balance = details.balance;
const currency = details.currency;
}
To create a transaction whether it is to request for payment or to disburse money to another person.
import Transaction, {
IStatus,
ITransactionBody,
ITransactionConfig,
ITransactionDetails,
ReceipientTypes,
ResourceUrls,
Status,
TransactionTypes,
IReceipient
} from 'mtn-pay/lib/transaction';
const receipient: IReceipient = {
partyIdType: 'msisdn',
partyId: '0770000000' // The phone number of receipient of the request, not your own number
}
const TransactionType = TransactionTypes.COLLECTION;
// or TransactionTypes.DISBURSEMENT or TransactionTypes.REMITTANCE
const transactionConfig: ITransactionConfig = {
amount: 100000, //<money amount to pay or receive>,
currency: 'UGX', // in sandbox, it is 'EUR'
externalId: 'your own unique UUID generation 4 Id for easy tracking',
payeeNote: 'A note for the payee',
receipient,
payerMessage: 'A message for the payer',
subscriptionKey: 'your subscription key for the given product',
targetEnvironment: 'sandbox or the production one', // for sandbox, put 'sandbox'
apiuserId: 'Your Api user ID',
apiKey: 'Your Api user key',
timeout: 35000, // the time in milliseconds for polling status to time out; default: 35000
interval: 31000, // the interval at which status is polled in ms: defaults to 30000; never goes below 30000
baseURL: 'The baseURL of the API. Get it from the official API docs',
authBaseURL: 'The baseURL of the /token endpoint for the given product', // Go to API docs
resourceUrl: resourceUrlsMap[transactionType],
receipientType: transactionReceipientTypesMap[transactionType],
};
const transaction = new Transaction(transactionType, transactionConfig);
const someAsyncFunction = async() => {
const details = await transaction.getDetails();
/*
* or you could go step by step but why!!!
* await transaction.initialize();
* await transaction.pollStatus();
* const details = await transaction.getDetails();
*/
const {
amount,
currency,
externalId,
payee, // or payer if we are requesting for payment i.e. transactionType === 'collection'
status,
reason
} = details;
}
For any future transaction types or if you want to extend the BaseProduct class
import { BaseProduct, IApiToken } from 'mtn-pay/lib/core';
export class ChildProduct extends BaseProduct {
// ...
}
For more details of each class, interface, enum etc, visit the TypeDoc generated docs site
-
Clone the repo
git clone https://github.com/sopherapps/mtn-pay-js.git
-
Enter the directory
cd mtn-pay-js
-
Rename the
testSetup.example.ts
file totestSetup.ts
mv testSetup.example.ts testSetup.ts
-
Update the variables in that
testSetup.ts
file appropriately. -
Install dependencies
npm install
-
Run npm script for testing
npm run test
This nice post by Carl_Johan Kihl was very helpful when setting up this Typescript project.
Copyright (c) 2019 Martin Ahindura Licensed under the MIT License