> For the complete documentation index, see [llms.txt](https://docs.brij.africa/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.brij.africa/brij-mpesa-offline-integration.md).

# Brij Mpesa Offline Integration

## Authentication

To obtain a bearer token send the following fields to the token endpoint

## Gets Auth token

<mark style="color:green;">`POST`</mark> `https://accounts.brij.africa/api/v1/connect/token`

Use **x-www-form-urlencoded body** to obtain a  bearer token &#x20;

#### Request Body

| Name                                             | Type   | Description                |
| ------------------------------------------------ | ------ | -------------------------- |
| client\_secret<mark style="color:red;">\*</mark> | String | \<your-client-secret>      |
| grant\_type<mark style="color:red;">\*</mark>    | String | \<your-client-credentials> |
| client\_id<mark style="color:red;">\*</mark>     | String | \<your-client-id>          |

{% tabs %}
{% tab title="200: OK success" %}

```json
 {
     "access_token": "eyJh......NrdM",
     "expires_in": 3600,
     "token_type": "Bearer",
     "scope": "Mpesa"
}
```

{% endtab %}
{% endtabs %}

## Registering a Callback URL

To receive payment information once an offline payment is received, you need to register a callback URL along with the routing prefix that will have to be part of the account number the users will key in during payment.&#x20;

For example, if the account number the user is paying to is 12862637, and your routing prefix is FT then the user has to enter FT12862637 as the account number when making the offline Mpesa Payment.&#x20;

The routing prefix is important to prevent transaction mix-up. Your callback URL must accept post requests. The request body must be of type application/json.

## Registering a Callback URL

<mark style="color:green;">`POST`</mark> `https://saf.brij.africa/api/mpesaoffline/register-url`

#### Request Body

| Name                                            | Type   | Description          |
| ----------------------------------------------- | ------ | -------------------- |
| routingPrefix<mark style="color:red;">\*</mark> | String | \<your-prefix>       |
| url<mark style="color:red;">\*</mark>           | String | \<your-callback-url> |

{% tabs %}
{% tab title="200: OK success" %}

```json
{
     "result": {
       "id": "018b290b......ef229116526c",
       "url": "https://yoursite.tld/path/to/callback",
       "routingPrefix": "FT"
     },
     "message": "success",
     "errors": []
}

```

{% endtab %}

{% tab title="400: Bad Request " %}

```json
{
     "result": null,
     "message": "failure message",
     "errors": []
}

```

{% endtab %}
{% endtabs %}

## Updating the Callback URL

The API allows you to update the callback URL or prefix if need be.

## Updating the Callback URL

<mark style="color:green;">`POST`</mark> `https://saf.brij.africa/api/mpesaoffline/update-url/`

#### Query Parameters

| Name                                 | Type   | Description    |
| ------------------------------------ | ------ | -------------- |
| id<mark style="color:red;">\*</mark> | String | \<your-url-id> |

#### Request Body

| Name                                            | Type   | Description                                                                            |
| ----------------------------------------------- | ------ | -------------------------------------------------------------------------------------- |
| routingPrefix<mark style="color:red;">\*</mark> | String | <p>\<your-prefix></p><p>Required if URL is null</p><p>otherwise optional</p>           |
| url<mark style="color:red;">\*</mark>           | String | <p>\<your-callback-url></p><p>Required if routingPrefix is null otherwise optional</p> |

{% tabs %}
{% tab title="200: OK success" %}

```json
{
     "result": {
       "id": "018b290b......ef229116526c",
       "url": "https://yourupdatesite.tld/path/to/callback",
       "routingPrefix": "FT"
     },
     "message": "success",
     "errors": []
}
```

{% endtab %}

{% tab title="400: Bad Request " %}

```json
{
     "result": null,
     "message": "failure message",
     "errors": []
}

```

{% endtab %}
{% endtabs %}

## Mpesa Offline Callback Structure

Expect the following JSON payload in your registered callback URL.

```json
{
     "msisdn": "254*******7",
     "transId": "RJB..AQ",
     "transAmount": 2.00,
     "billRefNumber": "FT…567",
     "transTime": "20231011132104",
     "firstName": "JOHN",
     "lastName": "DOE"
}
```

## Transaction Status Query

In case a callback is missed by our system or your system, the API provides a way to query the transaction status. You need to provide a result URL that will receive the transaction status callback once it is received from the Mpesa system

## Querying transaction status

<mark style="color:green;">`POST`</mark> `https://saf.brij.africa/api/mpesaoffline/transaction-status`

#### Request Body

| Name                                            | Type   | Description              |
| ----------------------------------------------- | ------ | ------------------------ |
| billRefNumber<mark style="color:red;">\*</mark> | String | \<account-number>        |
| transId<mark style="color:red;">\*</mark>       | String | \<mpesa-transaction-id>  |
| resultUrl<mark style="color:red;">\*</mark>     | String | \<url-to-receive-result> |

{% tabs %}
{% tab title="200: OK success" %}

```json
{
     "result": {
       "conversationId": "12ac……a9382"
     },
     "message": "success",
     "errors": []
}
```

{% endtab %}

{% tab title="400: Bad Request " %}

```json
{
     "result": null,
     "message": "failure message",
     "errors": []
}

```

{% endtab %}
{% endtabs %}

## Transaction status callback structure (sent to resultUrl)

```json
{
     "conversationId": "2ac……a9382",
     "resultCode": 0,
     "message": "Completed",
     "paymentInfo": {
         "msisdn": "254*******7",
         "transId": "RJB..AQ",
         "transAmount": 2.00,
         "billRefNumber": "FT…567",
         "transTime": "20231011132104",
         "firstName": "JOHN",
         "lastName": "DOE"
     }
}
```

When the resultCode field has a value of 0 the paymentInfo object will be populated. Otherwise, check for possible failure in the message field.

#### Postman collection for the APIs is available at:

{% embed url="<https://api.postman.com/collections/26066936-4dc35f72-22f0-494b-9f3f-ccb9eafb3683?access_key=PMAT-01HCMMVRK3FEG7Y6WHYGEFDAR6>" %}
BRij Mpesa Offline Integration Postman Collection
{% endembed %}

<br>
