Skip to content
This repository has been archived by the owner on Jun 2, 2021. It is now read-only.
/ mtn-pay-js Public archive

An unofficial JavaScript/Typescript client package for querying the MTN Mobile Money API

License

Notifications You must be signed in to change notification settings

sopherapps/mtn-pay-js

Repository files navigation

mtn-pay-js Build Status

An unofficial JavaScript/Typescript client package for querying the MTN Mobile Money API

Installation

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

Usage

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:

1. SandboxApiUser

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

2. Account

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;
    }

3. Transaction

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;
        }

4. Core

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 {
        // ...
    }

Advanced Docs

For more details of each class, interface, enum etc, visit the TypeDoc generated docs site

Running Tests

  1. Clone the repo

    git clone https://github.com/sopherapps/mtn-pay-js.git
  2. Enter the directory

    cd mtn-pay-js
  3. Rename the testSetup.example.ts file to testSetup.ts

    mv testSetup.example.ts testSetup.ts
  4. Update the variables in that testSetup.ts file appropriately.

  5. Install dependencies

    npm install
  6. Run npm script for testing

    npm run test

Acknowledgements

This nice post by Carl_Johan Kihl was very helpful when setting up this Typescript project.

License

Copyright (c) 2019 Martin Ahindura Licensed under the MIT License