Skip to content

Instantly share code, notes, and snippets.

@mtvbrianking
Last active July 22, 2020 18:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mtvbrianking/51320d7bde2dcc71cfb913d3aa3a9fc9 to your computer and use it in GitHub Desktop.
Save mtvbrianking/51320d7bde2dcc71cfb913d3aa3a9fc9 to your computer and use it in GitHub Desktop.
MTN MOMO API Requests

1 Client App

Subscription Key: Ocp-Apim-Subscription-Key

Gotten from user profile; after subscribing to some products

Generate API User ID: X-Reference-Id

api_user_id = \Ramsey\Uuid\Uuid::uuid4()->toString()

Note: providerCallbackHost == Provider callback uri

curl -X POST \
  https://sandbox.momodeveloper.mtn.com/v1_0/apiuser \
  -H 'Content-Type: application/json' \
  -H 'Ocp-Apim-Subscription-Key: a79ecad0b2dxxxxxxxxxxxx405c7fac8' \
  -H 'X-Reference-Id: 0efc4721-b2ec-409c-bcd4-429b4cb8e8e5' \
  -d '{"providerCallbackHost":"http://localhost:8000/callback"}'

Response; * No content

201 Created

This is a utility to validate that the user key is registered successful.

curl -X GET \
  https://sandbox.momodeveloper.mtn.com/v1_0/apiuser/0efc4721-b2ec-409c-bcd4-429b4cb8e8e5 \
  -H 'Ocp-Apim-Subscription-Key: a79ecad0b2dxxxxxxxxxxxx405c7fac8'

Response:

{
  "providerCallbackHost": "http://localhost:8000/callback",
  "targetEnvironment": "sandbox"
}

Use the API User ID registered above to generate the API Key.

* This invalidates any existing tokens.

curl -X POST \
  https://sandbox.momodeveloper.mtn.com/v1_0/apiuser/0efc4721-b2ec-409c-bcd4-429b4cb8e8e5/apikey \
  -H 'Content-Type: application/json' \
  -H 'Ocp-Apim-Subscription-Key: a79ecad0b2dxxxxxxxxxxxx405c7fac8' \
  -d '{"Just to have a content length - its required;. When consuming a POST route."}'

Response:

{
  "apiKey": "78da1ff701e141d9f5b55f321f122ca7"
}

The API has different products/services that you can utilise. You will need a subscription key for each other product and any client app can only consume one product since the app is tied to the product subscription key.

Note: Each product requires a different access token, i.e, use the endpoint related to the product you subscribed to.

Authorization: Basic base64_encode("api_user_id:api_key")

Delimiter :

curl -X POST https://sandbox.momodeveloper.mtn.com/collection/token/ \
  -H 'Authorization: Basic MGVmYzQ3MjEtYjJlYy00MDljLWJjZDQtNDI5YjRjYjhlOGU1Ojc4ZGExZmY3MDFlMTQxZDliNTVmNWYzMjFmMTIyY2E3' \
  -H 'Ocp-Apim-Subscription-Key: a79ecad0b2dxxxxxxxxxxxx405c7fac8' \
  -d '{"Just to have a content length - its required;. When consuming a POST route."}'

Or

curl -X POST https://sandbox.momodeveloper.mtn.com/collection/token/ \
  -u 'api_user_id:api_key'
  -H 'Ocp-Apim-Subscription-Key: a79ecad0b2dxxxxxxxxxxxx405c7fac8' \
  -d '{"Just to have a content length - its required;. When consuming a POST route."}'

Response:

{
  "access_token": "eyJ0eXAJKViOiQ1iLCJhbGciOiJSMjU2In0.eyJjbGllbnRJZCI6IjBlZmM0NzIxLWIyZWMtNDA5Yy1iY2Q0LTQyOWI0Y2I4ZThlNSIsImV4cGlyZXMiOiIyMDE4LTEyLTI5VDEzOjQyOjQ5LjE5NyIsInNlc3Npb25JZCI6IjdhZjdlMzllLWU0NDgtNDU2OC1iMTg3LTBkYzAxZGM4OWQxNSJ9.GdIdJDKJTLQpdO5YwWYntCjfuIupYmRBJZpQ2f-i0dHKBiv1aSpfumjVJxu9Ngwxubt-Wfb9hlqXy79QkXlYrT-bdtFQfHlw74QazUmKyE0r5BgwDnVBcsDIiLbZJFZ6RjL0YRq0aaO2T3QuKlJzN5Oujtktwe1Q6Gioke0_rrYY_1n5zJiW32dxTMTE4kRXxAw8HQTVTxLL7IqmHEqHH8GCCrRi0PR-4znikEsJsqmNAUDso0nAlnIp7Oq8OOLVXDMW52sSQmR4LJ4qO827DXJQ24wmPB3s0rJAocUVmmrr0Al456-tO9zHE96MIPmZCbOiq-hMkwrATtf2sqAZZw",
  "token_type": "access_token",
  "expires_in": 3600
}

* Token type indicated as access_token, but it's used as an OAuth Bearer token.

2.1.2 Refresh/renew token

A new token is requested by using the endpoint* in the same way as the initial token. A new token can be requested for even before the current one has expired.

This operation is used to request a payment from a consumer (Payer).

* X-Callback-Url is optional and shouldn't be sent in sandbox environment. If sent added in live environment, it must match the one registered. See: validate client id

* X-Reference-Id is a UUID format 4 to identify the transaction on the MTN MOMO system. You generate this yourself 😏

* externalId is your business transaction ID that identifies the transaction on the your system. Eg: Order No. 201903150001

$mtn_momo_transaction_id = \Ramsey\Uuid\Uuid::uuid4()->toString();
// 6a292529-c58b-4899-b4ac-eb945f3e34d0
curl -X POST \
  https://sandbox.momodeveloper.mtn.com/collection/v1_0/requesttopay \
  -H 'Authorization: Bearer {ACCESS_TOKEN}' \
  -H 'Content-Type: application/json' \
  -H 'Ocp-Apim-Subscription-Key: a79ecad0b2dxxxxxxxxxxxx405c7fac8' \
  -H 'X-Reference-Id: 6a292529-c58b-4899-b4ac-eb945f3e34d0' \
  -H 'X-Target-Environment: sandbox' \
  -d '{
    "amount": 100,
    "currency": "EUR",
    "externalId": "201903150001",
    "payer": {
      "partyIdType": "msisdn",
      "partyId": 46733123453
    },
    "payerMessage": "Confirm payment of EUR 100 to Jean'\''s Boutique.",
    "payeeNote": "201903150001 6a292529-c58b-4899-b4ac-eb945f3e34d0"
  }'
@mtvbrianking
Copy link
Author

mtvbrianking commented Sep 11, 2019

Guzzle HTTP Request example

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;

try {
    $response = (new Client)->request(
        'POST',
        'https://ericssonbasicapi2.azure-api.net/v1_0/apiuser',
        [
            'headers' => [
                'Content-Type' => 'application/json',
                'Ocp-Apim-Subscription-Key' => 'a79ecad0b2dxxxxxxxxxxxx405c7fac8',
                'X-Reference-Id' => '0efc4721-b2ec-409c-bcd4-429b4cb8e8e6',
            ],
            'json' => [
                'providerCallbackHost' => 'http://localhost:8000/callback',
            ]
        ]
    );

    echo $response->getBody();
} catch (RequestException $ex) {
    echo $ex->getResponse()->getBody();
}

Debug GuzzleHttp Request

@stevebaros
Copy link

stevebaros commented Jul 22, 2020

$url = 'https://ericssonbasicapi1.azure-api.net/collection/v1_0/requesttopay/';

$token ="eyJ0eXAiOiJKV1QiLCJhbGciOiJSMjU2In0.eyJjbGllbnRJZCI6IjdhNTA4ODUzLTBhMmUtNGNhMC1iODI1LTcyODg0YWFiNjc3ZCIsImV4cGlyZXMiOiIyMDIwLTA1LTExVDE2OjM0OjI4Ljg0MiIsInNlc3Npb25JZCI6IjBmNzZjZTE2LWMwOWItNGJjYy1iZmY4LTljZTRmNDYzYjdmYiJ9.a-pYf_AKmagkVwxmohQhOu7HbJyWmGO5bYyZmr7xKcdhjAYYORn_eeWXtzwymOSs06bhugWkgeoZsYzd8811iJCAO_dC3o6hpGU5aiXKCbi_znsKDp8PP21i-6zijO8kGHTiUalvW7vXrZLj5r-PXAMtwZ61Bc1f7gz_49S3CFzTecGwf1qc806ttFN4UiuYhHvJ1SzGm7W6PwxtY7RlvyaV7cfrmubLrwTIBNtekcpscWtFLnmqpZmi-Qyf61azjg-Im02goCo9oNwe0XIqKcYwYSfV1kI9LgvjykI8Ad9SFEe1jMJaQobqrQbEGCWh6ciN-oAjK_2PWrv-9myRGw";

//Create a cURL handle.
$ch = curl_init($url);

//Create an array of custom headers.
$customHeaders = array(
    'Authorization: Bearer '.$token,
    'Accept: application/json',
    'Content-Type: application/json',
    'Ocp-Apim-Subscription-Key: 8753dee8debf45453645645645',
    'Host: ericssonbasicapi1.azure-api.net',
    'X-Reference-Id: 5et54-1fa4-56455-8347-3633456445918',
    'X-Target-Environment: mtnuganda'
);


$payload = '{"amount":"500","currency":"UGX","externalId":"86435345390370511","payer":{"partyIdType":"msisdn","partyId":"256775054357"},"payerMessage":"","payeeNote":""}';

//Use the CURLOPT_HTTPHEADER option to use our
//custom headers.
curl_setopt($ch, CURLOPT_HTTPHEADER, $customHeaders);

curl_setopt( $ch, CURLOPT_POSTFIELDS, $payload );

//Set options to follow redirects and return output
//as a string.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

//Execute the request.
$result = curl_exec($ch);

echo $result;

@mtvbrianking
Copy link
Author

@stevebaros hope you'll change these credentials afterwards.

https://gist.github.com/mtvbrianking/51320d7bde2dcc71cfb913d3aa3a9fc9#gistcomment-3387832

Cause this is a public gist, else I delete the comment to protect you credentials.

@stevebaros
Copy link

Dummy credentials

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment