Send Money
Single API to send money from your IntaSend account to your mobile money account i.e M-PESA, send to PayBill and TillNumber (M-Pesa B2B API), and IntaSend P2P.

How to send money with the API

Currently, you can send money to the following providers directly from your IntaSend wallet.
Transfer Type
Provider API Code
IntaSend to IntaSend transfer
INTASEND
M-Pesa send money (B2C)
MPESA-B2C
M-Pesa send to Till and Paybills (B2B)
MPESA-B2B
post
https://sandbox.intasend.com
/api/v1/send-money/initiate/
Step 1 - Initiate send money
Transaction list items
Parameter
Type
Required
Description
name
string
Yes
Beneficiary name
account
integer
Yes
Beneficiary phone number. Must be in the format 2547xxxxxxxxx - note the country prefix 254 without a +
amount
integer
Yes
Amount to send
account_type
string
Conditional
Required only for M-Pesa B2B. Acceptable fields are: Paybill or TillNumber
NB - Obtain tracking_id for the purpose of checking status.

Code examples

Python
PHP
Go
Ruby
Java
1
import requests
2
3
url = "http://sandbox.intasend.com/api/v1/send-money/initiate/"
4
5
payload = {'provider': 'MPESA-B2C', 'currency': 'KES', 'callback_url': 'https://example.com', 'transactions': [{'name': 'test-name', 'account': 254723890353, 'amount': 10}], 'device_id': 1}
6
headers = {
7
'Authorization': 'Bearer LfqRDqvfvwv77BhxuDsdXN04NyUx97',
8
'Content-Type': 'application/json'
9
}
10
11
response = requests.request("POST", url, headers=headers, data = payload)
12
13
print(response.text.encode('utf8'))
14
Copied!
1
<?php
2
3
$curl = curl_init();
4
5
curl_setopt_array($curl, array(
6
CURLOPT_URL => "http://sandbox.intasend.com/api/v1/send-money/initiate/",
7
CURLOPT_RETURNTRANSFER => true,
8
CURLOPT_ENCODING => "",
9
CURLOPT_MAXREDIRS => 10,
10
CURLOPT_TIMEOUT => 0,
11
CURLOPT_FOLLOWLOCATION => true,
12
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
13
CURLOPT_CUSTOMREQUEST => "POST",
14
CURLOPT_POSTFIELDS =>"{\"transactions\": [{\"account\": \"254723890353\", \"amount\": \"5\"}, {\"account\": \"254723890323\", \"amount\": \"5000\"}], \"currency\": \"KES\", \"callback_url\": \"http://127.0.0.1:8000/false-api/\", \"device_id\": \"1\"}",
15
CURLOPT_HTTPHEADER => array(
16
"Authorization: Bearer LfqRDqvfvwv77BhxuDsdXN04NyUx97",
17
"Content-Type: application/json"
18
),
19
));
20
21
$response = curl_exec($curl);
22
23
curl_close($curl);
24
echo $response;
25
Copied!
1
package main
2
3
import (
4
"fmt"
5
"strings"
6
"net/http"
7
"io/ioutil"
8
)
9
10
func main() {
11
12
url := "http://sandbox.intasend.com/api/v1/send-money/initiate/"
13
method := "POST"
14
15
payload := strings.NewReader("{\"transactions\": [{\"account\": \"254723890353\", \"amount\": \"5\"}, {\"account\": \"254723890323\", \"amount\": \"5000\"}], \"currency\": \"KES\", \"callback_url\": \"http://127.0.0.1:8000/false-api/\", \"device_id\": \"1\"}")
16
17
client := &http.Client {
18
}
19
req, err := http.NewRequest(method, url, payload)
20
21
if err != nil {
22
fmt.Println(err)
23
}
24
req.Header.Add("Authorization", "Bearer LfqRDqvfvwv77BhxuDsdXN04NyUx97")
25
req.Header.Add("Content-Type", "application/json")
26
27
res, err := client.Do(req)
28
defer res.Body.Close()
29
body, err := ioutil.ReadAll(res.Body)
30
31
fmt.Println(string(body))
32
}
Copied!
1
require "uri"
2
require "net/http"
3
4
url = URI("http://sandbox.intasend.com/api/v1/send-money/initiate/")
5
6
http = Net::HTTP.new(url.host, url.port);
7
request = Net::HTTP::Post.new(url)
8
request["Authorization"] = "Bearer LfqRDqvfvwv77BhxuDsdXN04NyUx97"
9
request["Content-Type"] = "application/json"
10
request.body = "{\"transactions\": [{\"account\": \"254723890353\", \"amount\": \"5\"}, {\"account\": \"254723890323\", \"amount\": \"5000\"}], \"currency\": \"KES\", \"callback_url\": \"http://127.0.0.1:8000/false-api/\", \"device_id\": \"1\"}"
11
12
response = http.request(request)
13
puts response.read_body
14
Copied!
1
OkHttpClient client = new OkHttpClient().newBuilder()
2
.build();
3
MediaType mediaType = MediaType.parse("application/json");
4
RequestBody body = RequestBody.create(mediaType, "{\"transactions\": [{\"phone_number\": \"254723890353\",\"amount\": \"5\"},{\"phone_number\": \"254723890323\",\"amount\": \"5000\"}],\"currency\": \"KES\",\"device_id\": \"1\",\"callback_url\": \"http://127.0.0.1:8000/false-api/\"}");
5
Request request = new Request.Builder()
6
.url("http://sandbox.intasend.com/api/v1/send-money/initiate/")
7
.method("POST", body)
8
.addHeader("Authorization", "Bearer LfqRDqvfvwv77BhxuDsdXN04NyUx97")
9
.addHeader("Content-Type", "application/json")
10
.build();
11
Response response = client.newCall(request).execute();
Copied!

Sample response

Successful request
Failed request
1
{
2
"tracking_id": "c1acf08c-5cc1-4b3e-b4a8-e43bc068aa56",
3
"status": "Preview and approve",
4
"nonce": "1aiw02",
5
"device_id": 1,
6
"transactions": [
7
{
8
"status": "Pending",
9
"request_reference_id": "f6a5a8dc-e190-4707-8ea2-102919709a72",
10
"name": null,
11
"account": 254723890353,
12
"amount": 10,
13
"narrative": null
14
},
15
{
16
"status": "Pending",
17
"request_reference_id": "cd763f35-44b3-4e89-a27a-252d507105f6",
18
"name": null,
19
"phone_number": 254708374149,
20
"amount": 500,
21
"narrative": null
22
}
23
],
24
"charge_estimate": 50.0,
25
"total_amount_estimate": 560.0,
26
"created_at": "2020-07-31T14:00:56.563163+03:00",
27
"updated_at": "2020-07-31T14:00:56.632188+03:00"
28
}
Copied!
1
# Returned with http status 400, 403, 401 depending on error type
2
# Reason for failure will be indicated under "details".
3
Sample response:
4
5
{'details': 'Device id not found'}
Copied!
post
https://sandbox.intasend.com
/api/v1/send-money/approve/
Step 2 - Approve send money
The original i.e returned response in step 1 (initiation step) looks like in the code block below. Pay attention to the nonce token which is a unique generated id for this transaction. You are required to sign this token and attach it back to the payload. Send back the payload with the signed nonce to the approval API.
Note: You are required to sign the nonce with the Private Key of the device used to initiate the payment. Note this is under the device_id parameter. On the IntaSend side, we'll verify the signature with the Public Key uploaded for use on the device.
Here are more details on how to sign the nonce.
1
{
2
"tracking_id": "c1acf08c-5cc1-4b3e-b4a8-e43bc068aa56",
3
"status": "Preview and approve",
4
"nonce": "1aiw02",
5
"device_id": 1,
6
"transactions": [
7
{
8
"status": "Pending",
9
"request_reference_id": "f6a5a8dc-e190-4707-8ea2-102919709a72",
10
"name": null,
11
"account": 254723890353,
12
"amount": 10000,
13
"narrative": null
14
}
15
...
16
],
17
"charge_estimate": 140.0,
18
"total_amount_estimate": 20140.0,
19
...
20
}
Copied!
Sample signed payload
1
{
2
"tracking_id": "c1acf08c-5cc1-4b3e-b4a8-e43bc068aa56",
3
"status": "Preview and approve",
4
"nonce": "<SIGNED-NONCE-HEX>",
5
"transactions": [
6
{
7
"status": "Pending",
8
"request_reference_id": "f6a5a8dc-e190-4707-8ea2-102919709a72",
9
"name": null,
10
"account": 254723890353,
11
"amount": 10000,
12
"narrative": null
13
}
14
],
15
"charge_estimate": 140.0,
16
"total_amount_estimate": 20140.0,
17
...
18
}
Copied!
Last modified 2d ago