Introduction
_ __ _____ ___ ______ ______ _____
| | / // __ \ / _ \| ___ \_ _| | _ \
| |/ / `' / /' / /_\ \ |_/ / | | | | | |___ ___ ___
| \ / / | _ | __/ | | | | | / _ \ / __/ __|
| |\ \./ /___ | | | | | _| |_ | |/ / (_) | (__\__ \
\_| \_/\_____/ \_| |_|_| \___/ |___/ \___/ \___|___/
_ __ _____ ___ ______ ______ _____
| | / // __ \ / _ \| ___ \_ _| | _ \
| |/ / `' / /' / /_\ \ |_/ / | | | | | |___ ___ ___
| \ / / | _ | __/ | | | | | / _ \ / __/ __|
| |\ \./ /___ | | | | | _| |_ | |/ / (_) | (__\__ \
\_| \_/\_____/ \_| |_|_| \___/ |___/ \___/ \___|___/
_ __ _____ ___ ______ ______ _____
| | / // __ \ / _ \| ___ \_ _| | _ \
| |/ / `' / /' / /_\ \ |_/ / | | | | | |___ ___ ___
| \ / / | _ | __/ | | | | | / _ \ / __/ __|
| |\ \./ /___ | | | | | _| |_ | |/ / (_) | (__\__ \
\_| \_/\_____/ \_| |_|_| \___/ |___/ \___/ \___|___/
_ __ _____ ___ ______ ______ _____
| | / // __ \ / _ \| ___ \_ _| | _ \
| |/ / `' / /' / /_\ \ |_/ / | | | | | |___ ___ ___
| \ / / | _ | __/ | | | | | / _ \ / __/ __|
| |\ \./ /___ | | | | | _| |_ | |/ / (_) | (__\__ \
\_| \_/\_____/ \_| |_|_| \___/ |___/ \___/ \___|___/
<?
_ __ _____ ___ ______ ______ _____
| | / // __ \ / _ \| ___ \_ _| | _ \
| |/ / `' / /' / /_\ \ |_/ / | | | | | |___ ___ ___
| \ / / | _ | __/ | | | | | / _ \ / __/ __|
| |\ \./ /___ | | | | | _| |_ | |/ / (_) | (__\__ \
\_| \_/\_____/ \_| |_|_| \___/ |___/ \___/ \___|___/
_ __ _____ ___ ______ ______ _____
| | / // __ \ / _ \| ___ \_ _| | _ \
| |/ / `' / /' / /_\ \ |_/ / | | | | | |___ ___ ___
| \ / / | _ | __/ | | | | | / _ \ / __/ __|
| |\ \./ /___ | | | | | _| |_ | |/ / (_) | (__\__ \
\_| \_/\_____/ \_| |_|_| \___/ |___/ \___/ \___|___/
Welcome to the Kopo Kopo API documentation. This documentation gives you the specifications for connecting your systems to the Kopo Kopo Application. Primarily you can connect to the Kopo Kopo system to perform the following:
- Receive webhook notifications
- Receive payments from your users/customers
- Send money to third parties (external recipients)
- Send money to your transfer accounts
Please note, all requests MUST be made over HTTPS. Any non-secure requests are met with a redirect (HTTP 302) to the HTTPS equivalent URI. All calls made without authorization will also fail.
Authorization
Kopo Kopo uses Oauth2 to allow access to the Kopo Kopo API. You can view the API Authorization guide at our developer portal. Access to the API can be granted on behalf of the user or of the application itself.
The client credentials flow is used when an application needs to obtain permission to act on its own behalf. The application will exchange its client_id, client_secret and
grant_type=client_credentials for an application's access token.
The Kopo Kopo API then expects the application access token to be used to make calls to the Kopo Kopo API on behalf of the application. The Kopo Kopo API expects the application access token to be included in subsequent API calls via the Authorization HTTP header:
Authorization: Bearer {application_access_token_here}
Request application authorization
To request application authorization, use this code:
require 'k2-connect-ruby'
# Using K2 Connect, the assumption here is that you have already initialized the API Client
K2Config.set_base_url('sandbox.kopokopo.com')
access_token = K2AccessToken.new('your_client_id', 'your_client_secret').token_request
access_token # => "myApplicationAccessToken"
import k2connect
k2connect.initialize('your_client_id', 'your_client_secret', 'sandbox.kopokopo.com')
token_service = k2connect.Tokens
access_token_request = token_service.request_access_token()
access_token = token_service.get_access_token(access_token_request)
access_token # => "myApplicationAccessToken"
# With json, you can just pass the correct header with each request
curl -d "client_id=CGQXLrlfuOqdUYdTcLz3rBiCZQDRvdWIUPkwasGMuGhkem9Bo&client_secret=g7QLwvO37aN2HoKx1amekWi8a2g7AIuPbD5CcJSLqXIcDOxfTr&grant_type=client_credentials"
-H "Content-Type: application/x-www-form-urlencoded"
-H "User-Agent: <product>/<product-version> <comment>"
"https://sandbox.kopokopo.com/oauth/token"
const options = {
clientId: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
apiKey: 'YOUR_API_KEY',
baseUrl: 'https://sandbox.kopokopo.com'
}
//Including the kopokopo module
var K2 = require("k2-connect-node")(options)
const TokenService = K2.TokenService
TokenService
.getToken()
.then(response => {
//Developer can decide to store the token_details and track expiry
console.log(response)
})
.catch( error => {
console.log(error);
})
<?
use Kopokopo\SDK\K2;
// Do not hardcode these values
$options = [
'clientId' => 'YOUR_CLIENT_ID',
'clientSecret' => 'YOUR_CLIENT_SECRET',
'apiKey' => 'YOUR_API_KEY',
'baseUrl' => 'sandbox.kopokopo.com'
]
$K2 = new K2($options);
// Get one of the services
$tokens = $K2->TokenService();
// Use the service
$result = $tokens->getToken();
if($result['status'] == 'success'){
$data = $result['data'];
echo "My access token is: ".$data['accessToken'];
echo "It expires in: ".$data['expiresIn'];
}
// Ensure K2ConnectFlutter is initialized
await K2ConnectFlutter.initialize(
baseUrl: 'sandbox.kopokopo.com',
credentials: K2ConnectCredentials(
clientId: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
apiKey: 'YOUR_API_KEY',
),
loggingEnabled: true, // Optionally enable logging. This is disabled by default
);
// Get the token service using K2ConnectFlutter
final TokenService tokenService = K2ConnectFlutter.tokenService();
// Get the access token using the token service
final TokenResponse tokenResponse = await tokenService.requestAccessToken();
// Print the response
print("Token response: $tokenResponse");
On success the response has JSON structured like this
{
"access_token": "JCGQXLrlfuOqdUYdTcLz3rBiCZQDRvdWIUPkw++GMuGhkem9Bo",
"token_type": "Bearer",
"expires_in": 3600,
"created_at": "2026-04-27T00:09:15+03:00"
}
{
"access_token": "JCGQXLrlfuOqdUYdTcLz3rBiCZQDRvdWIUPkw++GMuGhkem9Bo",
"token_type": "Bearer",
"expires_in": 3600,
"created_at": "2026-04-27T00:09:15+03:00"
}
{
"access_token": "JCGQXLrlfuOqdUYdTcLz3rBiCZQDRvdWIUPkw++GMuGhkem9Bo",
"token_type": "Bearer",
"expires_in": 3600,
"created_at": "2026-04-27T00:09:15+03:00"
}
{
"access_token": "JCGQXLrlfuOqdUYdTcLz3rBiCZQDRvdWIUPkw++GMuGhkem9Bo",
"token_type": "Bearer",
"expires_in": 3600,
"created_at": "2026-04-27T00:09:15+03:00"
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"accessToken" => "JCGQXLrlfuOqdUYdTcLz3rBiCZQDRvdWIUPkw++GMuGhkem9Bo",
"tokenType" => "Bearer",
"expiresIn" => 3600,
"createdAt" => "2026-04-27T00:09:15+03:00"
]
]
{
"accessToken": "JCGQXLrlfuOqdUYdTcLz3rBiCZQDRvdWIUPkw++GMuGhkem9Bo",
"tokenType": "Bearer",
"expiresIn": 3600,
"createdAt": "2026-04-27T00:09:15+03:00"
}
The client credentials flow is the simplest OAuth 2 grant, with a server-to-server exchange of your application’s client_id, client_secret for an
OAuth application access token. In order to execute this flow, you will need to make an HTTP request from your application server, to the Kopo Kopo authorization server.
HTTP Request
POST https://sandbox.kopokopo.com/oauth/token User-Agent: "< product >/< product-version > < comment >"
Request Parameters
| Parameter | Required | Type | Description |
|---|---|---|---|
| client_id | yes | string | Application key. Navigate to https://app.kopokopo.com/applications (production) or https://sandbox.kopokopo.com/applications (Sandbox) for your application key |
| client_secret | yes | string | Application secret. Only revealed to the user when creating an application or during regeneration of client credentials. |
| grant_type | yes | string | This must be set to client_credentials. |
Revoke application's access token
To revoke an application's access token, use this code:
require 'k2-connect-ruby'
# Using K2 Connect, the assumption here is that you have already initialized the API Client
K2Config.set_base_url('sandbox.kopokopo.com')
k2_token = K2AccessToken.new('your_client_id', 'your_client_secret')
access_token = k2_token.request_token
k2_token.revoke_token(access_token)
import k2connect
k2connect.initialize('your_client_id', 'your_client_secret', 'sandbox.kopokopo.com')
token_service = k2connect.Tokens
access_token_request = token_service.request_access_token()
access_token = token_service.get_access_token(access_token_request)
token_service.revoke_access_token(access_token)
# Pass the correct parameters with each request
curl -H "User-Agent: <product>/<product-version> <comment>"
-F "client_id=9b36d8c0db59eff5038aea7a417d73e69aea75b41aac771816d2ef1b3109cc2f"
-F "client_secret=d6ea27703957b69939b8104ed4524595e210cd2e79af587744a7eb6e58f5b3d2"
-F "token=dbaf9757982a9e738f05d249b7b5b4a266b3a139049317c4909f2f263572c781"
-X POST "http://localhost:3000/oauth/revoke"
const options = {
clientId: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
baseUrl: 'https://sandbox.kopokopo.com',
apiKey: 'YOUR_API_KEY',
}
// Including the kopokopo module
var K2 = require("k2-connect-node")(options)
const TokenService = K2.TokenService
TokenService
.revokeToken({accessToken: 'my_access_token'})
.then(response => {
// Response will be empty if it is successful
console.log(response)
})
.catch( error => {
console.log(error);
})
<?
use Kopokopo\SDK\K2;
$clientId = 'YOUR_CLIENT_ID'; // use your sandbox app client ID for development
$clientSecret = 'YOUR_CLIENT_SECRET'; // use your sandbox app API key for development
$baseUrl = 'sandbox.kopokopo.com'; // Use appropriate url for the different environments
$K2 = new K2($clientId, $clientSecret, $baseUrl);
// Get one of the services
$tokens = $K2->TokenService();
// Use the service
$result = $tokens->revokeToken(['accessToken' => 'my_access_token']);
if($result['status'] == 'success'){
// Data will be empty if successful
$data = $result['data'];
}
// Ensure K2ConnectFlutter is initialized
await K2ConnectFlutter.initialize(
baseUrl: 'sandbox.kopokopo.com',
credentials: K2ConnectCredentials(
clientId: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
apiKey: 'YOUR_API_KEY',
),
loggingEnabled: true, // Optionally enable logging. This is disabled by default
);
// Get the token service using K2ConnectFlutter
final TokenService tokenService = K2ConnectFlutter.tokenService();
// Use the token service to revoke your token
// If the request fails, an exception will be thrown
try {
await tokenService.revokeAccessToken('accessToken');
} catch (exception) {
print('Revoking token failed with exception: $exception');
}
On success a 200 response with an empty body is returned
{}
{}
{}
{}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => []
]
{}
The request is used to revoke a particular token at a time.
HTTP Request
POST https://sandbox.kopokopo.com/oauth/revoke User-Agent: "< product >/< product-version > < comment >"
Request Parameters
| Parameter | Required | Type | Description |
|---|---|---|---|
| client_id | yes | string | Application key. Navigate to https://app.kopokopo.com/applications (production) or https://sandbox.kopokopo.com/applications (Sandbox) for your application key |
| client_secret | yes | string | Application secret. Only revealed to the user when creating an application or during regeneration of client credentials. |
| token | yes | string | The access token belonging to the application that is to be revoked. |
Request token introspection
To introspect an application access token, use this code:
require 'k2-connect-ruby'
# Using K2 Connect, the assumption here is that you have already initialized the API Client
K2Config.set_base_url('sandbox.kopokopo.com')
k2_token = K2AccessToken.new('your_client_id', 'your_client_secret')
access_token = k2_token.request_token
k2_token.introspect_token(access_token)
import k2connect
k2connect.initialize('your_client_id', 'your_client_secret', 'sandbox.kopokopo.com')
token_service = k2connect.Tokens
access_token_request = token_service.request_access_token()
access_token = token_service.get_access_token(access_token_request)
token_service.introspect_access_token(access_token)
# With json, pass the correct parameters with each request
curl -H "User-Agent: <product>/<product-version> <comment>"
-F "client_id=9b36d8c0db59eff5038aea7a417d73e69aea75b41aac771816d2ef1b3109cc2f"
-F "client_secret=d6ea27703957b69939b8104ed4524595e210cd2e79af587744a7eb6e58f5b3d2"
-F "token=dbaf9757982a9e738f05d249b7b5b4a266b3a139049317c4909f2f263572c781"
-X POST "http://localhost:3000/oauth/introspect"
const options = {
clientId: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
baseUrl: 'https://sandbox.kopokopo.com',
apiKey: 'YOUR_API_KEY',
}
//Including the kopokopo module
var K2 = require("k2-connect-node")(options)
const TokenService = K2.TokenService
TokenService
.introspectToken({ accessToken: 'my_access_token' })
.then(response => {
//Developer can decide to store the token_details and track expiry
console.log(response)
})
.catch( error => {
console.log(error);
})
<?
use Kopokopo\SDK\K2;
$clientId = 'YOUR_CLIENT_ID'; // use your sandbox app client ID for development
$clientSecret = 'YOUR_CLIENT_SECRET'; // use your sandbox app API key for development
$baseUrl = 'sandbox.kopokopo.com'; // Use appropriate url for the different environments
$K2 = new K2($clientId, $clientSecret, $baseUrl);
// Get one of the services
$tokens = $K2->TokenService();
// Use the service
$result = $tokens->introspectToken(['accessToken' => 'my_access_token']);
if($result['status'] == 'success'){
echo $result['data'];
}
On success the response has JSON structured like this
{
"active": true,
"scope": "",
"client_id": "_9fXMGROLmSegBhofF6z-qDKHH5L6FsbMn2MgG24Xnk",
"token_type": "Bearer",
"exp": 1613384155,
"iat": 1613376955
}
{
"active": true,
"scope": "",
"client_id": "_9fXMGROLmSegBhofF6z-qDKHH5L6FsbMn2MgG24Xnk",
"token_type": "Bearer",
"exp": 1613384155,
"iat": 1613376955
}
{
"active": true,
"scope": "",
"client_id": "_9fXMGROLmSegBhofF6z-qDKHH5L6FsbMn2MgG24Xnk",
"token_type": "Bearer",
"exp": 1613384155,
"iat": 1613376955
}
{
"active": true,
"scope": "",
"client_id": "_9fXMGROLmSegBhofF6z-qDKHH5L6FsbMn2MgG24Xnk",
"token_type": "Bearer",
"exp": 1613384155,
"iat": 1613376955
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"accessToken" => "JCGQXLrlfuOqdUYdTcLz3rBiCZQDRvdWIUPkw++GMuGhkem9Bo",
"active" => true,
"scope" => "",
"clientId" => "_9fXMGROLmSegBhofF6z-qDKHH5L6FsbMn2MgG24Xnk",
"tokenType" => "Bearer",
"exp" => 1613384155,
"iat" => 1613376955
]
]
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
It can be used to check the validity of your access tokens, and find out other information such as which user and which scopes are associated with the token. The client secret will not be displayed as that is to remain confidential with the application owner.
HTTP Request
POST https://sandbox.kopokopo.com/oauth/introspect User-Agent: "< product >/< product-version > < comment >"
Request Parameters
| Parameter | Required | Type | Description |
|---|---|---|---|
| client_id | yes | string | Application key. Navigate to https://app.kopokopo.com/applications (production) or https://sandbox.kopokopo.com/applications (Sandbox) for your application key |
| client_secret | yes | string | Application secret. Only revealed to the user when creating an application or during regeneration of client credentials. |
| token | yes | string | The access token belonging to the application. |
Request token information
To request information concerning an application's access token, use this code:
require 'k2-connect-ruby'
# Using K2 Connect, the assumption here is that you have already initialized the API Client
K2Config.set_base_url('sandbox.kopokopo.com')
k2_token = K2AccessToken.new('your_client_id', 'your_client_secret')
access_token = k2_token.request_token
k2_token.token_info(access_token)
import k2connect
k2connect.initialize('your_client_id', 'your_client_secret', 'sandbox.kopokopo.com')
token_service = k2connect.Tokens
access_token_request = token_service.request_access_token()
access_token = token_service.get_access_token(access_token_request)
token_service.request_token_info(access_token)
# With json, you can just pass the correct header with each request
curl -H "Authorization: Bearer access_token"
-H "User-Agent: <product>/<product-version> <comment>"
"https://sandbox.kopokopo.com/oauth/token/info"
const options = {
clientId: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
baseUrl: 'https://sandbox.kopokopo.com',
apiKey: 'YOUR_API_KEY',
}
//Including the kopokopo module
var K2 = require("k2-connect-node")(options)
const TokenService = K2.TokenService
TokenService
.infoToken({accessToken: 'my_access_token'})
.then(response => {
//Developer can decide to store the token_details and track expiry
console.log(response)
})
.catch( error => {
console.log(error);
})
<?
use Kopokopo\SDK\K2;
$clientId = 'YOUR_CLIENT_ID'; // use your sandbox app client ID for development
$clientSecret = 'YOUR_CLIENT_SECRET'; // use your sandbox app API key for development
$baseUrl = 'sandbox.kopokopo.com'; // Use appropriate url for the different environments
$K2 = new K2($clientId, $clientSecret, $baseUrl);
// Get one of the services
$tokens = $K2->TokenService();
// Use the service
$result = $tokens->infoToken(['accessToken' => 'my_access_token']);
if($result['status'] == 'success'){
$data = $result['data'];
echo "My access token is: ".$data['access_token'];
echo "It expires in: ".$data['expires_in'];
}
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
On success the response has JSON structured like this
{
"resource_owner_id": null,
"scope": [],
"expires_in": 4498,
"application": {
"uid": "_9fXMGROLmSegBhofF6z-qDKHH5L6FsbMn2MgG24Xnk"
},
"created_at": 1613376955
}
{
"resource_owner_id": null,
"scope": [],
"expires_in": 4498,
"application": {
"uid": "_9fXMGROLmSegBhofF6z-qDKHH5L6FsbMn2MgG24Xnk"
},
"created_at": 1613376955
}
{
"resource_owner_id": null,
"scope": [],
"expires_in": 4498,
"application": {
"uid": "_9fXMGROLmSegBhofF6z-qDKHH5L6FsbMn2MgG24Xnk"
},
"created_at": 1613376955
}
{
"resource_owner_id": null,
"scope": [],
"expires_in": 4498,
"application": {
"uid": "_9fXMGROLmSegBhofF6z-qDKHH5L6FsbMn2MgG24Xnk"
},
"created_at": 1613376955
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"accessToken" => "JCGQXLrlfuOqdUYdTcLz3rBiCZQDRvdWIUPkw++GMuGhkem9Bo",
"resourceOwnerId" => null,
"scope" => [],
"expires_in" => 4498,
"applicationId" => "_9fXMGROLmSegBhofF6z-qDKHH5L6FsbMn2MgG24Xnk",
"createdAt" => 1613376955
]
]
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
Shows details about the token used for authentication.
HTTP Request
GET https://sandbox.kopokopo.com/oauth/token/info User-Agent: "< product >/< product-version > < comment >"
Webhooks
Webhooks are a means of getting notified of events in the Kopo Kopo application. To receive webhooks, you need to create a webhook subscription. See developer guide
Create a webhook subscription
POST https://sandbox.kopokopo.com/api/v2/webhook_subscriptions Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: "< product >/< product-version > < comment >"
{
"event_type": "buygoods_transaction_received",
"url": "https://myapplication.com/webhooks",
"scope": "till",
"scope_reference": "555555",
"enable_daraja_payload": false
}
# Using K2Connect - https://github.com/kopokopo/k2-connect-ruby (Recommended)
require 'k2-connect-ruby'
app_token = K2AccessToken.new('your_client_id', 'your_client_secret').request_token
subscription = K2Subscribe.new(app_token)
event_subscription = {
event_type: "b2b_transaction_received",
url: "callback_url",
scope: "till",
scope_reference: "555555",
enable_daraja_payload: false
}
subscription.webhook_subscribe(event_subscription)
subscription.location_url # => "https://sandbox.kopokopo.com/api/v2/webhook_subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216"
const Webhooks = K2.Webhooks
var requestBody = {
eventType: 'buygoods_transaction_received',
url: 'https://myawesomeapplication.com/destination',
scope: 'till',
scopeReference: '555555', // Your till number
accessToken: 'my_access_token',
enableDarajaPayload: false
}
Webhooks
.subscribe(subscribeOptions)
.then(response => { console.log(response) })
.catch(error => { console.log(error) })
// => 'https://sandbox.kopokopo.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216'
<?
$webhooks = $K2->Webhooks();
$response = $webhooks->subscribe([
'eventType' => 'buygoods_transaction_received',
'url' => 'https://myawesomeapplication.com/destination',
'scope' => 'till',
'scopeReference' => '555555', // Your till number
'accessToken' => 'my_access_token',
'enableDarajaPayload' => 'false'
]);
if($response['status'] == 'success')
{
echo "The resource location is:" . json_encode($response['location']);
}
// => 'https://sandbox.kopokopo.com/webhook-subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216'
import k2connect
payload = {
"access_token": ACCESS_TOKEN,
"event_type": 'buygoods_transaction_received',
"webhook_endpoint": 'https://webhook.site/52fd1913-778e-4ee1-bdc4-74517abb758d',
"scope": 'till',
"scope_reference": '112233',
"enable_daraja_payload": True
}
k2connect.initialize(CLIENT_ID, CLIENT_SECRET, BASE_URL)
webhook_service = k2connect.Webhooks
subscription_location = webhook_service.create_subscription(payload)
subscription_location # => "https://sandbox.kopokopo.com/api/v2/webhook_subscriptions/5af4c10a-f6de-4ac8-840d-42cb65454216"
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
HTTP Request
POST https://sandbox.kopokopo.com/api/v2/webhook_subscriptions
Request Parameters (JSON)
| Parameter | Required | Type | Description |
|---|---|---|---|
| event_type | yes | string | The type of event you are subscribing to. Should be one of: buygoods_transaction_received, buygoods_transaction_reversed, b2b_transaction_received, b2b_transaction_reversed,settlement_transfer_completed, card_transaction_received, card_transaction_voided, card_transaction_reversed |
| url | yes | string | The HTTPS end point to send the webhook. MUST be secured with HTTPS (TLS) |
| scope | yes | string | The scope of the webhook subscription. Could be either company or till |
| scope_reference | yes | string | If the scope is till the scope reference is required and it should be your till number |
| enable_daraja_payload | no | Boolean | Configuration used to determine the payload structure that the webhook notifications will use. Either the Daraja API payload structure (true) or the K2Connect API payload structure (false). Defaulted to false. |
HTTP Response
Successful Response
Upon successful creation of the webhook subscription, HTTP Status Code 201 with the URL of the subscription in the Location Header of the HTTP Response.
HTTP/1.1 201 Created
Location: https://sandbox.kopokopo.com/api/v2/webhook_subscriptions/d76265cd-0951-e511-80da-0aa34a9b2388
Error Response
This will have a HTTP Status code indicating the error and it might have a json that contains the error code and an error message specifying the error that occured. Please note that the error response might not be present depending on the type of error that occured.
If the error json response is present, it will look as follows:
HTTP/1.1 400 Bad Request
{ "error_code": 400, "error_message": "Invalid scope reference" }
Validating webhooks
webhook_test = K2Client.new(ENV["API_KEY"])
webhook_test.parse_request(request)
webhook_payload = webhook_test.hash_body
processed_payload = K2ProcessWebhook.process(webhook_payload, secret, webhook_test.k2_signature)
k2connect.initialize(CLIENT_SECRET, CLIENT_SECRET, BASE_URL)
result_handler = k2connect.ResultHandler
processed_payload = result_handler.process(request)
const Webhooks = K2.Webhooks
//Router or whatever server you are using
// This is the endpoint you used when subscribing
router.post('/buygoodsreceived', function(req, res, next){
// This will both validate and process the payload for you
Webhooks
.webhookHandler(req, res)
.then( response => {
console.log(response)
})
.catch( error => {
console.log(error)
})
})
<?
$webhooks = $K2->Webhooks();
$webhook_payload = file_get_contents('php://input');
// This will both validate and process the payload for you
$response = $webhooks->webhookHandler($webhook_payload, $_SERVER['HTTP_X_KOPOKOPO_SIGNATURE']);
echo json_encode($response);
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
Before processing webhook events, make sure that they originated from Kopo Kopo.Each request is signed with the api_key you got when creating an oauth application on the platform.
The signature is contained in the X-KopoKopo-Signature header and is a SHA256 HMAC hash of the request body with
the key being your API Key.
Buygoods Transaction Received
Notifies your application when a Buygoods Transaction has been received.
Buygoods Transaction Received webhook notifications are in two formats:
K2Connect Payload structure
Daraja Payload structure
POST https://www.your-application.com/payments/webhook Content-Type: application/json User-Agent: < product >/< product-version > < comment > X-KopoKopo-Signature: a5d74a17a55554edc4e9999c59e460c61aa7f81a
{
"topic": "buygoods_transaction_received",
"id": "2133dbfb-24b9-40fc-ae57-2d7559785760",
"created_at": "2026-05-01T10:43:20+03:00",
"event": {
"type": "Buygoods Transaction",
"resource": {
"id": "458712f-gr76y-24b9-40fc-ae57-2d35785760",
"amount": "100.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "OJM6Q1W84K",
"till_number": "000000",
"sender_phone_number": "+254999999999",
"hashed_sender_phone" : "cbc504704d2c654f8bf08de98945980b77567d8c611d355ca3aef480c960ad9c",
"origination_time": "2026-05-01T10:43:19+03:00",
"sender_first_name": "Jane",
"sender_last_name": null,
"sender_middle_name": null
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/2133dbfb-24b9-40fc-ae57-2d7559785760",
"resource": "https://sandbox.kopokopo.com/financial_transaction/458712f-gr76y-24b9-40fc-ae57-2d35785760"
}
}
{
"topic": "buygoods_transaction_received",
"id": "2133dbfb-24b9-40fc-ae57-2d7559785760",
"created_at": "2026-05-01T10:43:20+03:00",
"event": {
"type": "Buygoods Transaction",
"resource": {
"id": "458712f-gr76y-24b9-40fc-ae57-2d35785760",
"amount": "100.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "OJM6Q1W84K",
"till_number": "000000",
"sender_phone_number": "+254999999999",
"origination_time": "2026-05-01T10:43:19+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": null
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/2133dbfb-24b9-40fc-ae57-2d7559785760",
"resource": "https://sandbox.kopokopo.com/financial_transaction/458712f-gr76y-24b9-40fc-ae57-2d35785760"
}
}
{
"topic": "buygoods_transaction_received",
"id": "2133dbfb-24b9-40fc-ae57-2d7559785760",
"created_at": "2026-05-01T10:43:20+03:00",
"event": {
"type": "Buygoods Transaction",
"resource": {
"id": "458712f-gr76y-24b9-40fc-ae57-2d35785760",
"amount": "100.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "OJM6Q1W84K",
"till_number": "000000",
"sender_phone_number": "+254999999999",
"origination_time": "2026-05-01T10:43:19+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": null
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/2133dbfb-24b9-40fc-ae57-2d7559785760",
"resource": "https://sandbox.kopokopo.com/financial_transaction/458712f-gr76y-24b9-40fc-ae57-2d35785760"
}
}
{
"topic": "buygoods_transaction_received",
"id": "2133dbfb-24b9-40fc-ae57-2d7559785760",
"created_at": "2026-05-01T10:43:20+03:00",
"event": {
"type": "Buygoods Transaction",
"resource": {
"id": "458712f-gr76y-24b9-40fc-ae57-2d35785760",
"amount": "100.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "OJM6Q1W84K",
"till_number": "000000",
"sender_phone_number": "+254999999999",
"origination_time": "2026-05-01T10:43:19+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": null
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/2133dbfb-24b9-40fc-ae57-2d7559785760",
"resource": "https://sandbox.kopokopo.com/financial_transaction/458712f-gr76y-24b9-40fc-ae57-2d35785760"
}
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"id" => "cac95329-9fa5-42f1-a4fc-c08af7b868fb",
"topic" => "buygoods_transaction_received",
"created_at" => "2018-06-20T22:45:12.790Z",
"eventType" =>"Buygoods Transaction",
"resourceId" => "52f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"status" => "Received",
"reference" => '123456789',
"originationTime" => "2017-01-20T22:45:12.790Z",
"senderPhoneNumber" => "+2549703119050",
"amount" => 20000,
"currency" => "KES",
"tillNumber" => "000000",
"system" => "Lipa Na M-PESA",
"senderFirstName" => "John",
"senderMiddleName" => "O",
"senderLastName" => "Doe",
"linkSelf" => "https://sandbox.kopokopo.com/webhook_events/cac95329-9fa5-42f1-a4fc-c08af7b868fb",
"linkResource" => "https://sandbox.kopokopo.com/financial_transaction/458712f-gr76y-24b9-40fc-ae57-2d35785760",
]
]
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
K2Connect Webhook Parameters (JSON)
Parameters contained in a buygoods_transaction_received webhook;
| Parameter | Type | Description |
|---|---|---|
| id | String | The ID of the Webhook Event |
| topic | String | The topic of the webhook. buygoods_transaction_received in this instance. |
| created_at | String | The timestamp of when the webhook event was created. |
| _links | JSON | A JSON object containing links to the Webhook Event and the corresponding Buygoods Transaction resource |
Event JSON
| Parameter | Type | Description |
|---|---|---|
| type | String | The type of transaction (Buygoods Transaction) |
| resource | JSON | The resource corresponding to the event. In this case this is a Buygoods Transaction |
Resource (Buygoods Transaction) JSON
| Parameter | Type | Description |
|---|---|---|
| id | String | The api reference of the transaction |
| reference | String | The mpesa reference |
| status | String | The status of the transaction |
| origination_time | String | The transaction timestamp |
| sender_phone_number | String | The phone number that sent the payment |
| hashed_sender_phone | String | The hashed phone number that sent the payment |
| amount | Float | The amount of the transaction |
| currency | String | Currency |
| till_number | String | The till number to which the payment was made |
| system | String | The mobile money system |
| sender_first_name | String | First name of payer |
| sender_middle_name | String | Middle name of payer |
| sender_last_name | String | Last name of payer |
Daraja Webhook Parameters (JSON)
POST https://www.your-application.com/payments/webhook Content-Type: application/json User-Agent: < product >/< product-version > < comment > X-KopoKopo-Signature: a5d74a17a55554edc4e9999c59e460c61aa7f81a
{
"TransactionType": "Buygoods",
"TransID": "OJM6Q1W84K",
"TransTime": "20260501191515",
"TransAmount": "100.0",
"BusinessShortCode": "000000",
"BillRefNumber": "",
"InvoiceNumber": "",
"OrgAccountBalance": "",
"ThirdPartyTransId": "",
"MSISDN": "rbFvT0GstruVPN/B68z6yWD973VhweR31G8fhM5bxo=",
"FirstName": "Jane",
"MiddleName": null,
"LastName": null
}
{
"TransactionType": "Buygoods",
"TransID": "OJM6Q1W84K",
"TransTime": "20260501191515",
"TransAmount": "100.0",
"BusinessShortCode": "000000",
"BillRefNumber": "",
"InvoiceNumber": "",
"OrgAccountBalance": "",
"ThirdPartyTransId": "",
"MSISDN": "rbFvT0GstruVPN/B68z6yWD973VhweR31G8fhM5bxo=",
"FirstName": "Jane",
"MiddleName": null,
"LastName": null
}
{
"TransactionType": "Buygoods",
"TransID": "OJM6Q1W84K",
"TransTime": "20260501191515",
"TransAmount": "100.0",
"BusinessShortCode": "000000",
"BillRefNumber": "",
"InvoiceNumber": "",
"OrgAccountBalance": "",
"ThirdPartyTransId": "",
"MSISDN": "rbFvT0GstruVPN/B68z6yWD973VhweR31G8fhM5bxo=",
"FirstName": "Jane",
"MiddleName": null,
"LastName": null
}
{
"TransactionType": "Buygoods",
"TransID": "OJM6Q1W84K",
"TransTime": "20260501191515",
"TransAmount": "100.0",
"BusinessShortCode": "000000",
"BillRefNumber": "",
"InvoiceNumber": "",
"OrgAccountBalance": "",
"ThirdPartyTransId": "",
"MSISDN": "rbFvT0GstruVPN/B68z6yWD973VhweR31G8fhM5bxo=",
"FirstName": "Jane",
"MiddleName": null,
"LastName": null
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"TransactionType": "Buygoods",
"TransID": "OJM6Q1W84K",
"TransTime": "20260501191515",
"TransAmount": "100.0",
"BusinessShortCode": "000000",
"BillRefNumber": "",
"InvoiceNumber": "",
"OrgAccountBalance": "",
"ThirdPartyTransId": "",
"MSISDN": "rbFvT0GstruVPN/B68z6yWD973VhweR31G8fhM5bxo=",
"FirstName": "Jane",
"MiddleName": null,
"LastName": null
]
]
Parameters contained in a buygoods_transaction_received daraja webhook;
| Parameter | Type | Description |
|---|---|---|
| TransactionType | String | The type of transaction (Buygoods in this instance) |
| TransID | String | The transaction reference. |
| TransTime | String | The timestamp in the format YYYYMMDDhhmmss of when the transaction occurred. |
| TransAmount | Float | The amount of the transaction |
| BusinessShortCode | String | The till number to which the payment was made to |
| BillRefNumber | String | Empty |
| InvoiceNumber | String | Empty |
| OrgAccountBalance | String | Empty |
| ThirdPartyTransId | String | Empty |
| MSISDN | String | The hashed phone number that sent the payment |
| FirstName | String | First name for customer who sent the payment |
| MiddleName | String | Empty |
| LastName | String | Empty |
B2B Transaction Received
Notifies your application when a B2B (External Till to Till transaction) has been received. These are payments received from other tills and not subscribers.
B2B Transaction Received webhook notifications are in two formats:
K2Connect Payload structure
Daraja Payload structure
POST https://www.your-application.com/payments/webhook Content-Type: application/json User-Agent: < product >/< product-version > < comment > X-KopoKopo-Signature: a5d74a17a55554edc4e9999c59e460c61aa7f81a
{
"topic": "b2b_transaction_received",
"id": "bcfb7175-bc7f-46e8-9727-eb46e6f88ef1",
"created_at": "2020-10-29T08:18:45+03:00",
"event": {
"type": "External Till to Till Transaction",
"resource": {
"id": "fbygwu7175-bc7f-46e8-9727-f88edyy",
"amount": "313",
"status": "Complete",
"system": "Lipa Na Mpesa",
"currency": "KES",
"reference": "OJQ8USH5XK",
"till_number": "000000",
"sending_till": "890642",
"origination_time": "2020-10-29T08:18:45+03:00"
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/bcfb7175-bc7f-46e8-9727-eb46e6f88ef1",
"resource": "https://sandbox.kopokopo.com/financial_transaction/fbygwu7175-bc7f-46e8-9727-f88edyy"
}
}
{
"topic": "b2b_transaction_received",
"id": "bcfb7175-bc7f-46e8-9727-eb46e6f88ef1",
"created_at": "2020-10-29T08:18:45+03:00",
"event": {
"type": "External Till to Till Transaction",
"resource": {
"id": "fbygwu7175-bc7f-46e8-9727-f88edyy",
"amount": "313",
"status": "Complete",
"system": "Lipa Na Mpesa",
"currency": "KES",
"reference": "OJQ8USH5XK",
"till_number": "000000",
"sending_till": "000001",
"origination_time": "2020-10-29T08:18:45+03:00"
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/bcfb7175-bc7f-46e8-9727-eb46e6f88ef1",
"resource": "https://sandbox.kopokopo.com/financial_transaction/fbygwu7175-bc7f-46e8-9727-f88edyy"
}
}
{
"topic": "b2b_transaction_received",
"id": "bcfb7175-bc7f-46e8-9727-eb46e6f88ef1",
"created_at": "2020-10-29T08:18:45+03:00",
"event": {
"type": "External Till to Till Transaction",
"resource": {
"id": "fbygwu7175-bc7f-46e8-9727-f88edyy",
"amount": "313",
"status": "Complete",
"system": "Lipa Na Mpesa",
"currency": "KES",
"reference": "OJQ8USH5XK",
"till_number": "000000",
"sending_till": "000001",
"origination_time": "2020-10-29T08:18:45+03:00"
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/bcfb7175-bc7f-46e8-9727-eb46e6f88ef1",
"resource": "https://sandbox.kopokopo.com/financial_transaction/fbygwu7175-bc7f-46e8-9727-f88edyy"
}
}
{
"topic": "b2b_transaction_received",
"id": "bcfb7175-bc7f-46e8-9727-eb46e6f88ef1",
"created_at": "2020-10-29T08:18:45+03:00",
"event": {
"type": "External Till to Till Transaction",
"resource": {
"id": "fbygwu7175-bc7f-46e8-9727-f88edyy",
"amount": "313",
"status": "Complete",
"system": "Lipa Na Mpesa",
"currency": "KES",
"reference": "OJQ8USH5XK",
"till_number": "000000",
"sending_till": "000001",
"origination_time": "2020-10-29T08:18:45+03:00"
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/bcfb7175-bc7f-46e8-9727-eb46e6f88ef1",
"resource": "https://sandbox.kopokopo.com/financial_transaction/fbygwu7175-bc7f-46e8-9727-f88edyy"
}
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"id" => "cac95329-9fa5-42f1-a4fc-c08af7b868fb",
"topic" => "b2b_transaction_received",
"createdAt" => "2018-06-20T22:45:12.790Z",
"eventType" =>"External Till to Till Transaction",
"resourceId" => "52f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"status" => "Received",
"system" => "Lipa Na Mpesa",
"reference" => '123456789',
"originationTime" => "2017-01-20T22:45:12.790Z",
"sendingTill" => "+2549703119050",
"amount" => 20000,
"currency" => "KES",
"tillNumber" => "000000",
"linkSelf" => "https://sandbox.kopokopo.com/webhook_events/cac95329-9fa5-42f1-a4fc-c08af7b868fb",
"linkResource" => "https://sandbox.kopokopo.com/financial_transaction/458712f-gr76y-24b9-40fc-ae57-2d35785760",
]
]
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
Notifies your application when a B2b (External Till to Till transaction) has been received. These are payments recieved from other tills and not subscribers.
K2Connect Webhook Parameters (JSON)
Parameters contained in a b2b_transaction_received webhook;
| Parameter | Type | Description |
|---|---|---|
| id | String | The ID of the Webhook Event |
| topic | String | The topic of the webhook. b2b_transaction_received in this instance. |
| created_at | String | The timestamp of when the webhook event was created. |
| _links | JSON | A JSON object containing links to the Webhook Event and the corresponding B2B Transaction resource |
Event JSON
| Parameter | Type | Description |
|---|---|---|
| type | String | The type of transaction (B2B Transaction) |
| resource | JSON | The resource corresponding to the event. In this case this is a Buygoods Transaction |
Resource (Buygoods Transaction) JSON
| Parameter | Type | Description |
|---|---|---|
| id | String | The api reference of the transaction |
| reference | String | The mpesa reference |
| origination_time | String | The transaction timestamp |
| sending_till | String | The till number of the sender |
| status | String | The status of the transaction |
| amount | Float | The amount of the transaction |
| currency | String | Currency |
| till_number | String | The till number to which the payment was made |
| system | String | The mobile money system |
Daraja Webhook Parameters (JSON)
POST https://www.your-application.com/payments/webhook Content-Type: application/json User-Agent: < product >/< product-version > < comment > X-KopoKopo-Signature: a5d74a17a55554edc4e9999c59e460c61aa7f81a
{
"TransactionType": "Organization To Organization Transfer",
"TransID": "OJM6Q1W84K",
"TransTime": "20260501191515",
"TransAmount": "100.0",
"BusinessShortCode": "000000",
"BillRefNumber": "",
"InvoiceNumber": "",
"OrgAccountBalance": "",
"ThirdPartyTransId": "",
"MSISDN": "112233",
"FirstName": "Organization name",
"MiddleName": null,
"LastName": null
}
{
"TransactionType": "Organization To Organization Transfer",
"TransID": "OJM6Q1W84K",
"TransTime": "20260501191515",
"TransAmount": "100.0",
"BusinessShortCode": "000000",
"BillRefNumber": "",
"InvoiceNumber": "",
"OrgAccountBalance": "",
"ThirdPartyTransId": "",
"MSISDN": "112233",
"FirstName": "Organization name",
"MiddleName": nil,
"LastName": nil
}
{
"TransactionType": "Organization To Organization Transfer",
"TransID": "OJM6Q1W84K",
"TransTime": "20260501191515",
"TransAmount": "100.0",
"BusinessShortCode": "000000",
"BillRefNumber": "",
"InvoiceNumber": "",
"OrgAccountBalance": "",
"ThirdPartyTransId": "",
"MSISDN": "112233",
"FirstName": "Organization name",
"MiddleName": null,
"LastName": null
}
{
"TransactionType": "Organization To Organization Transfer",
"TransID": "OJM6Q1W84K",
"TransTime": "20260501191515",
"TransAmount": "100.0",
"BusinessShortCode": "000000",
"BillRefNumber": "",
"InvoiceNumber": "",
"OrgAccountBalance": "",
"ThirdPartyTransId": "",
"MSISDN": "112233",
"FirstName": "Organization name",
"MiddleName": null,
"LastName": null
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"TransactionType": "Organization To Organization Transfer",
"TransID": "OJM6Q1W84K",
"TransTime": "20260501191515",
"TransAmount": "100.0",
"BusinessShortCode": "000000",
"BillRefNumber": "",
"InvoiceNumber": "",
"OrgAccountBalance": "",
"ThirdPartyTransId": "",
"MSISDN": "112233",
"FirstName": "Organization name",
"MiddleName": null,
"LastName": null
]
]
Parameters contained in a b2b_transaction_received webhook;
| Parameter | Type | Description |
|---|---|---|
| TransactionType | String | The type of transaction (Organization To Organization Transfer in this instance) |
| TransID | String | The transaction reference. |
| TransTime | String | The timestamp in the format YYYYMMDDhhmmss of when the transaction occurred. |
| TransAmount | Float | The amount of the transaction |
| BusinessShortCode | String | The till number to which the payment was made to |
| BillRefNumber | String | Empty |
| InvoiceNumber | String | Empty |
| OrgAccountBalance | String | Empty |
| ThirdPartyTransId | String | Empty |
| MSISDN | String | Till number or paybill number that sent the payment |
| FirstName | String | Organization name for till or paybill that sent payment |
| MiddleName | String | Empty |
| LastName | String | Empty |
Buygoods Transaction Reversed
POST https://www.your-application.com/payments/webhook Content-Type: application/json User-Agent: < product >/< product-version > < comment > X-KopoKopo-Signature: a5d74a17a55554edc4e9999c59e460c61aa7f81a
{
"topic": "buygoods_transaction_reversed",
"id": "98adf21e-5721-476a-8643-609b4a6513a2",
"created_at": "2020-10-29T08:06:49+03:00",
"event": {
"type": "Buygoods Transaction",
"resource": {
"id": "86345adf21e-5721-476a-8643-609b4a863",
"amount": "233",
"status": "Reversed",
"system": "Lipa Na Mpesa",
"currency": "KES",
"reference": "OJM6Q1W84K",
"till_number": "000000",
"origination_time": "2020-10-29T08:06:49+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": "",
"sender_phone_number": "+254999999999"
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/98adf21e-5721-476a-8643-609b4a6513a2",
"resource": "https://sandbox.kopokopo.com/financial_transaction/86345adf21e-5721-476a-8643-609b4a863"
}
}
{
"topic": "buygoods_transaction_reversed",
"id": "98adf21e-5721-476a-8643-609b4a6513a2",
"created_at": "2020-10-29T08:06:49+03:00",
"event": {
"type": "Buygoods Transaction",
"resource": {
"id": "86345adf21e-5721-476a-8643-609b4a863",
"amount": "233",
"status": "Reversed",
"system": "Lipa Na Mpesa",
"currency": "KES",
"reference": "OJM6Q1W84K",
"till_number": "000000",
"origination_time": "2020-10-29T08:06:49+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": "",
"sender_phone_number": "+254999999999"
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/98adf21e-5721-476a-8643-609b4a6513a2",
"resource": "https://sandbox.kopokopo.com/financial_transaction/86345adf21e-5721-476a-8643-609b4a863"
}
}
{
"topic": "buygoods_transaction_reversed",
"id": "98adf21e-5721-476a-8643-609b4a6513a2",
"created_at": "2020-10-29T08:06:49+03:00",
"event": {
"type": "Buygoods Transaction",
"resource": {
"id": "86345adf21e-5721-476a-8643-609b4a863",
"amount": "233",
"status": "Reversed",
"system": "Lipa Na Mpesa",
"currency": "KES",
"reference": "OJM6Q1W84K",
"till_number": "000000",
"origination_time": "2020-10-29T08:06:49+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": "",
"sender_phone_number": "+254999999999"
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/98adf21e-5721-476a-8643-609b4a6513a2",
"resource": "https://sandbox.kopokopo.com/financial_transaction/86345adf21e-5721-476a-8643-609b4a863"
}
}
{
"topic": "buygoods_transaction_reversed",
"id": "98adf21e-5721-476a-8643-609b4a6513a2",
"created_at": "2020-10-29T08:06:49+03:00",
"event": {
"type": "Buygoods Transaction",
"resource": {
"id": "86345adf21e-5721-476a-8643-609b4a863",
"amount": "233",
"status": "Reversed",
"system": "Lipa Na Mpesa",
"currency": "KES",
"reference": "OJM6Q1W84K",
"till_number": "000000",
"origination_time": "2020-10-29T08:06:49+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": "",
"sender_phone_number": "+254999999999"
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/98adf21e-5721-476a-8643-609b4a6513a2",
"resource": "https://sandbox.kopokopo.com/financial_transaction/86345adf21e-5721-476a-8643-609b4a863"
}
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"id" => "cac95329-9fa5-42f1-a4fc-c08af7b868fb",
"topic" => "buygoods_transaction_reversed",
"created_at" => "2018-06-20T22:45:12.790Z",
"eventType" =>"Buygoods Transaction",
"resourceId" => "52f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"status" => "Received",
"reference" => '123456789',
"originationTime" => "2017-01-20T22:45:12.790Z",
"senderPhoneNumber" => "+2549703119050",
"amount" => 20000,
"currency" => "KES",
"tillNumber" => "000000",
"system" => "Lipa Na M-PESA",
"senderFirstName" => "John",
"senderMiddleName" => "O",
"senderLastName" => "Doe",
"linkSelf" => "https://sandbox.kopokopo.com/webhook_events/cac95329-9fa5-42f1-a4fc-c08af7b868fb",
"linkResource" => "https://sandbox.kopokopo.com/financial_transaction/458712f-gr76y-24b9-40fc-ae57-2d35785760",
]
]
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
Notifies your application when a Buygoods Transaction has been reversed
Buygoods Transaction Reversed Webhook Parameters (JSON)
Parameters contained in a buygoods_transaction_reversed webhook;
| Parameter | Type | Description |
|---|---|---|
| id | String | The ID of the Webhook Event |
| topic | String | The topic of the webhook. buygoods_transaction_reversed in this instance. |
| created_at | String | The timestamp of when the webhook event was created. |
| _links | JSON | A JSON object containing links to the Webhook Event and the corresponding Buygoods Transaction resource |
Event JSON
| Parameter | Type | Description |
|---|---|---|
| type | String | The type of transaction (Buygoods Transaction) |
| resource | JSON | The resource corresponding to the event. In this case this is a Buygoods Transaction |
Resource (Buygoods Transaction) JSON
| Parameter | Type | Description |
|---|---|---|
| id | String | The api reference of the transaction |
| reference | String | The mpesa reference |
| status | String | The status of the transaction |
| origination_time | String | The transaction timestamp |
| sender_phone_number | String | The phone number that sent the payment |
| amount | Float | The amount of the transaction |
| currency | String | Currency |
| till_number | String | The till number to which the payment was made |
| system | String | The mobile money system |
| sender_first_name | String | First name of payer |
| sender_middle_name | String | Middle name of payer |
| sender_last_name | String | Last name of payer |
B2B Transaction Reversed
POST https://www.your-application.com/payments/webhook Content-Type: application/json User-Agent: < product >/< product-version > < comment > X-KopoKopo-Signature: a5d74a17a55554edc4e9999c59e460c61aa7f81a
{
"topic": "b2b_transaction_reversed",
"id": "98adf21e-5721-476a-8643-609b4a6513a2",
"created_at": "2020-10-29T08:06:49+03:00",
"event": {
"type": "External Till To Till Reversal Transaction",
"resource": {
"id": "86345adf21e-5721-476a-8643-609b4a863",
"reference": "OJM6Q1W84K",
"origination_time": "2020-10-29T08:06:49+03:00",
"sending_till": "Sending till",
"amount": "233",
"currency": "KES",
"till_number": "000000",
"system": "M-PESA",
"status": "Reversed"
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/98adf21e-5721-476a-8643-609b4a6513a2",
"resource": "https://sandbox.kopokopo.com/financial_transaction/86345adf21e-5721-476a-8643-609b4a863"
}
}
{
"topic": "b2b_transaction_reversed",
"id": "98adf21e-5721-476a-8643-609b4a6513a2",
"created_at": "2020-10-29T08:06:49+03:00",
"event": {
"type": "External Till To Till Reversal Transaction",
"resource": {
"id": "86345adf21e-5721-476a-8643-609b4a863",
"reference": "OJM6Q1W84K",
"origination_time": "2020-10-29T08:06:49+03:00",
"sending_till": "Sending till",
"amount": "233",
"currency": "KES",
"till_number": "000000",
"system": "M-PESA",
"status": "Reversed"
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/98adf21e-5721-476a-8643-609b4a6513a2",
"resource": "https://sandbox.kopokopo.com/financial_transaction/86345adf21e-5721-476a-8643-609b4a863"
}
}
{
"topic": "b2b_transaction_reversed",
"id": "98adf21e-5721-476a-8643-609b4a6513a2",
"created_at": "2020-10-29T08:06:49+03:00",
"event": {
"type": "External Till To Till Reversal Transaction",
"resource": {
"id": "86345adf21e-5721-476a-8643-609b4a863",
"reference": "OJM6Q1W84K",
"origination_time": "2020-10-29T08:06:49+03:00",
"sending_till": "Sending till",
"amount": "233",
"currency": "KES",
"till_number": "000000",
"system": "M-PESA",
"status": "Reversed"
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/98adf21e-5721-476a-8643-609b4a6513a2",
"resource": "https://sandbox.kopokopo.com/financial_transaction/86345adf21e-5721-476a-8643-609b4a863"
}
}
{
"topic": "b2b_transaction_reversed",
"id": "98adf21e-5721-476a-8643-609b4a6513a2",
"created_at": "2020-10-29T08:06:49+03:00",
"event": {
"type": "External Till To Till Reversal Transaction",
"resource": {
"id": "86345adf21e-5721-476a-8643-609b4a863",
"reference": "OJM6Q1W84K",
"origination_time": "2020-10-29T08:06:49+03:00",
"sending_till": "Sending till",
"amount": "233",
"currency": "KES",
"till_number": "000000",
"system": "M-PESA",
"status": "Reversed"
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/98adf21e-5721-476a-8643-609b4a6513a2",
"resource": "https://sandbox.kopokopo.com/financial_transaction/86345adf21e-5721-476a-8643-609b4a863"
}
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"id" => "cac95329-9fa5-42f1-a4fc-c08af7b868fb",
"topic" => "b2b_transaction_reversed",
"created_at" => "2018-06-20T22:45:12.790Z",
"eventType" =>"External Till To Till Reversal Transaction",
"resourceId" => "52f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"reference" => "OJM6Q1W84K",
"origination_time" => "2020-10-29T08:06:49+03:00",
"sending_till" => "Sending till",
"amount" => "233",
"currency" => "KES",
"till_number" => "000000",
"system" => "M-PESA",
"status" => "Reversed"
"linkSelf" => "https://sandbox.kopokopo.com/webhook_events/cac95329-9fa5-42f1-a4fc-c08af7b868fb",
"linkResource" => "https://sandbox.kopokopo.com/financial_transaction/458712f-gr76y-24b9-40fc-ae57-2d35785760",
]
]
Notifies your application when a B2B Transaction has been reversed
B2B Transaction Reversed Webhook Parameters (JSON)
Parameters contained in a b2b_transaction_reversed webhook;
| Parameter | Type | Description |
|---|---|---|
| id | String | The ID of the Webhook Event |
| topic | String | The topic of the webhook. b2b_transaction_reversed in this instance. |
| created_at | String | The timestamp of when the webhook event was created. |
| _links | JSON | A JSON object containing links to the Webhook Event and the corresponding Buygoods Transaction resource |
Event JSON
| Parameter | Type | Description |
|---|---|---|
| type | String | The type of transaction (External Till To Till Reversal Transaction) |
| resource | JSON | The resource corresponding to the event. In this case this is a B2B Transaction Reversal |
Resource (Buygoods Transaction) JSON
| Parameter | Type | Description |
|---|---|---|
| id | String | The api reference of the transaction |
| reference | String | The mpesa reference |
| status | String | The status of the transaction |
| origination_time | String | The transaction timestamp |
| sending_till | String | The till number that sent the payment |
| amount | Float | The amount of the transaction |
| currency | String | Currency |
| till_number | String | The till number to which the payment was made |
| system | String | The mobile money system |
Settlement Transfer Completed
POST https://www.your-application.com/settlement_transfers/webhook Content-Type: application/json User-Agent: < product >/< product-version > < comment > X-KopoKopo-Signature: a5d74a17a55554edc4e9999c59e460c61aa7f81a
{
"topic": "settlement_transfer_completed",
"id": "052b7b2a-745b-4ca1-866b-b92d4a1418c3",
"created_at": "2021-01-27T11:00:08+03:00",
"event": {
"type": "Settlement Transfer",
"resource": {
"id": "270b7b2a-745b-6735752-b92d4a141847-5d33",
"amount": "49452.0",
"status": "Transferred",
"currency": "KES",
"destination": {
"type": "Bank Account",
"resource": {
"reference": "34a273d1-fedc-4610-8ab6-a1ba4828f317",
"account_name": "Test Account",
"account_number": "1234",
"bank_branch_ref": "ea2e79f7-35a1-486e-9e18-fe06589a9d7d",
"settlement_method": "EFT"
}
},
"disbursements": [
{
"amount": "24452.0",
"status": "Transferred",
"origination_time": "2021-01-27T10:57:58.623+03:00",
"transaction_reference": null
},
{
"amount": "25000.0",
"status": "Transferred",
"origination_time": "2021-01-27T10:57:58.627+03:00",
"transaction_reference": null
}
],
"origination_time": "2021-01-27T10:57:58.444+03:00"
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/052b7b2a-745b-4ca1-866b-b92d4a1418c3",
"resource": "https://sandbox.kopokopo.com/transfer_batch/270b7b2a-745b-6735752-b92d4a141847-5d33"
}
}
{
"topic": "settlement_transfer_completed",
"id": "052b7b2a-745b-4ca1-866b-b92d4a1418c3",
"created_at": "2021-01-27T11:00:08+03:00",
"event": {
"type": "Settlement Transfer",
"resource": {
"id": "270b7b2a-745b-6735752-b92d4a141847-5d33",
"amount": "49452.0",
"status": "Transferred",
"currency": "KES",
"destination": {
"type": "Bank Account",
"resource": {
"reference": "34a273d1-fedc-4610-8ab6-a1ba4828f317",
"account_name": "Test Account",
"account_number": "1234",
"bank_branch_ref": "ea2e79f7-35a1-486e-9e18-fe06589a9d7d",
"settlement_method": "EFT"
}
},
"disbursements": [
{
"amount": "24452.0",
"status": "Transferred",
"origination_time": "2021-01-27T10:57:58.623+03:00",
"transaction_reference": null
},
{
"amount": "25000.0",
"status": "Transferred",
"origination_time": "2021-01-27T10:57:58.627+03:00",
"transaction_reference": null
}
],
"origination_time": "2021-01-27T10:57:58.444+03:00"
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/052b7b2a-745b-4ca1-866b-b92d4a1418c3",
"resource": "https://sandbox.kopokopo.com/transfer_batch/270b7b2a-745b-6735752-b92d4a141847-5d33"
}
}
{
"topic": "settlement_transfer_completed",
"id": "052b7b2a-745b-4ca1-866b-b92d4a1418c3",
"created_at": "2021-01-27T11:00:08+03:00",
"event": {
"type": "Settlement Transfer",
"resource": {
"id": "270b7b2a-745b-6735752-b92d4a141847-5d33",
"amount": "49452.0",
"status": "Transferred",
"currency": "KES",
"destination": {
"type": "Bank Account",
"resource": {
"reference": "34a273d1-fedc-4610-8ab6-a1ba4828f317",
"account_name": "Test Account",
"account_number": "1234",
"bank_branch_ref": "ea2e79f7-35a1-486e-9e18-fe06589a9d7d",
"settlement_method": "EFT"
}
},
"disbursements": [
{
"amount": "24452.0",
"status": "Transferred",
"origination_time": "2021-01-27T10:57:58.623+03:00",
"transaction_reference": null
},
{
"amount": "25000.0",
"status": "Transferred",
"origination_time": "2021-01-27T10:57:58.627+03:00",
"transaction_reference": null
}
],
"origination_time": "2021-01-27T10:57:58.444+03:00"
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/052b7b2a-745b-4ca1-866b-b92d4a1418c3",
"resource": "https://sandbox.kopokopo.com/transfer_batch/270b7b2a-745b-6735752-b92d4a141847-5d33"
}
}
{
"topic": "settlement_transfer_completed",
"id": "052b7b2a-745b-4ca1-866b-b92d4a1418c3",
"created_at": "2021-01-27T11:00:08+03:00",
"event": {
"type": "Settlement Transfer",
"resource": {
"id": "270b7b2a-745b-6735752-b92d4a141847-5d33",
"amount": "49452.0",
"status": "Transferred",
"currency": "KES",
"destination": {
"type": "Bank Account",
"resource": {
"reference": "34a273d1-fedc-4610-8ab6-a1ba4828f317",
"account_name": "Test Account",
"account_number": "1234",
"bank_branch_ref": "ea2e79f7-35a1-486e-9e18-fe06589a9d7d",
"settlement_method": "EFT"
}
},
"disbursements": [
{
"amount": "24452.0",
"status": "Transferred",
"origination_time": "2021-01-27T10:57:58.623+03:00",
"transaction_reference": null
},
{
"amount": "25000.0",
"status": "Transferred",
"origination_time": "2021-01-27T10:57:58.627+03:00",
"transaction_reference": null
}
],
"origination_time": "2021-01-27T10:57:58.444+03:00"
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/052b7b2a-745b-4ca1-866b-b92d4a1418c3",
"resource": "https://sandbox.kopokopo.com/transfer_batch/270b7b2a-745b-6735752-b92d4a141847-5d33"
}
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"topic" => "settlement_transfer_completed",
"id" => "a25cc04b-e503-44e8-a002-05ff2fc3297b",
"eventType" => "Settlement Transfer",
"resourceId" => "48674c51-2546-4844-adc8-d1a267fcbc58",
"createdAt" => "2020-11-02T09:47:03+03:00",
"originationTime" => "2026-05-01T12:57:38.272+03:00",
"amount" => "786",
"currency" => "KES",
"status" => "Transferred",
"destinationType" => "Bank Account",
"destinationReference" => "34a273d1-fedc-4610-8ab6-a1ba4828f317",
"accountName" => "Test Account",
"accountNumber" => "1234",
"bankBranchRef" => "ea2e79f7-35a1-486e-9e18-fe06589a9d7d",
"settlementMethod" => "EFT",
"disbursements" => [
[
"amount" => "24452.0",
"status" => "Transferred",
"origination_time" => "2021-01-27T10:57:58.623+03:00",
"transaction_reference" => null
],
[
"amount" => "25000.0",
"status" => "Transferred",
"origination_time" => "2021-01-27T10:57:58.627+03:00",
"transaction_reference" => null
]
],
"linkSelf" => "https://sandbox.kopokopo.com/webhook_events/a25cc04b-e503-44e8-a002-05ff2fc3297b",
"linkResource" => "https://sandbox.kopokopo.com/transfer_batch/48674c51-2546-4844-adc8-d1a267fcbc58"
]
]
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
Settlement Transfer Completed Webhook Parameters (JSON)
Parameters contained in a settlement_transfer_completed webhook;
| Parameter | Type | Description |
|---|---|---|
| id | String | The ID of the Webhook Event |
| topic | String | The topic of the webhook. settlement_transfer_completed in this instance. |
| created_at | String | The timestamp of when the webhook event was created. |
| _links | JSON | A JSON object containing links to the Webhook Event and the corresponding Transfer Batch resource |
Event JSON
| Parameter | Type | Description |
|---|---|---|
| type | String | The type of transaction (Settlement Transfer) |
| resource | JSON | The resource corresponding to the event. In this case this is a Settlement Transfer |
Resource (Buygoods Transaction) JSON
| Parameter | Type | Description |
|---|---|---|
| id | String | The api reference of the transaction |
| status | String | The status of the transaction |
| amount | Float | The total amount of the transaction |
| currency | String | Currency |
| destination | JSON | The destination of the settlement transfer |
| disbursements | JSON | These are the disbursements in that particular transfer batch |
Destination JSON
| Parameter | Type | Description |
|---|---|---|
| type | String | The destination type |
| resource | JSON | The destination resource |
Destination Resource (Mobile Wallet) JSON
| Parameter | Type | Description |
|---|---|---|
| reference | String | The destination reference |
| first_name | String | First name of the recipient |
| last_name | String | Last name of recipient |
| String | Email of recipient | |
| phone_number | String | Phone number |
| network | String | The mobile network to which the phone number belongs |
Destination Resource (Bank Account) JSON
| Parameter | Type | Description |
|---|---|---|
| reference | String | The destination reference |
| account_name | String | The name as indicated on the bank account |
| bank_branch_ref | String | An identifier identifying the destination bank branch |
| account_number | String | The bank account number |
| settlement_method | String | EFT or RTS |
Disbursements JSON(Could be multiple)
| Parameter | Type | Description |
|---|---|---|
| status | String | The status of the disbursement |
| amount | String | The amount of the disbursement |
| origination_time | String | Timestamp of when the transaction took place |
| transaction_reference | String | The reference from the transaction. i.e mpesa reference It is null for eft transactions |
Customer Created
POST https://www.your-application.com/customers/webhook Content-Type: application/json User-Agent: < product >/< product-version > < comment > X-KopoKopo-Signature: a5d74a17a55554edc4e9999c59e460c61aa7f81a
{
"topic": "customer_created",
"id": "f720ecf5-ff98-4ca8-a3f2-d70a65c4a02c",
"created_at": "2020-10-29T08:49:02+03:00",
"event": {
"type": "Customer Created",
"resource": {
"last_name": "Doe",
"first_name": "Jane",
"middle_name": "M",
"phone_number": "+254999999999"
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/f720ecf5-ff98-4ca8-a3f2-d70a65c4a02c",
"resource": "https://sandbox.kopokopo.com/mobile_money_user/8248a689-490e-4196-930a-db5fcbe58f6c"
}
}
{
"topic": "customer_created",
"id": "f720ecf5-ff98-4ca8-a3f2-d70a65c4a02c",
"created_at": "2020-10-29T08:49:02+03:00",
"event": {
"type": "Customer Created",
"resource": {
"last_name": "Doe",
"first_name": "Jane",
"middle_name": "M",
"phone_number": "+254999999999"
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/f720ecf5-ff98-4ca8-a3f2-d70a65c4a02c",
"resource": "https://sandbox.kopokopo.com/mobile_money_user/8248a689-490e-4196-930a-db5fcbe58f6c"
}
}
{
"topic": "customer_created",
"id": "f720ecf5-ff98-4ca8-a3f2-d70a65c4a02c",
"created_at": "2020-10-29T08:49:02+03:00",
"event": {
"type": "Customer Created",
"resource": {
"last_name": "Doe",
"first_name": "Jane",
"middle_name": "M",
"phone_number": "+254999999999"
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/f720ecf5-ff98-4ca8-a3f2-d70a65c4a02c",
"resource": "https://sandbox.kopokopo.com/mobile_money_user/8248a689-490e-4196-930a-db5fcbe58f6c"
}
}
{
"topic": "customer_created",
"id": "f720ecf5-ff98-4ca8-a3f2-d70a65c4a02c",
"created_at": "2020-10-29T08:49:02+03:00",
"event": {
"type": "Customer Created",
"resource": {
"last_name": "Doe",
"first_name": "Jane",
"middle_name": "M",
"phone_number": "+254999999999"
}
},
"_links": {
"self": "https://sandbox.kopokopo.com/webhook_events/f720ecf5-ff98-4ca8-a3f2-d70a65c4a02c",
"resource": "https://sandbox.kopokopo.com/mobile_money_user/8248a689-490e-4196-930a-db5fcbe58f6c"
}
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"id" => "cac95329-9fa5-42f1-a4fc-c08af7b868fb",
"topic" => "customer_created",
"createdAt" => "2018-06-20T22:45:12.790Z",
"eventType" =>"Customer Created",
"lastName" => "Doe",
"firstName" => "Jane",
"middleName" => "M",
"phoneNumber" => "+254999999999"
"linkSelf" => "https://sandbox.kopokopo.com/webhook_events/cac95329-9fa5-42f1-a4fc-c08af7b868fb",
"linkResource" => "https://sandbox.kopokopo.com/mobile_money_user/458712f-gr76y-24b9-40fc-ae57-2d35785760",
]
]
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
Customer Created Webhook Parameters (JSON)
Parameters contained in a customer_created webhook;
| Parameter | Type | Description |
|---|---|---|
| id | String | The ID of the Webhook Event |
| topic | String | The topic of the webhook. customer_created in this instance. |
| created_at | String | The timestamp of when the webhook event was created. |
| _links | JSON | A JSON object containing links to the Webhook Event and the corresponding Mobile Money User resource |
Event JSON
| Parameter | Type | Description |
|---|---|---|
| type | String | The type of record (Mobile Money User) |
| resource | JSON | The resource corresponding to the event. In this case this is a Mobile Money User |
Resource (Mobile Money User) JSON
| Parameter | Type | Description |
|---|---|---|
| first_name | String | First name of customer |
| middle_name | String | Middle name of customer |
| last_name | String | Last name of customer |
| phone_number | String | Phone number of customer |
Card Transaction Received
POST https://www.your-application.com/customers/webhook Content-Type: application/json User-Agent: < product >/< product-version > < comment > X-KopoKopo-Signature: a5d74a17a55554edc4e9999c59e460c61aa7f81a
{
"topic": "card_transaction_received",
"id": "4b981325-abf8-4f6e-ba2c-f1bf682687ca",
"created_at": "2025-06-19T15:18:03+03:00",
"event": {
"type": "Card Transaction",
"resource": {
"id": "00f5311d-8b93-433f-987e-08278a64e1a9",
"amount": "1000.0",
"status": "Received",
"system": "LittlePay",
"settled": false,
"currency": "KES",
"reference": "PENDINGCARD-1750335484",
"till_number": "7600314301",
"origination_time": "2025-06-19T15:18:03+03:00",
"customer_cc_number": "450875XXXXXX1019"
}
},
"_links": {
"self": "https://api.kopokopo.com/webhook_events/4b981325-abf8-4f6e-ba2c-f1bf682687ca",
"resource": "https://api.kopokopo.com/financial_transaction/00f5311d-8b93-433f-987e-08278a64e1a9"
}
}
Pending
Pending
Pending
Pending
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
Notifies your application when a Card Transaction has been received.
Card Transaction Received Webhook Parameters (JSON)
Parameters contained in a card_transaction_received webhook;
| Parameter | Type | Description |
|---|---|---|
| id | String | The ID of the Webhook Event |
| topic | String | The topic of the webhook. card_transaction_received in this instance. |
| created_at | String | The timestamp of when the webhook event was created. |
| _links | JSON | A JSON object containing links to the Webhook Event and the corresponding Card Transaction resource |
Event JSON
| Parameter | Type | Description |
|---|---|---|
| type | String | The type of transaction (Card Transaction) |
| resource | JSON | The resource corresponding to the event. In this case this is a Card Transaction |
Resource (Card Transaction) JSON
| Parameter | Type | Description |
|---|---|---|
| id | String | The api reference of the transaction |
| reference | String | The card transaction reference |
| status | String | The status of the transaction |
| origination_time | String | The transaction timestamp |
| customer_cc_number | String | The customer's card number that sent the payment |
| amount | Float | The amount of the transaction |
| currency | String | Currency |
| till_number | String | The till number/terminal to which the payment was made |
| system | String | The card system |
| settled | String | Flag indicating whether or not the card payment was settled |
Card Transaction Voided
POST https://www.your-application.com/customers/webhook Content-Type: application/json User-Agent: < product >/< product-version > < comment > X-KopoKopo-Signature: a5d74a17a55554edc4e9999c59e460c61aa7f81a
{
"topic": "card_transaction_voided",
"id": "4b981325-abf8-4f6e-ba2c-f1bf682687ca",
"created_at": "2025-06-19T15:18:03+03:00",
"event": {
"type": "Card Void Transaction",
"resource": {
"id": "00f5311d-8b93-433f-987e-08278a64e1a9",
"amount": "1000.0",
"status": "Complete",
"system": "LittlePay",
"currency": "KES",
"reference": "PENDINGCARD-1750335484",
"till_number": "7600314301",
"origination_time": "2025-06-19T15:18:03+03:00",
"customer_cc_number": "450875XXXXXX1019"
}
},
"_links": {
"self": "https://api.kopokopo.com/webhook_events/4b981325-abf8-4f6e-ba2c-f1bf682687ca",
"resource": "https://api.kopokopo.com/financial_transaction/00f5311d-8b93-433f-987e-08278a64e1a9"
}
}
Pending
Pending
Pending
Pending
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
Notifies your application when a Card Transaction has been voided.
Card Void Transaction Webhook Parameters (JSON)
Parameters contained in a card_transaction_voided webhook;
| Parameter | Type | Description |
|---|---|---|
| id | String | The ID of the Webhook Event |
| topic | String | The topic of the webhook. card_transaction_voided in this instance. |
| created_at | String | The timestamp of when the webhook event was created. |
| _links | JSON | A JSON object containing links to the Webhook Event and the corresponding Card Void Transaction resource |
Event JSON
| Parameter | Type | Description |
|---|---|---|
| type | String | The type of transaction (Card Void Transaction) |
| resource | JSON | The resource corresponding to the event. In this case this is a Card Void Transaction |
Resource (Card Void Transaction) JSON
| Parameter | Type | Description |
|---|---|---|
| id | String | The api reference of the transaction |
| reference | String | The card transaction reference |
| status | String | The status of the transaction |
| origination_time | String | The transaction timestamp |
| customer_cc_number | String | The customer's card number that sent the original payment |
| amount | Float | The amount of the transaction |
| currency | String | Currency |
| till_number | String | The till number/terminal to which the original payment was made |
| system | String | The card system |
Card Transaction Reversed
POST https://www.your-application.com/customers/webhook Content-Type: application/json User-Agent: < product >/< product-version > < comment > X-KopoKopo-Signature: a5d74a17a55554edc4e9999c59e460c61aa7f81a
{
"topic": "card_transaction_reversed",
"id": "4b981325-abf8-4f6e-ba2c-f1bf682687ca",
"created_at": "2025-06-19T15:18:03+03:00",
"event": {
"type": "Card Reversal Transaction",
"resource": {
"id": "00f5311d-8b93-433f-987e-08278a64e1a9",
"amount": "1000.0",
"status": "Complete",
"system": "LittlePay",
"currency": "KES",
"reference": "PENDINGCARD-1750335484",
"till_number": "7600314301",
"origination_time": "2025-06-19T15:18:03+03:00",
"customer_cc_number": "450875XXXXXX1019"
}
},
"_links": {
"self": "https://api.kopokopo.com/webhook_events/4b981325-abf8-4f6e-ba2c-f1bf682687ca",
"resource": "https://api.kopokopo.com/financial_transaction/00f5311d-8b93-433f-987e-08278a64e1a9"
}
}
Pending
Pending
Pending
Pending
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
Notifies your application when a Card Transaction has been reversed.
Card Reversal Transaction Webhook Parameters (JSON)
Parameters contained in a card_transaction_reversed webhook;
| Parameter | Type | Description |
|---|---|---|
| id | String | The ID of the Webhook Event |
| topic | String | The topic of the webhook. card_transaction_reversed in this instance. |
| created_at | String | The timestamp of when the webhook event was created. |
| _links | JSON | A JSON object containing links to the Webhook Event and the corresponding Card Reversal Transaction resource |
Event JSON
| Parameter | Type | Description |
|---|---|---|
| type | String | The type of transaction (Card Reversal Transaction) |
| resource | JSON | The resource corresponding to the event. In this case this is a Card Reversal Transaction |
Resource (Card Reversal Transaction) JSON
| Parameter | Type | Description |
|---|---|---|
| id | String | The api reference of the transaction |
| reference | String | The card transaction reference |
| status | String | The status of the transaction |
| origination_time | String | The transaction timestamp |
| customer_cc_number | String | The customer's card number that had sent the original payment |
| amount | Float | The amount of the transaction |
| currency | String | Currency |
| till_number | String | The till number/terminal to which the original payment was made |
| system | String | The card system |
Receive M-PESA payments
Receive payments from M-PESA users via STK Push
POST https://sandbox.kopokopo.com/api/v2/incoming_payments Content-Type: application/json Accept: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: "< product >/< product-version > < comment >"
{
"payment_channel": "M-PESA STK Push",
"till_number": "K000000",
"subscriber": {
"first_name": "Joe",
"last_name": "Buyer",
"phone_number": "+254999999999",
"email": "jbuyer@mail.net"
},
"amount": {
"currency": "KES",
"value": 20000
},
"metadata": {
"customer_id": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"_links": {
"callback_url": "https://callback_to_your_app.your_application.com"
}
}
# Using K2Connect - https://github.com/kopokopo/k2-connect-ruby (Recommended)
your_input =
{
payment_channel: 'M-PESA STK Push',
till_number: 'K444555',
first_name: 'Joe',
last_name: 'Buyer',
phone_number: '+254999999999',
email: 'jbuyer@mail.net',
currency: 'KES',
value: 20000,
metadata: {
customer_id: '123456789',
reference: '123456',
notes: 'Payment for invoice 12345'
},
callback_url: 'https://call_back_to_your_app.your_application.com'
}
k2_stk = K2Stk.new("your_access_token")
k2_stk.receive_mpesa_payments(your_input)
k2_stk.location_url # => "https://sandbox.kopokopo.com/api/v2/incoming_payments/247b1bd8-f5a0-4b71-a898-f62f67b8ae1c"
request_body =
{
"access_token": ACCESS_TOKEN,
"callback_url": "https://webhook.site/52fd1913-778e-4ee1-bdc4-74517abb758d",
"first_name": "python_first_name",
"last_name": "python_last_name",
"email": "john.doe@gmail.com",
"payment_channel": "MPESA",
"phone_number": "+254911222536",
"till_number": "K000000",
"amount": "10"
}
# Using K2Connect - https://github.com/kopokopo/k2-connect-python (Recommended)
k2connect.initialize(environ.get('CLIENT_ID'), environ.get('CLIENT_SECRET'), 'http://127.0.0.1:3000/')
stk_service = k2connect.ReceivePayments
stk_push_location = stk_service.create_payment_request(request_body)
stk_push_location # => 'https://sandbox.kopokopo.com/api/v2/incoming_payments/247b1bd8-f5a0-4b71-a898-f62f67b8ae1c'
const StkService = K2.StkService;
var stkOptions = {
paymentChannel: "M-PESA STK Push",
tillNumber: "K000000",
firstName: "Jane",
lastName: "Doe",
phoneNumber: "+254999999999",
email: "example@example.com",
currency: "KES",
// A maximum of 5 key value pairs
metadata: {
customerId: "123456789",
reference: "123456",
notes: "Payment for invoice 123456",
},
// This is where once the request is completed kopokopo will post the response
callbackUrl: "https://callback_to_your_app.your_application.com/endpoint",
accessToken: "myRand0mAcc3ssT0k3n",
};
StkService.initiateIncomingPayment(stkOptions)
.then((response) => {
console.log(response);
// => 'https://sandbox.kopokopo.com/api/v2/incoming_payments/247b1bd8-f5a0-4b71-a898-f62f67b8ae1c'
})
.catch((error) => {
console.log(error);
});
<?
$stk = $K2->StkService();
$response = $stk->initiateIncomingPayment([
'paymentChannel' => 'M-PESA STK Push',
'tillNumber' => 'K000000',
'firstName' => 'Jane',
'lastName' => 'Doe',
'phoneNumber' => '+254999999999',
'amount' => 3455,
'currency' => 'KES',
'email' => 'example@example.com',
'callbackUrl' => 'https://callback_to_your_app.your_application.com/endpoint',
'metadata' => [
'customerId' => '123456789',
'reference' => '123456',
'notes' => 'Payment for invoice 12345'
],
'accessToken' => 'myRand0mAcc3ssT0k3n',
]);
if($response['status'] == 'success')
{
echo "The resource location is:" . json_encode($response['location']);
// => 'https://sandbox.kopokopo.com/api/v2/incoming_payments/247b1bd8-f5a0-4b71-a898-f62f67b8ae1c'
}
final TokenService tokenService = K2ConnectFlutter.tokenService();
final tokenResponse = await tokenService.requestAccessToken();
# For bottom sheet payment request UI
final request = StkPushRequest(
companyName: 'Test Company',
tillNumber: 'K12345',
amount: Amount(
currency: 'KES', value: '1.00'),
callbackUrl:
'https://webhook.site/your-callback-url',
metadata: {'source': 'flutter-app'},
onSuccess: () =>
print('Payment success'),
onError: (error) =>
print('Payment error: $error'),
accessToken: tokenResponse.accessToken,
);
final stkService =
K2ConnectFlutter.stkService();
await stkService
.requestPaymentBottomSheet(
context,
request: request,
);
# To make a request without UI
final stkRequest = StkPushRequest(
tillNumber: 'K12345',
subscriber: Subscriber(phoneNumber: '0712345678'),
amount: Amount(value: '10.00', currency: 'KES'),
callbackUrl: 'https://webhook.site/your-callback-url',
accessToken: tokenResponse.accessToken,
);
final service = StkService(baseUrl: 'base_url');
final result = await service.requestPayment(stkRequest);
HTTP Request
POST https://sandbox.kopokopo.com/api/v2/incoming_payments
Request Parameters (JSON)
| Parameter | Required | Type | Description |
|---|---|---|---|
| payment_channel | Yes | String | The payment channel to be used eg. M-PESA |
| till_number | Yes | String | The online payments till number from the Kopo Kopo dashboard to which the payment will be made |
| subscriber | Yes | Subscriber | A Subscriber JSON object see below |
| amount | Yes | Amount | An Amount JSON object containing currency and amount |
| metadata | No | Metadata | An optional JSON object containing a maximum of 5 key value pairs |
| links | Yes | _links | A JSON object containing the call back URL where the result of the Incoming Payment will be posted |
Subscriber (JSON)
| Parameter | Required | Type | Description |
|---|---|---|---|
| first_name | No | String | First name of the subscriber |
| last_name | No | String | Last name of the subscriber |
| phone_number | Yes | String | The phone number of the subscriber from which the payment will be made |
| No | String | E-mail address of the subscriber - optional |
HTTP Response
Successful Response
Upon a successful request a HTTP Status 201 will be returned and the location HTTP Header will contain the URL of the newly created Incoming Payment
HTTP/1.1 201 Created
Location: https://sandbox.kopokopo.com/api/v2/incoming_payments/247b1bd8-f5a0-4b71-a898-f62f67b8ae1c
Error Response
This will have a HTTP Status code indicating the error and it might have a json that contains the error code and an error message specifying the error that occured. Please note that the error response might not be present depending on the type of error that occured.
If the error json response is present, it will look as follows:
HTTP/1.1 400 Bad Request
{ "error_code": 400, "error_message": "Till number can't be blank" }
Process Incoming Payment Result
POST https://your-callback-url.com/api/v2/payment_request_result Content-Type: application/json User-Agent: < product >/< product-version > < comment > X-KopoKopo-Signature: 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q
{
"data": {
"id": "a652f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"type": "incoming_payment",
"attributes": {
"initiation_time": "2020-10-19T09:24:48.622+03:00",
"status": "Success",
"event": {
"type": "Incoming Payment Request",
"resource": {
"id": "52f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"reference": "OJJ1MPU40Z",
"origination_time": "2020-10-19T09:24:54+03:00",
"sender_phone_number": "+254999999999",
"amount": "100.0",
"currency": "KES",
"till_number": "K000000",
"system": "Lipa Na M-PESA",
"status": "Received",
"sender_first_name": "Joe",
"sender_middle_name": null,
"sender_last_name": "Buyer"
},
"errors": null
},
"metadata": {
"customer_id": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"_links": {
"callback_url": "https://webhook.site/675d4ef4-0629-481f-83cd-d101f55e4bc8",
"self": "http://sandbox.kopokopo.com/api/v2/incoming_payments/a652f86f-f2aa-4d70-baa2-ccfe4b78f4fc"
}
}
}
}
incoming_payment = K2Client.new("API_KEY")
incoming_payment.parse_request(request)
stk_object = K2ProcessResult.process(incoming_payment.hash_body, API_KEY, incoming_payment.k2_signature)
# Processed stk result in json format
{
"data": {
"id": "a652f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"type": "incoming_payment",
"attributes": {
"initiation_time": "2020-10-19T09:24:48.622+03:00",
"status": "Success",
"event": {
"type": "Incoming Payment Request",
"resource": {
"id": "52f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"reference": "OJJ1MPU40Z",
"origination_time": "2020-10-19T09:24:54+03:00",
"sender_phone_number": "+254999999999",
"amount": "100.0",
"currency": "KES",
"till_number": "K514459",
"system": "Lipa Na M-PESA",
"status": "Received",
"sender_first_name": "Joe",
"sender_middle_name": nil,
"sender_last_name": "Buyer"
},
"errors": nil
},
"metadata": {
"customer_id": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"_links": {
"callback_url": "https://webhook.site/675d4ef4-0629-481f-83cd-d101f55e4bc8",
"self": "http://sandbox.kopokopo.com/api/v2/incoming_payments/a652f86f-f2aa-4d70-baa2-ccfe4b78f4fc"
}
}
}
}
k2connect.initialize(CLIENT_ID, CLIENT_SECRET, BASE_URL)
result_handler = k2connect.ResultHandler
processed_payload = result_handler.process(request)
decomposed_result = payload_decomposer.decompose(processed_payload)
# Processed stk result in json format
{
"data": {
"id": "a652f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"type": "incoming_payment",
"attributes": {
"initiation_time": "2020-10-19T09:24:48.622+03:00",
"status": "Success",
"event": {
"type": "Incoming Payment Request",
"resource": {
"id": "52f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"reference": "OJJ1MPU40Z",
"origination_time": "2020-10-19T09:24:54+03:00",
"sender_phone_number": "+254999999999",
"amount": "100.0",
"currency": "KES",
"till_number": "K514459",
"system": "Lipa Na M-PESA",
"status": "Received",
"sender_first_name": "Joe",
"sender_middle_name": nil,
"sender_last_name": "Buyer"
},
"errors": nil
},
"metadata": {
"customer_id": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"_links": {
"callback_url": "https://webhook.site/675d4ef4-0629-481f-83cd-d101f55e4bc8",
"self": "http://sandbox.kopokopo.com/api/v2/incoming_payments/a652f86f-f2aa-4d70-baa2-ccfe4b78f4fc"
}
}
}
}
{
"data": {
"id": "a652f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"type": "incoming_payment",
"attributes": {
"initiation_time": "2020-10-19T09:24:48.622+03:00",
"status": "Success",
"event": {
"type": "Incoming Payment Request",
"resource": {
"id": "52f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"reference": "OJJ1MPU40Z",
"origination_time": "2020-10-19T09:24:54+03:00",
"sender_phone_number": "+254999999999",
"amount": "100.0",
"currency": "KES",
"till_number": "K000000",
"system": "Lipa Na M-PESA",
"status": "Received",
"sender_first_name": "Joe",
"sender_middle_name": null,
"sender_last_name": "Buyer"
},
"errors": null
},
"metadata": {
"customer_id": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"_links": {
"callback_url": "https://webhook.site/675d4ef4-0629-481f-83cd-d101f55e4bc8",
"self": "http://sandbox.kopokopo.com/api/v2/incoming_payments/a652f86f-f2aa-4d70-baa2-ccfe4b78f4fc"
}
}
}
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"id" => "cac95329-9fa5-42f1-a4fc-c08af7b868fb",
"type" => "incoming_payment",
"initiationTime" => "2018-06-20T22:45:12.790Z",
"status" => "Success",
"eventType" =>"Incoming Payment Request",
"resourceId" => "52f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"reference" => '123456789',
"originationTime" => "2017-01-20T22:45:12.790Z",
"senderPhoneNumber" => "+2549703119050",
"amount" => 20000,
"currency" => "KES",
"tillNumber" => "K000000",
"system" => "Lipa Na M-PESA",
"resourceStatus" => "Received",
"senderFirstName" => "John",
"senderMiddleName" => "O",
"senderLastName" => "Doe"
"errors" => [],
"metadata" => [
"customer_id" => "123456789",
"reference" => "123456",
"notes" => "Payment for invoice 123456"
],
"linkSelf" => "https://sandbox.kopokopo.com/payment_request_results/cac95329-9fa5-42f1-a4fc-c08af7b868fb",
"callbackUrl" => "https://webhook.site/fa3645c6-7199-426a-8efa-98e7b754babb",
]
]
// The result payload sent to your backend callback URL will look like this.
{
"data": {
"id": "a652f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"type": "incoming_payment",
"attributes": {
"initiation_time": "2020-10-19T09:24:48.622+03:00",
"status": "Success",
"event": {
"type": "Incoming Payment Request",
"resource": {
"id": "52f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"reference": "OJJ1MPU40Z",
"origination_time": "2020-10-19T09:24:54+03:00",
"sender_phone_number": "+254999999999",
"amount": "100.0",
"currency": "KES",
"till_number": "K000000",
"system": "Lipa Na M-PESA",
"status": "Received",
"sender_first_name": "Joe",
"sender_middle_name": null,
"sender_last_name": "Buyer"
},
"errors": null
},
"metadata": {
"customer_id": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"_links": {
"callback_url": "https://webhook.site/675d4ef4-0629-481f-83cd-d101f55e4bc8",
"self": "http://sandbox.kopokopo.com/api/v2/incoming_payments/a652f86f-f2aa-4d70-baa2-ccfe4b78f4fc"
}
}
}
}
Unsuccessful Incoming Payment
{
"data": {
"id": "09bc45fc-3b97-4c44-b860-42a7bcbd7480",
"type": "incoming_payment",
"attributes": {
"initiation_time": "2020-10-15T09:45:18.843+03:00",
"status": "Failed",
"event": {
"type": "Incoming Payment Request",
"resource": null,
"errors": ["The initiator information is invalid."]
},
"metadata": {
"customer_id": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"_links": {
"callback_url": "https://webhook.site/675d4ef4-0629-481f-83cd-d101f55e4bc8",
"self": "http://localhost:3000/api/v2/incoming_payments/09bc45fc-3b97-4c44-b860-42a7bcbd7480"
}
}
}
}
{
"data": {
"id": "09bc45fc-3b97-4c44-b860-42a7bcbd7480",
"type": "incoming_payment",
"attributes": {
"initiation_time": "2020-10-15T09:45:18.843+03:00",
"status": "Failed",
"event": {
"type": "Incoming Payment Request",
"resource": null,
"errors": ["The initiator information is invalid."]
},
"metadata": {
"customer_id": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"_links": {
"callback_url": "https://webhook.site/675d4ef4-0629-481f-83cd-d101f55e4bc8",
"self": "http://localhost:3000/api/v2/incoming_payments/09bc45fc-3b97-4c44-b860-42a7bcbd7480"
}
}
}
}
{
"data": {
"id": "09bc45fc-3b97-4c44-b860-42a7bcbd7480",
"type": "incoming_payment",
"attributes": {
"initiation_time": "2020-10-15T09:45:18.843+03:00",
"status": "Failed",
"event": {
"type": "Incoming Payment Request",
"resource": null,
"errors": ["The initiator information is invalid."]
},
"metadata": {
"customer_id": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"_links": {
"callback_url": "https://webhook.site/675d4ef4-0629-481f-83cd-d101f55e4bc8",
"self": "http://localhost:3000/api/v2/incoming_payments/09bc45fc-3b97-4c44-b860-42a7bcbd7480"
}
}
}
}
{
"data": {
"id": "09bc45fc-3b97-4c44-b860-42a7bcbd7480",
"type": "incoming_payment",
"attributes": {
"initiation_time": "2020-10-15T09:45:18.843+03:00",
"status": "Failed",
"event": {
"type": "Incoming Payment Request",
"resource": null,
"errors": ["The initiator information is invalid."]
},
"metadata": {
"customer_id": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"_links": {
"callback_url": "https://webhook.site/675d4ef4-0629-481f-83cd-d101f55e4bc8",
"self": "http://localhost:3000/api/v2/incoming_payments/09bc45fc-3b97-4c44-b860-42a7bcbd7480"
}
}
}
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"id" => "cac95329-9fa5-42f1-a4fc-c08af7b868fb",
"type" => "incoming_payment",
"initiationTime" => "2018-06-20T22:45:12.790Z",
"status" => "Failed",
"eventType" =>"Incoming Payment Request",
"resource" => null,
"errors" => ["Insufficient funds"]
"metadata" => [
"customer_id" => "123456789",
"reference" => "123456",
"notes" => "Payment for invoice 123456"
],
"linkSelf" => "https://sandbox.kopokopo.com/payment_request_results/cac95329-9fa5-42f1-a4fc-c08af7b868fb",
"callbackUrl" => "https://webhook.site/fa3645c6-7199-426a-8efa-98e7b754babb",
]
]
// The result payload sent to your backend callback URL will look like this.
{
"data": {
"id": "09bc45fc-3b97-4c44-b860-42a7bcbd7480",
"type": "incoming_payment",
"attributes": {
"initiation_time": "2020-10-15T09:45:18.843+03:00",
"status": "Failed",
"event": {
"type": "Incoming Payment Request",
"resource": null,
"errors": ["The initiator information is invalid."]
},
"metadata": {
"customer_id": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"_links": {
"callback_url": "https://webhook.site/675d4ef4-0629-481f-83cd-d101f55e4bc8",
"self": "http://localhost:3000/api/v2/incoming_payments/09bc45fc-3b97-4c44-b860-42a7bcbd7480"
}
}
}
}
After a Incoming Payment is initiated, a Incoming Payment Result will be posted asynchronously to the call back URL specified in the Incoming Payment.
Incoming Payment Result Parameters (JSON)
Parameters contained in a successful Incoming Payment result;
| Parameter | Required | Type | Description |
|---|---|---|---|
| id | Yes | String | The ID of the Incoming Payment |
| type | Yes | String | The topic of the request. incoming_payment in this instance. |
| initiation_time | Yes | String | The timestamp of when the Incoming Payment was created. |
| status | Yes | String | A status string denoting the status of the Incoming Payment |
| event | Yes | JSON | A JSON Object encapsulating the event of the request (see below) |
| metadata | No | JSON | An optional JSON objet containing a maximum of 5 key - value pairs that had been sent during the initiation of the request |
| _links | Yes | JSON | A JSON object containing links to the Incoming Payment and the corresponding Buygoods Transaction resource |
Event JSON
| Parameter | Required | Type | Description |
|---|---|---|---|
| type | Yes | String | The type of the event (Incoming Payment) |
| resource | Yes | JSON | The resource corresponding to the event. In this case this is a Buygoods Transaction |
| errors | No | String | A string containing information on the error than occured |
Resource (Buygoods Transaction) JSON
| Parameter | Required | Type | Description |
|---|---|---|---|
| reference | Yes | String | The reference of the transaction |
| origination_time | Yes | String | The transaction timestamp |
| sender_phone_number | Yes | String | The phone number that sent the payment |
| amount | Yes | Float | The amount of the transaction |
| currency | Yes | String | Currency |
| till_number | Yes | String | The Online Payments Account till number to which the payment was made |
| system | Yes | String | The mobile money system |
| sender_first_name | Yes | String | First name of payer |
| sender_middle_name | No | String | Middle name of payer |
| sender_last_name | Yes | String | Last name of payer |
Query Incoming Payment Status
GET https://sandbox.kopokopo.com/api/v2/incoming_payments/d79995cd-0111-e511-80da-0aa34a9b2388 Accept: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
payment_request_url = 'https://sandbox.kopokopo.com/api/v2/incoming_payments/d76265cd-0951-e511-80da-0aa34a9b2388'
# Using K2 Connect - https://github.com/kopokopo/k2-connect-ruby (Recommended)
k2_stk = K2Stk.new("your_access_token")
k2_stk.receive_mpesa_payments(your_input)
# Query specific resource
k2_stk.query_resource(payment_request_url) or k2_stk.query_resource(k2_stk.location_url)
# Query recent transaction
k2_stk.query_status
payment_request_url = 'https://sandbox.kopokopo.com/api/v2/incoming_payments/d76265cd-0951-e511-80da-0aa34a9b2388'
# Using K2 Connect - https://github.com/kopokopo/k2-connect-python (Recommended)
k2connect.initialize(environ.get('CLIENT_ID'), environ.get('CLIENT_SECRET'), 'http://127.0.0.1:3000/')
stk_service = k2connect.ReceivePayments
stk_push_location = stk_service.payment_request_status(access_token, payment_request_url)
var StkService = K2.StkService;
var stkUrl =
"https://sandbox.kopokopo.com/api/v2/incoming_payments/d76265cd-0951-e511-80da-0aa34a9b2388";
StkService.getStatus({ accessToken: "myRand0mAcc3ssT0k3n", location: stkUrl })
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(error);
});
<?
$stk = $K2->StkService();
$options = [
'location' => 'https://sandbox.kopokopo.com/api/v2/incoming_payments/d76265cd-0951-e511-80da-0aa34a9b2388',
'accessToken' => 'myRand0mAcc3ssT0k3n',
];
$response = $stk->getStatus($options);
echo $response
final location = result.headers['location'];
final statusResponse = await service.requestStatus(
uri: location,
accessToken: tokenResponse.accessToken,
);
final status = statusResponse.attributes.status;
print('Payment status: $status');
The request above results the following JSON payload when a Incoming Payment Result exists
{
"data": {
"id": "a652f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"type": "incoming_payment",
"attributes": {
"initiation_time": "2020-10-19T09:24:48.622+03:00",
"status": "Success",
"event": {
"type": "Incoming Payment Request",
"resource": {
"id": "52f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"reference": "OJJ1MPU40Z",
"origination_time": "2020-10-19T09:24:54+03:00",
"sender_phone_number": "+254999999999",
"amount": "100.0",
"currency": "KES",
"till_number": "K000000",
"system": "Lipa Na M-PESA",
"status": "Received",
"sender_first_name": "Joe",
"sender_middle_name": null,
"sender_last_name": "Buyer"
},
"errors": null
},
"metadata": {
"customer_id": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"_links": {
"callback_url": "https://webhook.site/675d4ef4-0629-481f-83cd-d101f55e4bc8",
"self": "http://sandbox.kopokopo.com/api/v2/incoming_payments/a652f86f-f2aa-4d70-baa2-ccfe4b78f4fc"
}
}
}
}
{
"data": {
"id": "a652f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"type": "incoming_payment",
"attributes": {
"initiation_time": "2020-10-19T09:24:48.622+03:00",
"status": "Success",
"event": {
"type": "Incoming Payment Request",
"resource": {
"id": "52f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"reference": "OJJ1MPU40Z",
"origination_time": "2020-10-19T09:24:54+03:00",
"sender_phone_number": "+254999999999",
"amount": "100.0",
"currency": "KES",
"till_number": "K000000",
"system": "Lipa Na M-PESA",
"status": "Received",
"sender_first_name": "Joe",
"sender_middle_name": null,
"sender_last_name": "Buyer"
},
"errors": null
},
"metadata": {
"customer_id": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"_links": {
"callback_url": "https://webhook.site/675d4ef4-0629-481f-83cd-d101f55e4bc8",
"self": "http://sandbox.kopokopo.com/api/v2/incoming_payments/a652f86f-f2aa-4d70-baa2-ccfe4b78f4fc"
}
}
}
}
{
"data": {
"id": "a652f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"type": "incoming_payment",
"attributes": {
"initiation_time": "2020-10-19T09:24:48.622+03:00",
"status": "Success",
"event": {
"type": "Incoming Payment Request",
"resource": {
"id": "52f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"reference": "OJJ1MPU40Z",
"origination_time": "2020-10-19T09:24:54+03:00",
"sender_phone_number": "+254999999999",
"amount": "100.0",
"currency": "KES",
"till_number": "K000000",
"system": "Lipa Na M-PESA",
"status": "Received",
"sender_first_name": "Joe",
"sender_middle_name": null,
"sender_last_name": "Buyer"
},
"errors": null
},
"metadata": {
"customer_id": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"_links": {
"callback_url": "https://webhook.site/675d4ef4-0629-481f-83cd-d101f55e4bc8",
"self": "http://sandbox.kopokopo.com/api/v2/incoming_payments/a652f86f-f2aa-4d70-baa2-ccfe4b78f4fc"
}
}
}
}
{
"data": {
"id": "a652f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"type": "incoming_payment",
"attributes": {
"initiation_time": "2020-10-19T09:24:48.622+03:00",
"status": "Success",
"event": {
"type": "Incoming Payment Request",
"resource": {
"id": "52f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"reference": "OJJ1MPU40Z",
"origination_time": "2020-10-19T09:24:54+03:00",
"sender_phone_number": "+254999999999",
"amount": "100.0",
"currency": "KES",
"till_number": "K000000",
"system": "Lipa Na M-PESA",
"status": "Received",
"sender_first_name": "Joe",
"sender_middle_name": null,
"sender_last_name": "Buyer"
},
"errors": null
},
"metadata": {
"customer_id": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"_links": {
"callback_url": "https://webhook.site/675d4ef4-0629-481f-83cd-d101f55e4bc8",
"self": "http://sandbox.kopokopo.com/api/v2/incoming_payments/a652f86f-f2aa-4d70-baa2-ccfe4b78f4fc"
}
}
}
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"id" => "cac95329-9fa5-42f1-a4fc-c08af7b868fb",
"type" => "incoming_payment",
"initiationTime" => "2018-06-20T22:45:12.790Z",
"status" => "Success",
"eventType" =>"Incoming Payment Request",
"resourceId" => "52f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"reference" => '123456789',
"originationTime" => "2017-01-20T22:45:12.790Z",
"senderPhoneNumber" => "+2549703119050",
"amount" => 20000,
"currency" => "KES",
"tillNumber" => "K000000",
"system" => "Lipa Na M-PESA",
"resourceStatus" => "Received",
"senderFirstName" => "John",
"senderMiddleName" => "O",
"senderLastName" => "Doe"
"errors" => [],
"metadata" => [
"customer_id" => "123456789",
"reference" => "123456",
"notes" => "Payment for invoice 123456"
],
"linkSelf" => "https://sandbox.kopokopo.com/payment_request_results/cac95329-9fa5-42f1-a4fc-c08af7b868fb",
"callbackUrl" => "https://webhook.site/fa3645c6-7199-426a-8efa-98e7b754babb",
]
]
// The payload from the k2-connect-flutter SDK will look like this.
{
"id": "a652f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"type": "incoming_payment",
"attributes": {
"initiationTime": "2020-10-19T09:24:48.622+03:00",
"status": "Success",
"event": {
"type": "Incoming Payment Request",
"resource": {
"id": "52f86f-f2aa-4d70-baa2-ccfe4b78f4fc",
"reference": "OJJ1MPU40Z",
"origination_time": "2020-10-19T09:24:54+03:00",
"sender_phone_number": "+254999999999",
"amount": "100.0",
"currency": "KES",
"till_number": "K000000",
"system": "Lipa Na M-PESA",
"status": "Received",
"sender_first_name": "Joe",
"sender_middle_name": null,
"sender_last_name": "Buyer"
},
"errors": null
},
"metadata": {
"customerId": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"links": {
"callbackUrl": "https://webhook.site/675d4ef4-0629-481f-83cd-d101f55e4bc8",
"self": "http://sandbox.kopokopo.com/api/v1/incoming_payments/a652f86f-f2aa-4d70-baa2-ccfe4b78f4fc"
}
}
}
JSON structure returned when No corresponding Incoming Payment Result exists
{
"data": {
"id": "e192ac63-8b24-4caf-8637-a2a9b75a14e6",
"type": "incoming_payment",
"attributes": {
"initiation_time": "2020-10-27T11:16:42.364+03:00",
"status": "Pending",
"event": {
"type": "Incoming Payment Request",
"resource": null,
"errors": null
},
"metadata": {
"customer_id": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"_links": {
"callback_url": "https://webhook.site/675d4ef4-0629-481f-83cd-d101f55e4bc8",
"self": "http://localhost:3000/api/v2/incoming_payments/e192ac63-8b24-4caf-8637-a2a9b75a14e6"
}
}
}
}
{
"data": {
"id": "e192ac63-8b24-4caf-8637-a2a9b75a14e6",
"type": "incoming_payment",
"attributes": {
"initiation_time": "2020-10-27T11:16:42.364+03:00",
"status": "Pending",
"event": {
"type": "Incoming Payment Request",
"resource": null,
"errors": null
},
"metadata": {
"customer_id": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"_links": {
"callback_url": "https://webhook.site/675d4ef4-0629-481f-83cd-d101f55e4bc8",
"self": "http://localhost:3000/api/v2/incoming_payments/e192ac63-8b24-4caf-8637-a2a9b75a14e6"
}
}
}
}
{
"data": {
"id": "e192ac63-8b24-4caf-8637-a2a9b75a14e6",
"type": "incoming_payment",
"attributes": {
"initiation_time": "2020-10-27T11:16:42.364+03:00",
"status": "Pending",
"event": {
"type": "Incoming Payment Request",
"resource": null,
"errors": null
},
"metadata": {
"customer_id": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"_links": {
"callback_url": "https://webhook.site/675d4ef4-0629-481f-83cd-d101f55e4bc8",
"self": "http://localhost:3000/api/v2/incoming_payments/e192ac63-8b24-4caf-8637-a2a9b75a14e6"
}
}
}
}
{
"data": {
"id": "e192ac63-8b24-4caf-8637-a2a9b75a14e6",
"type": "incoming_payment",
"attributes": {
"initiation_time": "2020-10-27T11:16:42.364+03:00",
"status": "Pending",
"event": {
"type": "Incoming Payment Request",
"resource": null,
"errors": null
},
"metadata": {
"customer_id": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"_links": {
"callback_url": "https://webhook.site/675d4ef4-0629-481f-83cd-d101f55e4bc8",
"self": "http://localhost:3000/api/v2/incoming_payments/e192ac63-8b24-4caf-8637-a2a9b75a14e6"
}
}
}
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"id" => "cac95329-9fa5-42f1-a4fc-c08af7b868fb",
"type" => "incoming_payment",
"initiationTime" => "2018-06-20T22:45:12.790Z",
"status" => "Pending",
"eventType" =>"Incoming Payment Request",
"resource" => null,
"errors" => [],
"metadata" => [
"customer_id" => "123456789",
"reference" => "123456",
"notes" => "Payment for invoice 123456"
],
"linkSelf" => "https://sandbox.kopokopo.com/payment_request_results/cac95329-9fa5-42f1-a4fc-c08af7b868fb",
"callbackUrl" => "https://webhook.site/fa3645c6-7199-426a-8efa-98e7b754babb",
]
]
// The payload from the k2-connect-flutter SDK will look like this.
{
"id": "e192ac63-8b24-4caf-8637-a2a9b75a14e6",
"type": "incoming_payment",
"attributes": {
"initiationTime": "2020-10-27T11:16:42.364+03:00",
"status": "Pending",
"event": {
"type": "Incoming Payment Request",
"resource": null,
"errors": null
},
"metadata": {
"customer_id": "123456789",
"reference": "123456",
"notes": "Payment for invoice 12345"
},
"links": {
"callbackUrl": "https://webhook.site/675d4ef4-0629-481f-83cd-d101f55e4bc8",
"self": "http://localhost:3000/api/v1/incoming_payments/e192ac63-8b24-4caf-8637-a2a9b75a14e6"
}
}
}
With an Incoming Payment location url, you can query what the status of the Incoming Payment is. If a corresponding Incoming Payment Result
exists, it will be bundled in the payload of the result.
HTTP Request
GET https://sandbox.kopokopo.com/api/v2/incoming_payments/ Accept: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
Query Parameters
| Parameter | Required | Type | Description |
|---|---|---|---|
| ID | Yes | String | The reference / ID of the Incoming Payment to retrieve |
Send Money
Create a merchant mobile wallet
POST https://sandbox.kopokopo.com/api/v2/merchant_wallets Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
{
"first_name": "first_name",
"last_name": "last_name",
"nickname": "nickname",
"phone_number": "254999999999",
"network": "Safaricom"
}
settlement_account_request = {
type: "merchant_wallet",
first_name: "first_name",
last_name: "last_name",
nickname: "nickname",
phone_number: "254999999999",
network: "Safaricom"
}
# Using K2Connect - https://github.com/kopokopo/k2-connect-ruby (Recommended)
settlement = K2Settlement.new('your_access_token')
settlement.add_settlement_account(settlement_account_request)
settlement.location_url # => "https://sandbox.kopokopo.com/api/v2/merchant_wallets/d76265cd-0951-e511-80da-0aa34a9b2388"
request_body ={
"access_token": ACCESS_TOKEN,
"first_name": 'py_sdk_first_name',
"last_name": 'py_sdk_last_name',
"phone_number": '+254911222538',
"network": 'Safaricom'
}
# Using Kopo Kopo Connect - https://github.com/kopokopo/kopokopo-connect-python (Recommended)
transfer_service = k2connect.Transfer
transfer_location = pay_service.add_mobile_wallet_settlement_account(request_body)
transfer_location # => 'https://sandbox.kopokopo.com/api/v2/merchant_wallets/d76265cd-0951-e511-80da-0aa34a9b2388'
var requestBody = {
network: 'Safaricom',
phoneNumber: '+254999999999',
firstName: 'first_name',
lastName: 'last_name',
accessToken: 'myRand0mAcc3ssT0k3n'
}
// Using Kopo Kopo Connect - https://github.com/kopokopo/k2-connect-node (Recommended)
const TransferService = K2.TransferService
TransferService
.createMerchantWallet(requestBody)
.then( response => {
console.log(response) // => 'https://sandbox.kopokopo.com/api/v2/merchant_wallets/d76265cd-0951-e511-80da-0aa34a9b2388'
})
.catch( error => {
console.log(error)
})
<?
// Using Kopo Kopo Connect - https://github.com/kopokopo/k2-connect-php (Recommended)
$transfer = $K2->SettlementTransferService();
$response = $transfer->createMerchantWallet([
'network' => 'Safaricom',
'phoneNumber' => '+254999999999',
'firstName' => 'Jane',
'lastName' => 'Doe',
'accessToken' => 'myRand0mAcc3ssT0k3n'
]);
if($response['status'] == 'success')
{
echo "The resource location is:" . json_encode($response['location']);
}
HTTP Request
POST https://sandbox.kopokopo.com/api/v2/merchant_wallets Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
Request Parameters (JSON)
| Parameter | Required | Type | Description |
|---|---|---|---|
| network | Yes | String | The mobile network to which the phone number belongs |
| first_name | Yes | String | First name |
| last_name | Yes | String | Last name |
| nickname | No | String | Nickname for mobile wallet |
| phone_number | Yes | String | Phone number |
HTTP Response
Successful Response
Upon successful creation of the merchant wallet, HTTP Status Code 201 with the URL of the merchant wallet in the Location Header of the HTTP Response.
HTTP/1.1 201 Created
Location: https://sandbox.kopokopo.com/api/v2/merchant_wallets/d76265cd-0951-e511-80da-0aa34a9b2388
Error Response
This will have a HTTP Status code indicating the error and it might have a json that contains the error code and an error message specifying the error that occured. Please note that the error response might not be present depending on the type of error that occured.
If the error json response is present, it will look as follows:
HTTP/1.1 400 Bad Request
{ "error_code": 400, "error_message": "First name can't be blank" }
Create a merchant bank account
POST https://sandbox.kopokopo.com/api/v2/merchant_bank_accounts Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: "< product >/< product-version > < comment >"
{
"account_name": "John Doe",
"bank_branch_ref": "c7f300c0-f1ef-4151-9bbe-005005aa3747",
"account_number": "123456789",
"nickname": "JD",
"settlement_method": "EFT"
}
eft_bank_settlement_account = {
type: 'merchant_bank_account',
nickname: 'JD',
account_name: 'John Doe',
account_number: '123456789',
bank_branch_ref: 'c7f300c0-f1ef-4151-9bbe-005005aa3747',
settlement_method: "EFT"
}
rts_bank_settlement_account = {
type: 'merchant_bank_account',
nickname: 'JD',
account_name: 'John Doe',
account_number: '123456789',
bank_branch_ref: 'c7f300c0-f1ef-4151-9bbe-005005aa3747',
settlement_method: "RTS"
}
# Using K2Connect - https://github.com/kopokopo/k2-connect-ruby (Recommended)
settlement = K2Settlement.new('your_access_token')
# To Add an EFT bank settlement account
settlement.add_settlement_account(eft_bank_settlement_account)
# To Add an RTS bank settlement account
settlement.add_settlement_account(rts_bank_settlement_account)
settlement.location_url # => "https://sandbox.kopokopo.com/api/v2/merchant_bank_accounts/d76265cd-0951-e511-80da-0aa34a9b2388"
request_body ={
'access_token': ACCESS_TOKEN,
'account_name': 'John Doe',
'bank_branch_ref': 'c7f300c0-f1ef-4151-9bbe-005005aa3747',
'account_number': '123456789',
"settlement_method": "EFT"
}
# Using Kopo Kopo Connect - https://github.com/kopokopo/kopokopo-connect-python (Recommended)
transfer_service = k2connect.Transfer
transfer_location = pay_service.add_bank_settlement_account(request_body)
transfer_location # => 'https://sandbox.kopokopo.com/api/v2/merchant_bank_accounts/d76265cd-0951-e511-80da-0aa34a9b2388'
var requestBody = {
'accountName': 'John Doe',
'bankBranchRef': 'c7f300c0-f1ef-4151-9bbe-005005aa3747',
'accountNumber': '123456789',
'settlementMethod': 'EFT',
'accessToken': 'myRand0mAcc3ssT0k3n'
}
// Using Kopo Kopo Connect - https://github.com/kopokopo/k2-connect-node (Recommended)
const TransferService = K2.TransferService
TransferService
.createMerchantBankAccount(requestBody)
.then( response => {
console.log(response) // => 'https://sandbox.kopokopo.com/api/v2/merchant_bank_accounts/d76265cd-0951-e511-80da-0aa34a9b2388'
})
.catch( error => {
console.log(error)
})
<?
// Using Kopo Kopo Connect - https://github.com/kopokopo/k2-connect-php (Recommended)
$transfer = $K2->SettlementTransferService();
$response = $transfer->createMerchantBankAccount([
'accountName' => 'John Doe',
'bankBranchRef' => 'c7f300c0-f1ef-4151-9bbe-005005aa3747',
'accountNumber' => '123456789',
'settlementMethod' => 'EFT',
'accessToken' => 'myRand0mAcc3ssT0k3n'
]);
if($response['status'] == 'success')
{
echo "The resource location is:" . json_encode($response['location']);
}
HTTP Request
POST https://sandbox.kopokopo.com/api/v2/merchant_bank_accounts Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
Request Parameters (JSON)
| Parameter | Required | Type | Description |
|---|---|---|---|
| account_name | Yes | String | The name as indicated on the bank account name |
| nickname | No | String | Nickname for bank account |
| bank_branch_ref | Yes | String | An identifier identifying the destination bank branch. Details on how to get a bank_branch_ref are here |
| account_number | Yes | String | The bank account number |
| settlement_method | Yes | String | EFT or RTS |
HTTP Response
Successful Response
Upon successful creation of the merchant bank account, HTTP Status Code 201 with the URL of the merchant bank account in the Location Header of the HTTP Response.
HTTP/1.1 201 Created
Location: https://sandbox.kopokopo.com/api/v2/merchant_bank_accounts/d76265cd-0951-e511-80da-0aa34a9b2388
Error Response
This will have a HTTP Status code indicating the error and it might have a json that contains the error code and an error message specifying the error that occured. Please note that the error response might not be present depending on the type of error that occured.
If the error json response is present, it will look as follows:
HTTP/1.1 400 Bad Request
{ "error_code": 400, "error_message": "Bank branch ref is not valid" }
Create an external recipient
POST https://sandbox.kopokopo.com/api/v2/external_recipients Content-Type: application/json Accept: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
Create Send Money external mobile wallet recipient
{
"type": "mobile_wallet",
"external_recipient" : {
"first_name": "John",
"last_name": "Doe",
"nickname": "JD",
"email": "johndoe@nomail.net",
"phone_number": "+254999999999",
"network": "Safaricom"
}
}
your_input = {
type: 'mobile_wallet',
first_name: 'John',
last_name: 'Doe',
email: 'johndoe@nomail.net',
phone_number: '+254999999999',
network: 'Safaricom'
}
# Using k2-connect - https://github.com/kopokopo/k2-connect-ruby(Recommended)
k2_external_recipient = K2ConnectRuby::K2Entity::ExternalRecipient.new(access_token)
k2_external_recipient.add_external_recipient(your_input)
k2_external_recipient.recipients_location_url # => "https://sandbox.kopokopo.com/api/v2/external_recipients/c7f300c0-f1ef-4151-9bbe-005005aa3747"
your_input = {
"type": "mobile_wallet",
"first_name": "John",
"last_name": "Doe",
"phone_number": "+254999999999",
"email": "johndoe@nomail.net",
"nickname": "JD",
"network": "Safaricom"
}
# Using k2-connect - https://github.com/kopokopo/k2-connect-python (Recommended)
send_money_service = k2connect.SendMoney(access_token)
k2_external_recipient_location = send_money_service.add_external_recipient(your_input)
k2_external_recipient_location # => 'https://sandbox.kopokopo.com/api/v2/external_recipients/c7f300c0-f1ef-4151-9bbe-005005aa3747'
// Using Kopo Kopo Connect - https://github.com/kopokopo/k2-connect-node (Recommended)
const ExternalRecipientService = K2.ExternalRecipientService
var requestBody = {
type: 'mobile_wallet',
firstName: 'John',
lastName: 'Doe',
network: 'Safaricom',
email: 'johndoe@nomail.net',
phoneNumber: '+254999999999',
accessToken: 'myRand0mAcc3ssT0k3n'
}
ExternalRecipientService
.addExternalRecipient(requestBody)
.then(function(res) {
console.log(response)// => 'https://sandbox.kopokopo.com/api/v2/external_recipients/c7f300c0-f1ef-4151-9bbe-005005aa3747'
})
.catch( error => {
console.log(error)
})
<?
// Using KopoKopoConnect - https://github.com/kopokopo/k2-connect-php (Recommended
$externalRecipientService = $K2->ExternalRecipientService();
$response = $externalRecipientService->addExternalRecipient([
'type' => 'mobile_wallet',
'firstName'=> 'John',
'lastName'=> 'Doe',
'phoneNumber'=> '+254999999999',
'network'=> 'Safaricom',
'access_token' => 'myRand0mAcc3ssT0k3n'
]);
if($response['status'] == 'success')
{
echo "The resource location is:" . json_encode($response['location']); // => 'https://sandbox.kopokopo.com/api/v2/external_recipients/c7f300c0-f1ef-4151-9bbe-005005aa3747'
}
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
Create Send Money external bank account recipient
{
"type": "bank_account",
"external_recipient" : {
"account_name": "John Doe",
"bank_branch_ref": "c7f300c0-f1ef-4151-9bbe-005005aa3747",
"account_number": "123456789",
"nick_name": "JD",
"settlement_method": "RTS"
}
}
your_input = {
type: 'bank_account',
account_name: 'John Doe',
account_number: '123456789',
bank_branch_ref: 'c7f300c0-f1ef-4151-9bbe-005005aa3747',
settlement_method: 'RTS'
}
# Using k2-connect - https://github.com/kopokopo/k2-connect-ruby(Recommended)
k2_external_recipient = K2ConnectRuby::K2Entity::ExternalRecipient.new(access_token)
k2_external_recipient.add_external_recipient(your_input)
k2_external_recipient.recipients_location_url # => "https://sandbox.kopokopo.com/api/v2/external_recipients/c7f300c0-f1ef-4151-9bbe-005005aa3747"
request_body = {
'type': 'bank_account',
'account_name': 'John Doe',
'account_number': '123456789',
'bank_branch_ref': 'c7f300c0-f1ef-4151-9bbe-005005aa3747',
'settlement_method': 'RTS',
'nickname': 'JD',
}
# Using k2-connect - https://github.com/kopokopo/k2-connect-python (Recommended)
send_money_service = k2connect.SendMoney(access_token)
k2_external_recipient_location = send_money_service.add_external_recipient(request_body)
k2_external_recipient_location # => 'https://sandbox.kopokopo.com/api/v2/external_recipients/c7f300c0-f1ef-4151-9bbe-005005aa3747'
// Using Kopo Kopo Connect - https://github.com/kopokopo/k2-connect-node (Recommended)
const ExternalRecipientService = K2.ExternalRecipientService
var requestBody = {
type: 'bank_account',
accountName: 'John Doe',
bankBranchRef: 'c7f300c0-f1ef-4151-9bbe-005005aa3747',
accountNumber: '123456789',
settlementMethod: 'RTS',
accessToken: 'myRand0mAcc3ssT0k3n'
}
ExternalRecipientService
.addExternalRecipient(requestBody)
.then(function(res) {
console.log(response)// => 'https://sandbox.kopokopo.com/api/v2/external_recipients/c7f300c0-f1ef-4151-9bbe-005005aa3747'
})
.catch( error => {
console.log(error)
})
<?
// Using KopoKopoConnect - https://github.com/kopokopo/k2-connect-php (Recommended
$externalRecipientService = $K2->ExternalRecipientService();
$response = $externalRecipientService->addExternalRecipient([
'type' => 'bank_account',
'bankBranchRef' => 'c7f300c0-f1ef-4151-9bbe-005005aa3747',
'accountName' => 'John Doe',
'accountNumber' => '123456789',
'settlementMethod' => 'RTS',
'accessToken' => 'myRand0mAcc3ssT0k3n'
]);
if($response['status'] == 'success')
{
echo "The resource location is:" . json_encode($response['location']); // => 'https://sandbox.kopokopo.com/api/v2/external_recipients/c7f300c0-f1ef-4151-9bbe-005005aa3747'
}
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
Create Send Money external till recipient
{
"type": "till",
"external_recipient" : {
"till_name": "John Doe",
"till_number": "000000",
"nickname": "JD"
}
}
your_input = {
type: 'till',
till_name: 'John Doe',
till_number: '123456789',
}
# Using k2-connect - https://github.com/kopokopo/k2-connect-ruby(Recommended)
k2_external_recipient = K2ConnectRuby::K2Entity::ExternalRecipient.new(access_token)
k2_external_recipient.add_external_recipient(your_input)
k2_external_recipient.recipients_location_url # => "https://sandbox.kopokopo.com/api/v2/external_recipients/c7f300c0-f1ef-4151-9bbe-005005aa3747"
request_body = {
'access_token': ACCESS_TOKEN,
'recipient_type': 'till',
'till_name': 'John Doe',
'till_number': '123456789',
'nickname': 'JD',
}
# Using k2-connect - https://github.com/kopokopo/k2-connect-python (Recommended)
send_money_service = k2connect.SendMoney(access_token)
k2_external_recipient_location = send_money_service.add_external_recipient(request_body)
k2_external_recipient_location # => 'https://sandbox.kopokopo.com/api/v2/external_recipients/c7f300c0-f1ef-4151-9bbe-005005aa3747'
// Using Kopo Kopo Connect - https://github.com/kopokopo/k2-connect-node (Recommended)
const ExternalRecipientService = K2.ExternalRecipientService
var requestBody = {
type: 'till',
tillName: 'John Doe',
tillNumber: '000000',
accessToken: 'myRand0mAcc3ssT0k3n'
}
ExternalRecipientService
.addExternalRecipient(requestBody)
.then(function(res) {
console.log(response)// => 'https://sandbox.kopokopo.com/api/v2/external_recipients/c7f300c0-f1ef-4151-9bbe-005005aa3747'
})
.catch( error => {
console.log(error)
})
<?
// Using KopoKopoConnect - https://github.com/kopokopo/k2-connect-php (Recommended
$externalRecipientService = $K2->ExternalRecipientService();
$response = $externalRecipientService->addExternalRecipient([
'type' => 'till',
'tillName' => 'John Doe',
'tillNumber' => '000000',
'accessToken' => 'myRand0mAcc3ssT0k3n'
]);
if($response['status'] == 'success')
{
echo "The resource location is:" . json_encode($response['location']);
}
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
Create Send Money paybill recipient
{
"type": "paybill",
"external_recipient" : {
"paybill_name": "KPLC Paybill",
"paybill_number": "890087",
"paybill_account_number": "test_account",
"nickname": "KPLC"
}
}
your_input = {
type: 'paybill',
paybill_name: "KPLC Paybill",
paybill_number: "890087",
paybill_account_number: "test_account",
}
# Using k2-connect - https://github.com/kopokopo/k2-connect-ruby(Recommended)
k2_external_recipient = K2ConnectRuby::K2Entity::ExternalRecipient.new(access_token)
k2_external_recipient.add_external_recipient(your_input)
k2_external_recipient.recipients_location_url # => "https://sandbox.kopokopo.com/api/v2/external_recipients/c7f300c0-f1ef-4151-9bbe-005005aa3747"
request_body = {
'access_token': ACCESS_TOKEN,
'recipient_type': 'paybill',
'paybill_name': 'KPLC Paybill',
'paybill_number': '890087',
'paybill_account_number': 'test_account',
'nickname': 'KPLC',
}
# Using k2-connect - https://github.com/kopokopo/k2-connect-python (Recommended)
send_money_service = k2connect.SendMoney(access_token)
k2_external_recipient_location = send_money_service.add_external_recipient(request_body)
k2_external_recipient_location # => 'https://sandbox.kopokopo.com/api/v2/external_recipients/c7f300c0-f1ef-4151-9bbe-005005aa3747'
// Using Kopo Kopo Connect - https://github.com/kopokopo/k2-connect-node (Recommended)
const ExternalRecipientService = K2.ExternalRecipientService
var requestBody = {
type: 'paybill',
paybillName: 'KPLC Paybill',
paybillNumber: '890087',
paybillAccountNumber: 'test_account',
nickname: 'KPLC',
accessToken: 'myRand0mAcc3ssT0k3n'
}
ExternalRecipientService
.addExternalRecipient(requestBody)
.then(function(res) {
console.log(response)// => 'https://sandbox.kopokopo.com/api/v2/external_recipients/c7f300c0-f1ef-4151-9bbe-005005aa3747'
})
.catch( error => {
console.log(error)
})
<?
// Using KopoKopoConnect - https://github.com/kopokopo/k2-connect-php (Recommended
$externalRecipientService = $K2->ExternalRecipientService();
$response = $externalRecipientService->addExternalRecipient([
'type' => 'paybill',
'paybillName' => 'KPLC Paybill',
'paybillNumber' => '890087',
'paybillAccountNumber' => 'test_account',
'accessToken' => 'myRand0mAcc3ssT0k3n'
]);
if($response['status'] == 'success')
{
echo "The resource location is:" . json_encode($response['location']);
}
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
Add external entities that will be the destination of your payments.
HTTP Request
POST https://sandbox.kopokopo.com/api/v2/external_recipients Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
Request Parameters (JSON)
| Parameter | Required | Type | Description |
|---|---|---|---|
| type | Yes | String | The type of the recipient eg. mobile_wallet, bank_account, till or paybill |
| external_recipient | Yes | JSON | A JSON object containing details of the recipient (see below) |
Send Money Recipient (Mobile Wallet) JSON
| Parameter | Required | Type | Description |
|---|---|---|---|
| first_name | Yes | String | First name of the recipient |
| last_name | Yes | String | Last name of recipient |
| nickname | No | String | Nickname for mobile wallet |
| No | String | Email of recipient | |
| phone_number | Yes | String | Phone number |
| network | Yes | String | The mobile network to which the phone number belongs |
Send Money Recipient (Bank Account) JSON
| Parameter | Required | Type | Description |
|---|---|---|---|
| account_name | Yes | String | The name as indicated on the bank account name |
| bank_branch_ref | Yes | String | An identifier identifying the destination bank branch. Details on how to get a bank_branch_ref are here |
| account_number | Yes | String | The bank account number (validation rules here) |
| nickname | No | String | Nickname for bank account |
| settlement_method | Yes | String | RTS |
Send Money Recipient (External Till) JSON
| Parameter | Required | Type | Description |
|---|---|---|---|
| till_name | Yes | String | The name as indicated on the till |
| till_number | Yes | String | The till number |
| nickname | No | String | Nickname for external till |
Send Money Recipient (Paybill) JSON
| Parameter | Required | Type | Description |
|---|---|---|---|
| paybill_name | Yes | String | The name referring to the paybill |
| paybill_number | Yes | String | The paybill business number |
| paybill_account_number | Yes | String | The paybill account number |
| nickname | No | String | Nickname for paybill account |
HTTP Response
Successful Response
A HTTP response code of 201 is returned upon successful creation of the Send Money recipient. The URL of the recipient resource is also returned in the HTTP Location Header
HTTP/1.1 201 Created
Location: https://sandbox.kopokopo.com/api/v2/external_recipients/c7f300c0-f1ef-4151-9bbe-005005aa3747
Error Response
This will have a HTTP Status code indicating the error and it might have a json that contains the error code and an error message specifying the error that occured. Please note that the error response might not be present depending on the type of error that occured.
If the error json response is present, it will look as follows:
HTTP/1.1 400 Bad Request
{ "error_code": 400, "error_message": "Invalid recipient type" }
Send Money to my accounts
POST https://sandbox.kopokopo.com/api/v2/send_money Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
{
"currency": "KES",
"metadata": {
"customerId": "8675309",
"notes": "Salary payment for September 2025"
},
"_links": {
"callback_url": "https://your-call-bak.yourapplication.com/send_money_result"
}
}
transfer_request = {
callback_url: 'https://webhook.site/437a5819-1a9d-4e96-b403-a6f898e5bed3',
}
# Using K2Connect - https://github.com/kopokopo/k2-connect-ruby (Recommended)
k2_transfer = K2Transfer.new('your_access_token')
k2_transfer.transfer_funds(transfer_request)
k2_transfer.location_url # => "https://sandbox.kopokopo.com/api/v2/transfers/d76265cd-0951-e511-80da-0aa34a9b2388"
request_body = {
"access_token": ACCESS_TOKEN,
"callback_url": 'https://webhook.site/52fd1913-778e-4ee1-bdc4-74517abb758d'
}
# Using K2 Connect - https://github.com/kopokopo/k2-connect-python (Recommended)
k2connect.initialize(environ.get('CLIENT_ID'), environ.get('CLIENT_SECRET'), 'http://127.0.0.1:3000/')
transfer_service = k2connect.Transfers
transfer_location_url = transfer_service.settle_funds(request_body)
transfer_location_url # => 'https://sandbox.kopokopo.com/api/v2/transfers/d76265cd-0951-e511-80da-0aa34a9b2388'
var transferOpts = {
accessToken: 'myRand0mAcc3ssT0k3n',
callbackUrl: 'https://your-call-bak.yourapplication.com/transfer_result'
}
// Using Kopo Kopo Connect - https://github.com/kopokopo/k2-connect-node (Recommended)
const TransferService = K2.TransferService
TransferService
.settleFunds(transferOpts)
.then(response => {
console.log(response) // => 'https://sandbox.kopokopo.com/api/v2/settlement_transfers/d76265cd-0951-e511-80da-0aa34a9b2388'
})
.catch(error => {
console.log(error)
})
<?
// Using Kopo Kopo Connect - https://github.com/kopokopo/k2-connect-php (Recommended)
$sendMoneyService = $k2->SendMoneyService();
$sendMoneyRequest = [
"currency" => "KES",
"metadata" => [
"notes" => "Salary payment for September 2025"
],
"callbackUrl" => "https://your-call-bak.yourapplication.com/send_money_result",
"accessToken" => "myRand0mAcc3ssT0k3n"
];
// For Kopo Kopo API applications, an accessToken can be used for this endpoint. (https://api-docs.kopokopo.com/#application-authorization)
$response = $sendMoneyService->sendMoney($sendMoneyRequest);
print_r($response); // Array([status] => success, [location] => https://sandbox.kopokopo.com/api/v2/send_money/d76265cd-0951-e511-80da-0aa34a9b2388)
Create a blind transfer without specifying the amount NOR the destination. Your available funds will be sent to your preferred settlement location(s) that are linked to your company and tills.
HTTP Request
POST https://sandbox.kopokopo.com/api/v2/send_money Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
Request Parameters (JSON)
| Parameter | Required | Type | Description |
|---|---|---|---|
| currency | No | String | Currency of funds to transfer |
| metadata | No | JSON | A JSON object with a maximum of 5 key-value pairs containing additional contextual information about the transfer. The values must be primitive data types |
| _links | Yes | JSON | A JSON containing a call back URL where the results of the Settlement Transfer will be posted. MUST be a secure HTTPS (TLS) endpoint |
HTTP Response
Successful Response
Upon successful initiation of the transfer, HTTP Status Code 201 with the URL of the transfer in the Location Header of the HTTP Response.
HTTP/1.1 201 Created
Location: https://sandbox.kopokopo.com/api/v2/send_money/d76265cd-0951-e511-80da-0aa34a9b2388
Error Response
This will have a HTTP Status code indicating the error and it might have a json that contains the error code and an error message specifying the error that occured. Please note that the error response might not be present depending on the type of error that occured.
If the error json response is present, it will look as follows:
HTTP/1.1 400 Bad Request
{ "error_code": 400, "error_message": "Callback url can't be blank" }
Send Money to my account
POST https://sandbox.kopokopo.com/api/v2/send_money Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
{
"destinations": [
{
"type": "merchant_bank_account",
"reference": "e479b8de-d05d-46f1-89ea-27948293f5df",
"amount": 100,
"description": null
}
],
"source_identifier": "4321",
"currency": "KES",
"metadata": {
"customerId": "8675309",
"notes": "Salary payment for September 2025"
},
"_links": {
"callback_url": "https://your-call-bak.yourapplication.com/send_money_result"
}
}
transfer_request = {
destination_reference: '38f7c997-527c-452f-adc4-49ffab98982e',
destination_type: 'merchant_bank_account',
currency: 'currency',
value: 'value',
callback_url: 'callback_url',
}
# Using K2Connect - https://github.com/kopokopo/k2-connect-ruby (Recommended)
k2_transfer = K2Transfer.new('your_access_token')
k2_transfer.transfer_funds(transfer_request)
k2_transfer.location_url # => "https://sandbox.kopokopo.com/api/v2/transfers/d76265cd-0951-e511-80da-0aa34a9b2388"
request_body = {
"access_token": ACCESS_TOKEN,
"destination_type": 'merchant_bank_account',
"destination_reference": '6ad03242-2c6e-4050-8e46-987cb74f5326',
"callback_url": 'https://webhook.site/52fd1913-778e-4ee1-bdc4-74517abb758d',
"value": '10',
}
# Using K2 Connect - https://github.com/kopokopo/k2-connect-python (Recommended)
k2connect.initialize(environ.get('CLIENT_ID'), environ.get('CLIENT_SECRET'), 'http://127.0.0.1:3000/')
transfer_service = k2connect.Transfers
transfer_location_url = transfer_service.settle_funds(request_body)
transfer_location_url # => 'https://sandbox.kopokopo.com/api/v2/transfers/d76265cd-0951-e511-80da-0aa34a9b2388'
var transferOpts = {
amount : 2250.00,
currency: 'KES',
destinationType: 'merchant_bank_account',
destinationReference: '38f7c997-527c-452f-adc4-49ffab98982e',
accessToken: 'myRand0mAcc3ssT0k3n',
callbackUrl: 'https://your-call-bak.yourapplication.com/transfer_result'
}
// Using Kopo Kopo Connect - https://github.com/kopokopo/k2-connect-node (Recommended)
const TransferService = K2.TransferService
TransferService
.settleFunds(transferOpts)
.then(response => {
console.log(response) // => 'https://sandbox.kopokopo.com/api/v2/settlement_transfers/d76265cd-0951-e511-80da-0aa34a9b2388'
})
.catch(error => {
console.log(error)
})
<?
// Using Kopo Kopo Connect - https://github.com/kopokopo/k2-connect-php (Recommended)
$sendMoneyService = $k2->SendMoneyService();
$sendMoneyRequest = [
"destinations" => [
[
"type" => "merchant_wallet", // or merchant_bank_account
"reference" => "af033d43-75f7-4123-b5c3-252377d96739",
"amount" => 250
]
],
"currency" => "KES",
"sourceIdentifier": "4321",
"metadata" => [
"notes" => "Salary payment for September 2025"
],
"callbackUrl" => "https://your-call-bak.yourapplication.com/send_money_result",
"accessToken" => "myRand0mAcc3ssT0k3n"
];
// For Kopo Kopo API applications, an accessToken can be used for this endpoint. (https://api-docs.kopokopo.com/#application-authorization)
$response = $sendMoneyService->sendMoney($sendMoneyRequest);
print_r($response); // Array([status] => success, [location] => https://sandbox.kopokopo.com/api/v2/send_money/cb95aa2d-cd7f-4c9f-9d16-a2eb1a7fef42)
Create a transfer from your Kopo Kopo account by specifying the destination of the funds.
HTTP Request
POST https://sandbox.kopokopo.com/api/v2/send_money Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
Request Parameters (JSON)
| Parameter | Required | Type | Description |
|---|---|---|---|
| destinations | Yes | JSON | A JSON object containing destinations details |
| source_identifier | No | String | Till number or null for available balance |
| currency | No | String | Currency of funds to transfer |
| metadata | No | JSON | A JSON object with a maximum of 5 key-value pairs containing additional contextual information about the transfer. The values must be primitive data types |
| _links | Yes | JSON | A JSON containing a call back URL where the results of the Settlement Transfer will be posted. MUST be a secure HTTPS (TLS) endpoint |
Destination JSON
| Parameter | Required | Type | Description |
|---|---|---|---|
| type | Yes | String | Type of destination. Either merchant_wallet or merchant_bank_account |
| amount | Yes | Integer | Amount to transfer |
| reference | Yes | String | Identifier of the destination account of the funds. Details on how to locate an account's destination reference are here |
| description | No | String | Description of the transfer |
HTTP Response
Successful Response
Upon successful initiation of the transfer, HTTP Status Code 201 with the URL of the transfer in the Location Header of the HTTP Response.
HTTP/1.1 201 Created
Location: https://sandbox.kopokopo.com/api/v2/send_money/d76265cd-0951-e511-80da-0aa34a9b2388
Error Response
This will have HTTP Status code indicating the error, and it might have a json that contains the error code and an error message specifying the error that occurred. Please note that the error response might not be present depending on the type of error that occured.
If the error json response is present, it will look as follows:
HTTP/1.1 400 Bad Request
{ "error_code": 400, "error_message": "Destination reference is invalid" }
Send Money to external recipients
POST https://sandbox.kopokopo.com/api/v2/send_money Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
{
"destinations": [
{
"type": "mobile_wallet",
"nickname": "Jane Doe",
"phone_number": "254900000000",
"network": "Safaricom",
"amount": 1000,
"description": "Reason for payment",
"favourite": true
},
{
"type": "mobile_wallet",
"nickname": "John Doe",
"phone_number": "254900111111",
"network": "Safaricom",
"amount": 1000,
"description": "Reason for payment",
"favourite": true
}
],
"source_identifier": "4321",
"currency": "KES",
"metadata": {
"customerId": "8675309",
"notes": "Salary payment for September 2025"
},
"_links": {
"callback_url": "https://your-call-bak.yourapplication.com/send_money_result"
}
}
your_input = {
destination_type: "bank_account",
destination_reference: "c7f300c0-f1ef-4151-9bbe-005005aa3747",
currency: "KES",
value: 20000,
description: "Salary payment for May 2018",
category: "salaries",
tags: ["tag 1", "tag 2"],
metadata: {
customer_id: "8675309",
notes: "Salary payment for May 2018"
},
callback_url: "https://your-call-bak.yourapplication.com/payment_result"
}
# Using K2Connect - https://github.com/kopokpo/k2-connect-ruby (Recommended)
k2_pay = K2Pay.new('your_access_token')
k2_pay.create_payment(your_input)
k2_pay.payments_location_url # => "https://sandbox.kopokopo.com/api/v2/payments/d76265cd-0951-e511-80da-0aa34a9b2388"
payment_request = {
"access_token": ACCESS_TOKEN,
"destination_reference": '3344-effefnkka-132',
"destination_type": 'mobile_wallet',
"callback_url": 'https://webhook.site/52fd1913-778e-4ee1-bdc4-74517abb758d',
"amount": '10',
"currency": 'KES'
"description": "Salary payment for May 2018",
"category": 'salaries',
"tags": ["tag 1", "tag 2"]
}
# Using k2-connect - https://github.com/kopokopo/k2-connect-python (Recommended)
pay_service = k2connect.Pay
create_pay_location = pay_service.send_pay(payment_request)
create_pay_location # => 'https://sandbox.kopokopo.com/api/v2/payments/d76265cd-0951-e511-80da-0aa34a9b2388'
var paymentRequest = {
destinationType: 'bank_account',
destinationReference: 'c7f300c0-f1ef-4151-9bbe-005005aa3747',
amount: '20000',
currency: 'KES',
description: 'Salary payment for May 2018',
category: "salaries",
tags: ["tag 1", "tag 2"],
metadata: {
customer_id: '8675309',
notes: 'Salary payment for May 2018'
},
callbackUrl: 'https://your-call-bak.yourapplication.com/payment_result'
}
// Using Kopo Kopo Connect - https://github.com/kopokopo/k2-connect-node (Recommended)
const PayService = K2.PayService
PayService
.sendPay(paymentRequest)
.then(function(res) {
console.log(response)
// => 'https://sandbox.kopokopo.com/api/v2/payments/d76265cd-0951-e511-80da-0aa34a9b2388'
})
.catch( error => {
console.log(error)
})
<?
// Using KopoKopoConnect - https://github.com/kopokopo/k2-connect-php (Recommended
$sendMoneyService = $K2->SendMoneyService();
$sendMoneyRequest = [
"destinations" => [
[
"type" => "mobile_wallet",
"amount" => 1000,
"network" => "Safaricom",
"nickname" => "External Wallet 1",
"favourite" => true,
"description" => "Sending money to external mobile wallet 1",
"phoneNumber" => "25490000000"
],
[
"type" => "mobile_wallet",
"amount" => 1000,
"network" => "Safaricom",
"nickname" => "External Wallet 2",
"favourite" => false,
"description" => "Sending money to external mobile wallet 2",
"phoneNumber" => "254900111222"
]
],
"currency" => "KES",
"sourceIdentifier" => "4321",
"metadata" => [
"notes" => "Salary payment for September 2025"
],
"callbackUrl" => "https://your-call-bak.yourapplication.com/send_money_result",
"accessToken" => "myRand0mAcc3ssT0k3n"
];
$response = $sendMoneyService->sendMoney($sendMoneyRequest);
print_r($response); // Array([status] => success, [location] => https://sandbox.kopokopo.com/api/v2/send_money/1854d8ad-3c3c-4842-a965-5d8ea7a3cad7)
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
Create an outgoing payment to a third party. The final result of the payment will be posted asynchronously to your systems via the call back URL provided in the request.
Note: Send Money to multiple destinations is only supported for mobile_wallet and bank_account destination types.
All destinations included in a single request must be of the same type (i.e., you cannot mix different destination types within one request).
HTTP Request
POST https://sandbox.kopokopo.com/api/v2/send_money Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
Request Parameters (JSON)
| Parameter | Required | Type | Description |
|---|---|---|---|
| destinations | Yes | JSON | A JSON object containing destinations details |
| source_identifier | No | String | Till number or null for available balance |
| currency | No | String | Currency of funds to transfer |
| metadata | No | JSON | A JSON object with a maximum of 5 key-value pairs containing additional contextual information about the transfer. The values must be primitive data types |
| _links | Yes | JSON | A JSON containing a call back URL where the results of the Settlement Transfer will be posted. MUST be a secure HTTPS (TLS) endpoint |
External Mobile Wallet Destination JSON (Could be multiple)
| Parameter | Required | Type | Description |
|---|---|---|---|
| type | Yes | String | Type of destination. Must be mobile_wallet |
| phone_number | Yes | String | Phone number |
| network | Yes | String | The mobile network to which the phone number belongs |
| amount | Yes | Integer | Amount to transfer |
| nickname | No | String | Nickname for the external mobile wallet |
| description | Yes | String | Description of the transfer |
| favourite | No | Boolean | Mark destination as favorite or not |
External Bank Account Destination JSON (Could be multiple)
| Parameter | Required | Type | Description |
|---|---|---|---|
| type | Yes | String | Type of destination. Must be bank_account |
| bank_branch_ref | Yes | String | An identifier identifying the destination bank branch. Details on how to get a bank_branch_ref are here |
| account_name | Yes | String | Bank account name |
| account_number | Yes | String | Bank account number |
| nickname | No | String | Nickname for the external bank account |
| amount | Yes | Integer | Amount to transfer |
| description | Yes | String | Description of the transfer |
| favourite | No | Boolean | Mark destination as favorite or not |
External Till Destination JSON
| Parameter | Required | Type | Description |
|---|---|---|---|
| type | Yes | String | Type of destination. Must be till |
| till_number | Yes | String | Till number |
| nickname | No | String | Nickname for the external till |
| amount | Yes | Integer | Amount to transfer |
| description | Yes | String | Description of the transfer |
| favourite | No | Boolean | Mark destination as favorite or not |
External Paybill Destination JSON
| Parameter | Required | Type | Description |
|---|---|---|---|
| type | Yes | String | Type of destination. Must be paybill |
| paybill_number | Yes | String | Paybill number |
| paybill_account_number | Yes | String | Paybill account number |
| nickname | No | String | Nickname for the paybill account |
| amount | Yes | Integer | Amount to transfer |
| description | Yes | String | Description of the transfer |
| favourite | No | Boolean | Mark destination as favorite or not |
HTTP Response
Successful Response
A HTTP response code of 201 is returned upon successful creation of the Payment request. The URL of the Payment
resource is also returned in the HTTP Location Header
HTTP/1.1 201 Created
Location: https://sandbox.kopokopo.com/api/v2/send_money/c7f300c0-f1ef-4151-9bbe-005005aa3747
Error Response
This will have a HTTP Status code indicating the error and it might have a json that contains the error code and an error message specifying the error that occured. Please note that the error response might not be present depending on the type of error that occured.
If the error json response is present, it will look as follows:
HTTP/1.1 400 Bad Request
{ "error_code": 400, "error_message": "Destination type can't be blank" }
Process Send Money result
POST https://your-callback-url.com/send_money_result Content-Type: application/json X-KopoKopo-Signature: 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
{
"data": {
"id": "716481bc-635c-4d35-92c9-65bb0797196a",
"type": "send_money",
"attributes": {
"status": "Processed",
"created_at": "2025-09-23T20:05:46.522+03:00",
"source_identifier": "4321",
"destinations": [
{
"type": "mobile_wallet",
"amount": 1000,
"network": "Safaricom",
"nickname": "Test",
"favourite": true,
"description": "Testing",
"phone_number": "254900000000"
},
{
"type": "mobile_wallet",
"amount": 1000,
"network": "Safaricom",
"nickname": "Test2",
"favourite": true,
"description": "Testing",
"phone_number": "254900111111"
}
],
"currency": "KES",
"transfer_batches": [
{
"status": "Transferred",
"amount": "1000.0",
"disbursements": [
{
"amount": "1000.0",
"errors": null,
"status": "Transferred",
"nickname": "Test",
"favourite": true,
"phone_number": "254900111111",
"destination_type": "mobile_wallet",
"origination_time": "2025-09-23T20:22:59.913+03:00",
"destination_reference": "a3bd6298-8a5a-4a93-b880-7948a621fdfb",
"transaction_reference": "QCL160124A7"
}
]
},
{
"status": "Transferred",
"amount": "1000.0",
"disbursements": [
{
"amount": "1000.0",
"errors": null,
"status": "Transferred",
"nickname": "Test",
"favourite": true,
"phone_number": "254900000000",
"destination_type": "mobile_wallet",
"origination_time": "2025-09-23T20:26:49.173+03:00",
"destination_reference": "5f58ce16-0320-4da8-ad38-0f2cf7f520f2",
"transaction_reference": "QDZ273694C8"
}
]
}
],
"errors": null,
"metadata": {
"notes": "Salary payment for September 2025",
"customerId": "8675309"
},
"_links": {
"callback_url": "https://webhook.site/f0b07170-4397-4e81-b552-a6bc0fc20ed9",
"self": "https://api.kopokopo.com/api/v2/send_money/716481bc-635c-4d35-92c9-65bb0797196a"
}
}
}
}
send_money_client = K2Client.new(ENV["API_KEY"])
send_money_client.parse_request(request)
send_money_object = K2ProcessResult.process(send_money_client.hash_body, API_KEY, send_money_client.k2_signature)
# Processed send money result in json format
{
"data": {
"id": "716481bc-635c-4d35-92c9-65bb0797196a",
"type": "send_money",
"attributes": {
"status": "Processed",
"created_at": "2025-09-23T20:05:46.522+03:00",
"source_identifier": "4321",
"destinations": [
{
"type": "mobile_wallet",
"amount": 1000,
"network": "Safaricom",
"nickname": "Test",
"favourite": true,
"description": "Testing",
"phone_number": "254900000000"
},
{
"type": "mobile_wallet",
"amount": 1000,
"network": "Safaricom",
"nickname": "Test2",
"favourite": true,
"description": "Testing",
"phone_number": "254900111111"
}
],
"currency": "KES",
"transfer_batches": [
{
"status": "Transferred",
"amount": "1000.0",
"disbursements": [
{
"amount": "1000.0",
"errors": null,
"status": "Transferred",
"nickname": "Test",
"favourite": true,
"phone_number": "254900111111",
"destination_type": "mobile_wallet",
"origination_time": "2025-09-23T20:22:59.913+03:00",
"destination_reference": "a3bd6298-8a5a-4a93-b880-7948a621fdfb",
"transaction_reference": "QCL160124A7"
}
]
},
{
"status": "Transferred",
"amount": "1000.0",
"disbursements": [
{
"amount": "1000.0",
"errors": null,
"status": "Transferred",
"nickname": "Test",
"favourite": true,
"phone_number": "254900000000",
"destination_type": "mobile_wallet",
"origination_time": "2025-09-23T20:26:49.173+03:00",
"destination_reference": "5f58ce16-0320-4da8-ad38-0f2cf7f520f2",
"transaction_reference": "QDZ273694C8"
}
]
}
],
"errors": null,
"metadata": {
"notes": "Salary payment for September 2025",
"customerId": "8675309"
},
"_links": {
"callback_url": "https://webhook.site/f0b07170-4397-4e81-b552-a6bc0fc20ed9",
"self": "https://api.kopokopo.com/api/v2/send_money/716481bc-635c-4d35-92c9-65bb0797196a"
}
}
}
}
k2connect.initialize(CLIENT_ID, CLIENT_SECRET, BASE_URL)
result_handler = k2connect.ResultHandler
processed_payload = result_handler.process(request)
decomposed_result = payload_decomposer.decompose(processed_payload)
# Processed send money result in json format
{
"data": {
"id": "716481bc-635c-4d35-92c9-65bb0797196a",
"type": "send_money",
"attributes": {
"status": "Processed",
"created_at": "2025-09-23T20:05:46.522+03:00",
"source_identifier": "4321",
"destinations": [
{
"type": "mobile_wallet",
"amount": 1000,
"network": "Safaricom",
"nickname": "Test",
"favourite": true,
"description": "Testing",
"phone_number": "254900000000"
},
{
"type": "mobile_wallet",
"amount": 1000,
"network": "Safaricom",
"nickname": "Test2",
"favourite": true,
"description": "Testing",
"phone_number": "254900111111"
}
],
"currency": "KES",
"transfer_batches": [
{
"status": "Transferred",
"amount": "1000.0",
"disbursements": [
{
"amount": "1000.0",
"errors": null,
"status": "Transferred",
"nickname": "Test",
"favourite": true,
"phone_number": "254900111111",
"destination_type": "mobile_wallet",
"origination_time": "2025-09-23T20:22:59.913+03:00",
"destination_reference": "a3bd6298-8a5a-4a93-b880-7948a621fdfb",
"transaction_reference": "QCL160124A7"
}
]
},
{
"status": "Transferred",
"amount": "1000.0",
"disbursements": [
{
"amount": "1000.0",
"errors": null,
"status": "Transferred",
"nickname": "Test",
"favourite": true,
"phone_number": "254900000000",
"destination_type": "mobile_wallet",
"origination_time": "2025-09-23T20:26:49.173+03:00",
"destination_reference": "5f58ce16-0320-4da8-ad38-0f2cf7f520f2",
"transaction_reference": "QDZ273694C8"
}
]
}
],
"errors": null,
"metadata": {
"notes": "Salary payment for September 2025",
"customerId": "8675309"
},
"_links": {
"callback_url": "https://webhook.site/f0b07170-4397-4e81-b552-a6bc0fc20ed9",
"self": "https://api.kopokopo.com/api/v2/send_money/716481bc-635c-4d35-92c9-65bb0797196a"
}
}
}
}
{
"data": {
"id": "716481bc-635c-4d35-92c9-65bb0797196a",
"type": "send_money",
"attributes": {
"status": "Processed",
"created_at": "2025-09-23T20:05:46.522+03:00",
"source_identifier": "4321",
"destinations": [
{
"type": "mobile_wallet",
"amount": 1000,
"network": "Safaricom",
"nickname": "Test",
"favourite": true,
"description": "Testing",
"phone_number": "254900000000"
},
{
"type": "mobile_wallet",
"amount": 1000,
"network": "Safaricom",
"nickname": "Test2",
"favourite": true,
"description": "Testing",
"phone_number": "254900111111"
}
],
"currency": "KES",
"transfer_batches": [
{
"status": "Transferred",
"amount": "1000.0",
"disbursements": [
{
"amount": "1000.0",
"errors": null,
"status": "Transferred",
"nickname": "Test",
"favourite": true,
"phone_number": "254900111111",
"destination_type": "mobile_wallet",
"origination_time": "2025-09-23T20:22:59.913+03:00",
"destination_reference": "a3bd6298-8a5a-4a93-b880-7948a621fdfb",
"transaction_reference": "QCL160124A7"
}
]
},
{
"status": "Transferred",
"amount": "1000.0",
"disbursements": [
{
"amount": "1000.0",
"errors": null,
"status": "Transferred",
"nickname": "Test",
"favourite": true,
"phone_number": "254900000000",
"destination_type": "mobile_wallet",
"origination_time": "2025-09-23T20:26:49.173+03:00",
"destination_reference": "5f58ce16-0320-4da8-ad38-0f2cf7f520f2",
"transaction_reference": "QDZ273694C8"
}
]
}
],
"errors": null,
"metadata": {
"notes": "Salary payment for September 2025",
"customerId": "8675309"
},
"_links": {
"callback_url": "https://webhook.site/f0b07170-4397-4e81-b552-a6bc0fc20ed9",
"self": "https://api.kopokopo.com/api/v2/send_money/716481bc-635c-4d35-92c9-65bb0797196a"
}
}
}
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"data" => [
"id" => "716481bc-635c-4d35-92c9-65bb0797196a",
"type" => "send_money",
"attributes" => [
"status" => "Processed",
"created_at" => "2025-09-23T20:05:46.522+03:00",
"source_identifier" => "4321",
"destinations" => [
[
"type" => "mobile_wallet",
"amount" => 1000,
"network" => "Safaricom",
"nickname" => "Test",
"favourite" => true,
"description" => "Testing",
"phone_number" => "254900000000"
],
[
"type" => "mobile_wallet",
"amount" => 1000,
"network" => "Safaricom",
"nickname" => "Test2",
"favourite" => true,
"description" => "Testing",
"phone_number" => "254900111111"
]
],
"currency" => "KES",
"transfer_batches" => [
[
"status" => "Transferred",
"amount" => "1000.0",
"disbursements" => [
[
"amount" => "1000.0",
"errors" => null,
"status" => "Transferred",
"nickname" => "Test",
"favourite" => true,
"phone_number" => "254900111111",
"destination_type" => "mobile_wallet",
"origination_time" => "2025-09-23T20:22:59.913+03:00",
"destination_reference" => "a3bd6298-8a5a-4a93-b880-7948a621fdfb",
"transaction_reference" => "QCL160124A7"
]
]
],
[
"status" => "Transferred",
"amount" => "1000.0",
"disbursements" => [
[
"amount" => "1000.0",
"errors" => null,
"status" => "Transferred",
"nickname" => "Test",
"favourite" => true,
"phone_number" => "254900000000",
"destination_type" => "mobile_wallet",
"origination_time" => "2025-09-23T20:26:49.173+03:00",
"destination_reference" => "5f58ce16-0320-4da8-ad38-0f2cf7f520f2",
"transaction_reference" => "QDZ273694C8"
]
]
]
],
"errors" => null,
"metadata" => [
"notes" => "Salary payment for September 2025",
"customerId" => "8675309"
],
"_links" => [
"callback_url" => "https://webhook.site/f0b07170-4397-4e81-b552-a6bc0fc20ed9",
"self" => "https://api.kopokopo.com/api/v2/send_money/716481bc-635c-4d35-92c9-65bb0797196a"
]
]
]
]
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
After a Send Money request is initiated, a Send Money result will be posted asynchronously to the callback URL specified in the Send Money request. This callback is secured by signing the payload of the request (HMAC) and passing the signature in the X-KopoKopo-Signature HTTP header.
Send Money Result Parameters (JSON)
A HTTP response with the following JSON payload is returned.
| Parameter | Required | Type | Description |
|---|---|---|---|
| id | Yes | String | The ID of the transfer |
| type | Yes | String | Request type, i.e., send_money |
| attributes | Yes | JSON | A JSON object containing the attributes of the Send Money request |
Attributes JSON
| Parameter | Required | Type | Description |
|---|---|---|---|
| status | Yes | String | Current status of the Send Money request |
| created_at | Yes | String | Timestamp when the Send Money request was created |
| currency | Yes | String | Currency of funds to transfer |
| source_identifier | Yes | String | Till number or null if Send Money request was from available balance |
| destinations | Yes | JSON | A JSON object containing destinations details or null for Send Money requests to my accounts |
| transfer_batches | Yes | JSON | A JSON object containing transfer batches information |
| errors | Yes | JSON | A JSON object containing errors for failed Send Money request |
| metadata | Yes | JSON | A JSON object with a maximum of 5 key-value pairs containing additional contextual information about the transfer. The values must be primitive data types |
| _links | Yes | JSON | A JSON object containing the URL pointing to the Send Money request and the callback url |
Transfer Batches JSON (Could be multiple)
| Parameter | Type | Description |
|---|---|---|
| status | String | The status of the transfer batch |
| amount | String | The total amount of the transfer batch |
| disbursements | JSON | These are the disbursements in that particular transfer batch |
Disbursements JSON (Could be multiple)
| Parameter | Type | Description |
|---|---|---|
| status | String | The status of the disbursement |
| amount | String | The amount of the disbursement |
| errors | JSON | A JSON object containing errors for failed disbursement |
| origination_time | String | Timestamp of when the transaction took place |
| destination_type | String | Type of destination, .i.e, merchant_bank_account, merchant_wallet, mobile_wallet, bank_account, till or paybill |
| destination_reference | String | Identifier of the destination account of the funds |
| transaction_reference | String | The reference from the transaction, i.e, mpesa reference. It is null for eft transactions |
Query Send Money request status
GET https://sandbox.kopokopo.com/api/v2/send_money/1b7c1ec2-8c3f-49b8-9b73-3a94fc60c6ab Accept: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q Content-Type: application/json User-Agent: < product >/< product-version > < comment >
transfer_url = 'https://sandbox.kopokopo.com/api/v2/settlement_transfers/d76265cd-0951-e511-80da-0aa34a9b2388'
# Using K2 Connect - https://github.com/kopokopo/k2-connect-ruby (Recommended)
k2_transfer = K2Transfer.new('your_access_token')
k2_transfer.query_resource_url(transfer_url) or k2_transfer.query_resource_url(k2_transfer.location_url)
# Query most recent request
k2_transfer.query_status
transfer_url = 'https://sandbox.kopokopo.com/api/v2/settlement_transfers/d76265cd-0951-e511-80da-0aa34a9b2388'
# Using K2 Connect - https://github.com/kopokopo/k2-connect-python (Recommended)
k2connect.initialize(environ.get('CLIENT_ID'), environ.get('CLIENT_SECRET'), 'http://127.0.0.1:3000/')
transfer_service = k2connect.Transfers
transfer_service.transfer_transaction_status(access_token, transfer_url)
var transferUrl = 'https://sandbox.kopokopo.com/api/v2/settlement_transfers/d76265cd-0951-e511-80da-0aa34a9b2388'
// Using Kopo Kopo Connect - https://github.com/kopokopo/k2-connect-node (Recommended)
const TransferService = K2.TransferService
TransferService
.getStatus({accessToken: 'myRand0mAcc3ssT0k3n', location: transferUrl})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
<?
// Using Kopo Kopo Connect - https://github.com/kopokopo/k2-connect-php (Recommended)
$transfer = $K2->SettlementTransferService();
$options = [
'location' => 'https://sandbox.kopokopo.com/api/v2/settlement_transfers/d76265cd-0951-e511-80da-0aa34a9b2388',
'accessToken' => 'myRand0mAcc3ssT0k3n',
];
$response = $transfer->getStatus($options);
echo $response;
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
The request above results in the following JSON payload
{
"data": {
"id": "716481bc-635c-4d35-92c9-65bb0797196a",
"type": "send_money",
"attributes": {
"status": "Processed",
"created_at": "2025-09-23T20:05:46.522+03:00",
"source_identifier": "4321",
"destinations": [
{
"type": "mobile_wallet",
"amount": 1000,
"network": "Safaricom",
"nickname": "Test",
"favourite": true,
"description": "Testing",
"phone_number": "254900000000"
},
{
"type": "mobile_wallet",
"amount": 1000,
"network": "Safaricom",
"nickname": "Test",
"favourite": true,
"description": "Testing",
"phone_number": "254900111111"
}
],
"currency": "KES",
"transfer_batches": [
{
"status": "Transferred",
"amount": "1000.0",
"disbursements": [
{
"amount": "1000.0",
"errors": null,
"status": "Transferred",
"nickname": "Test",
"favourite": true,
"phone_number": "254900111111",
"destination_type": "mobile_wallet",
"origination_time": "2025-09-23T20:22:59.913+03:00",
"destination_reference": "a3bd6298-8a5a-4a93-b880-7948a621fdfb",
"transaction_reference": "QCL160124A7"
}
]
},
{
"status": "Transferred",
"amount": "1000.0",
"disbursements": [
{
"amount": "1000.0",
"errors": null,
"status": "Transferred",
"nickname": "Test",
"favourite": true,
"phone_number": "254900000000",
"destination_type": "mobile_wallet",
"origination_time": "2025-09-23T20:26:49.173+03:00",
"destination_reference": "5f58ce16-0320-4da8-ad38-0f2cf7f520f2",
"transaction_reference": "QDZ273694C8"
}
]
}
],
"errors": null,
"metadata": {
"notes": "Salary payment for September 2025",
"customerId": "8675309"
},
"_links": {
"callback_url": "https://webhook.site/f0b07170-4397-4e81-b552-a6bc0fc20ed9",
"self": "https://api.kopokopo.com/api/v2/send_money/716481bc-635c-4d35-92c9-65bb0797196a"
}
}
}
}
{
"data": {
"id": "01aece24-e596-4f5c-9ace-9eb1a0939dda",
"type": "settlement_transfer",
"attributes": {
"status": "Processed",
"created_at": "2021-01-27T10:57:09.838+03:00",
"amount": {
"currency": "KES",
"value": null
},
"transfer_batches": [
{
"status": "Transferred",
"disbursements": [
{
"amount": "19900.0",
"status": "Transferred",
"destination_type": "Mobile Wallet",
"origination_time": "2021-01-06T12:42:36.000+03:00",
"destination_reference": "17067bf7-648e-424c-af0f-8c541a1b4ec3",
"transaction_reference": "LDLJANAPH26"
}
]
},
{
"status": "Transferred",
"disbursements": [
{
"amount": "24452.0",
"status": "Transferred",
"destination_type": "Bank Account",
"origination_time": "2021-01-27T10:57:58.623+03:00",
"destination_reference": "34a273d1-fedc-4610-8ab6-a1ba4828f317",
"transaction_reference": null
},
{
"amount": "25000.0",
"status": "Transferred",
"destination_type": "Bank Account",
"origination_time": "2021-01-27T10:57:58.627+03:00",
"destination_reference": "34a273d1-fedc-4610-8ab6-a1ba4828f317",
"transaction_reference": null
}
]
}
],
"_links": {
"callback_url": "https://webhook.site/3856ff77-93eb-4130-80cd-e62dc0db5c1a",
"self": "https://sandbox.kopokopo.com/api/v2/settlement_transfers/01aece24-e596-4f5c-9ace-9eb1a0939dda"
}
}
}
}
{
"data": {
"id": "01aece24-e596-4f5c-9ace-9eb1a0939dda",
"type": "settlement_transfer",
"attributes": {
"status": "Processed",
"created_at": "2021-01-27T10:57:09.838+03:00",
"amount": {
"currency": "KES",
"value": null
},
"transfer_batches": [
{
"status": "Transferred",
"disbursements": [
{
"amount": "19900.0",
"status": "Transferred",
"destination_type": "Mobile Wallet",
"origination_time": "2021-01-06T12:42:36.000+03:00",
"destination_reference": "17067bf7-648e-424c-af0f-8c541a1b4ec3",
"transaction_reference": "LDLJANAPH26"
}
]
},
{
"status": "Transferred",
"disbursements": [
{
"amount": "24452.0",
"status": "Transferred",
"destination_type": "Bank Account",
"origination_time": "2021-01-27T10:57:58.623+03:00",
"destination_reference": "34a273d1-fedc-4610-8ab6-a1ba4828f317",
"transaction_reference": null
},
{
"amount": "25000.0",
"status": "Transferred",
"destination_type": "Bank Account",
"origination_time": "2021-01-27T10:57:58.627+03:00",
"destination_reference": "34a273d1-fedc-4610-8ab6-a1ba4828f317",
"transaction_reference": null
}
]
}
],
"_links": {
"callback_url": "https://webhook.site/3856ff77-93eb-4130-80cd-e62dc0db5c1a",
"self": "https://sandbox.kopokopo.com/api/v2/settlement_transfers/01aece24-e596-4f5c-9ace-9eb1a0939dda"
}
}
}
}
{
"data": {
"id": "01aece24-e596-4f5c-9ace-9eb1a0939dda",
"type": "settlement_transfer",
"attributes": {
"status": "Processed",
"created_at": "2021-01-27T10:57:09.838+03:00",
"amount": {
"currency": "KES",
"value": null
},
"transfer_batches": [
{
"status": "Transferred",
"disbursements": [
{
"amount": "19900.0",
"status": "Transferred",
"destination_type": "Mobile Wallet",
"origination_time": "2021-01-06T12:42:36.000+03:00",
"destination_reference": "17067bf7-648e-424c-af0f-8c541a1b4ec3",
"transaction_reference": "LDLJANAPH26"
}
]
},
{
"status": "Transferred",
"disbursements": [
{
"amount": "24452.0",
"status": "Transferred",
"destination_type": "Bank Account",
"origination_time": "2021-01-27T10:57:58.623+03:00",
"destination_reference": "34a273d1-fedc-4610-8ab6-a1ba4828f317",
"transaction_reference": null
},
{
"amount": "25000.0",
"status": "Transferred",
"destination_type": "Bank Account",
"origination_time": "2021-01-27T10:57:58.627+03:00",
"destination_reference": "34a273d1-fedc-4610-8ab6-a1ba4828f317",
"transaction_reference": null
}
]
}
],
"_links": {
"callback_url": "https://webhook.site/3856ff77-93eb-4130-80cd-e62dc0db5c1a",
"self": "https://sandbox.kopokopo.com/api/v2/settlement_transfers/01aece24-e596-4f5c-9ace-9eb1a0939dda"
}
}
}
} }
}
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"id" => "f8c02eb2-c35e-42f6-8835-18074f3ca6a7",
"type" => "send_money",
"createdAt" => "2025-10-10T04:45:36.977+03:00",
"status" => "Processed",
"sourceIdentifier" => "4321",
"destinations" => [
[
"type" => "merchant_wallet",
"amount" => 1000,
"reference" => "af033d43-75f7-4123-b5c3-252377d96739"
]
],
"currency" => "KES",
"transferBatches" => [
[
"status" => "Transferred",
"amount" => "1000.0",
"disbursements" => [
[
"amount" => "1000.0",
"errors" => null,
"status" => "Transferred",
"destinationType" => "merchant_wallet",
"originationTime" => "2025-10-10T04:52:08.654+03:00",
"destinationReference" => "af033d43-75f7-4123-b5c3-252377d96739",
"transactionReference" => "OCT52342025"
]
]
]
],
"errors" => null,
"metadata" => null,
"linkSelf" => "https://sandbox.kopokopo.com/api/v2/send_money/f8c02eb2-c35e-42f6-8835-18074f3ca6a7",
"callbackUrl" => "https://your-call-bak.yourapplication.com/send_money_result"
]
]
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
Check the status of a prior initiated Send Money request.
HTTP Request
GET https://sandbox.kopokopo.com/api/v2/send_money/1b7c1ec2-8c3f-49b8-9b73-3a94fc60c6ab Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
Query Parameters
| Parameter | Required | Type | Description |
|---|---|---|---|
| ID | Yes | String | The reference / ID of the Send Money request to retrieve |
HTTP Response
A HTTP response with the following JSON payload is returned.
| Parameter | Required | Type | Description |
|---|---|---|---|
| id | Yes | String | The ID of the transfer |
| type | Yes | String | Request type. send_money |
| attributes | Yes | JSON | A JSON object containing the attributes of the Send Money request |
Attributes JSON
| Parameter | Required | Type | Description |
|---|---|---|---|
| status | Yes | String | Current status of the Send Money request |
| created_at | Yes | String | Timestamp when the Send Money request was created |
| currency | Yes | String | Currency of funds to transfer |
| source_identifier | Yes | String | Till number or null if Send Money request was from available balance |
| destinations | Yes | JSON | A JSON object containing destinations details or null for Send Money requests to my accounts |
| transfer_batches | Yes | JSON | A JSON object containing transfer batches information |
| errors | Yes | JSON | A JSON object containing errors for failed Send Money request |
| metadata | Yes | JSON | A JSON object with a maximum of 5 key-value pairs containing additional contextual information about the transfer. The values must be primitive data types |
| _links | Yes | JSON | A JSON object containing the URL pointing to the Send Money request and the callback url |
Transfer Batches JSON (Could be multiple)
| Parameter | Type | Description |
|---|---|---|
| status | String | The status of the transfer batch |
| amount | String | The total amount of the transfer batch |
| disbursements | JSON | These are the disbursements in that particular transfer batch |
Disbursements JSON (Could be multiple)
| Parameter | Type | Description |
|---|---|---|
| status | String | The status of the disbursement |
| amount | String | The amount of the disbursement |
| errors | JSON | A JSON object containing errors for failed disbursement |
| origination_time | String | Timestamp of when the transaction took place |
| destination_type | String | Type of destination, .i.e, merchant_bank_account, merchant_wallet, mobile_wallet, bank_account, till or paybill |
| destination_reference | String | Identifier of the destination account of the funds |
| transaction_reference | String | The reference from the transaction, i.e, mpesa reference. It is null for eft transactions |
Polling
Polling API Requests
Poll Buygoods Transactions between the specified dates for a particular till or for the whole company
POST https://sandbox.kopokopo.com/api/v2/polling Content-Type: application/json Accept: application/json Authorization: Bearer < AccessToken > User-Agent: "< product >/< product-version > < comment >"
{
"scope": "company",
"scope_reference": "",
"from_time": "2021-04-12T08:50:22+03:00",
"to_time": "2021-04-19T08:50:22+03:00",
"_links": {
"callback_url": "https://callback_to_your_app.your_application.com"
}
}
# Using K2Connect - https://github.com/kopokopo/k2-connect-ruby (Recommended)
your_input =
{
scope: "company",
scope_reference: "",
from_time: "2021-04-12T08:50:22+03:00",
to_time: "2021-04-19T08:50:22+03:00",
callback_url: 'https://call_back_to_your_app.your_application.com'
}
k2_polling = K2Polling.new("your_access_token")
k2_polling.poll(your_input)
k2_polling.location_url # => "https://sandbox.kopokopo.com/api/v2/polling/247b1bd8-f5a0-4b71-a898-f62f67b8ae1c"
request_body =
{
"access_token": ACCESS_TOKEN,
"callback_url": "https://webhook.site/52fd1913-778e-4ee1-bdc4-74517abb758d",
"scope": "company",
"scope_reference": "",
"from_time": "2021-04-12T08:50:22+03:00",
"to_time": "2021-04-19T08:50:22+03:00"
}
# Using K2Connect - https://github.com/kopokopo/k2-connect-python (Recommended)
k2connect.initialize(environ.get('CLIENT_ID'), environ.get('CLIENT_SECRET'), 'http://127.0.0.1:3000/')
polling_service = k2connect.Polling
polling_location = polling_service.create_polling_request(request_body)
polling_location # => 'https://sandbox.kopokopo.com/api/v2/polling/247b1bd8-f5a0-4b71-a898-f62f67b8ae1c'
const PollingService = K2.PollingService
var pollingOptions = {
scope: "company",
scopeReference: "",
fromTime: "2021-04-12T08:50:22+03:00",
toTime: "2021-04-19T08:50:22+03:00",
callbackUrl: 'https://callback_to_your_app.your_application.com/endpoint',
accessToken: 'myRand0mAcc3ssT0k3n'
}
PollingService
.pollTransactions(pollingOptions)
.then( response => {
console.log(response)
// => 'https://sandbox.kopokopo.com/api/v2/polling/247b1bd8-f5a0-4b71-a898-f62f67b8ae1c'
})
.catch( error => {
console.log(error)
})
<?
$polling = $K2->PollingService();
$response = $polling->pollTransactions([
'scope' => "company",
'scopeReference' => "",
'fromTime' => "2021-04-12T08:50:22+03:00",
'toTime' => "2021-04-19T08:50:22+03:00",
'callbackUrl' => 'https://callback_to_your_app.your_application.com/endpoint',
'accessToken' => 'myRand0mAcc3ssT0k3n',
]);
if($response['status'] == 'success')
{
echo "The resource location is:" . json_encode($response['location']);
// => 'https://sandbox.kopokopo.com/api/v2/polling/247b1bd8-f5a0-4b71-a898-f62f67b8ae1c'
}
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
HTTP Request
POST https://sandbox.kopokopo.com/api/v2/polling Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
Request Parameters (JSON)
| Parameter | Required | Type | Description |
|---|---|---|---|
| scope | yes | String | The scope of the polling request. Could be either company or till |
| scope_reference | yes | String | If the scope is till the scope reference is required and it should be your till number |
| from_time | Yes | String | A string containing a date in the iso8601 format |
| to_time | Yes | String | A string containing a date in the iso8601 format |
| _links | Yes | JSON | A JSON object containing the callback_url where the result of the Polling Query will be posted |
HTTP Response
Successful Response
Upon a successful request a HTTP Status 201 will be returned and the location HTTP Header will contain the URL of the newly created Polling API Request
HTTP/1.1 201 Created
Location: https://sandbox.kopokopo.com/api/v2/polling/247b1bd8-f5a0-4b71-a898-f62f67b8ae1c
Error Response
This will have a HTTP Status code indicating the error and it might have a json that contains the error code and an error message specifying the error that occured. Please note that the error response might not be present depending on the type of error that occured.
If the error json response is present, it will look as follows:
HTTP/1.1 400 Bad Request
{ "error_code": 400, "error_message": "Scope is invalid" }
Process Polling API Result
POST https://your-callback-url.com/api/v2/polling_result Content-Type: application/json X-KopoKopo-Signature: 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
{
"data": {
"id": "d4849121-d7d4-49f8-881f-b41601a7fe43",
"type": "polling",
"attributes": {
"status": "Success",
"created_at": "2021-04-28T11:25:53.497+03:00",
"from_time": "2021-04-12T08:50:22+03:00",
"to_time": "2021-04-19T08:50:22+03:00",
"transactions": [
{
"type": "Buygoods Transaction",
"resource": {
"id": "c4fbb520-9155-406e-aee8-661a07a49f86",
"amount": "500.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "APR202119",
"till_number": "000000",
"origination_time": "2021-04-19T08:19:00+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": "",
"sender_phone_number": "+254799999999"
}
},
{
"type": "Buygoods Transaction",
"resource": {
"id": "18f8da83-5d95-45f9-9670-1958a8fe1e30",
"amount": "500.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "APR202126",
"till_number": "K000000",
"origination_time": "2021-04-19T08:19:00+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": "",
"sender_phone_number": "+254799999999"
}
},
{
"type": "External Till to Till Transaction",
"resource": {
"id": "dfcfd000-3c43-4fff-beb3-c82718715f2e",
"amount": "1000.0",
"status": "Complete",
"system": "M-PESA",
"currency": "KES",
"reference": "JUL202410",
"till_number": "112233",
"sending_till": "John",
"origination_time": "2024-07-10T13:00:00+03:00"
}
}
],
"scope": "Company",
"scope_reference": null,
"_links": {
"callback_url": "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e",
"self": "https://sandbox.kopokopo.com/api/v2/polling/d4849121-d7d4-49f8-881f-b41601a7fe43"
}
}
}
}
polling = K2Client.new("API_KEY")
polling.parse_request(request)
polling_object = K2ProcessResult.process(polling.hash_body, API_KEY, polling.k2_signature)
# Processed polling result in json format
{
"data": {
"id": "d4849121-d7d4-49f8-881f-b41601a7fe43",
"type": "polling",
"attributes": {
"status": "Success",
"created_at": "2021-04-28T11:25:53.497+03:00",
"from_time": "2021-04-12T08:50:22+03:00",
"to_time": "2021-04-19T08:50:22+03:00",
"transactions": [
{
"type": "Buygoods Transaction",
"resource": {
"id": "c4fbb520-9155-406e-aee8-661a07a49f86",
"amount": "500.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "APR202119",
"till_number": "000000",
"origination_time": "2021-04-19T08:19:00+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": "",
"sender_phone_number": "+254799999999"
}
},
{
"type": "Buygoods Transaction",
"resource": {
"id": "18f8da83-5d95-45f9-9670-1958a8fe1e30",
"amount": "500.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "APR202126",
"till_number": "K000000",
"origination_time": "2021-04-19T08:19:00+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": "",
"sender_phone_number": "+254799999999"
}
}
],
"scope": "Company",
"scope_reference": null,
"_links": {
"callback_url": "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e",
"self": "https://sandbox.kopokopo.com/api/v2/polling/d4849121-d7d4-49f8-881f-b41601a7fe43"
}
}
}
}
k2connect.initialize(CLIENT_ID, CLIENT_SECRET, BASE_URL)
result_handler = k2connect.ResultHandler
processed_payload = result_handler.process(request)
decomposed_result = payload_decomposer.decompose(processed_payload)
# Processed polling result in json format
{
"data": {
"id": "d4849121-d7d4-49f8-881f-b41601a7fe43",
"type": "polling",
"attributes": {
"status": "Success",
"created_at": "2021-04-28T11:25:53.497+03:00",
"from_time": "2021-04-12T08:50:22+03:00",
"to_time": "2021-04-19T08:50:22+03:00",
"transactions": [
{
"type": "Buygoods Transaction",
"resource": {
"id": "c4fbb520-9155-406e-aee8-661a07a49f86",
"amount": "500.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "APR202119",
"till_number": "000000",
"origination_time": "2021-04-19T08:19:00+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": "",
"sender_phone_number": "+254799999999"
}
},
{
"type": "Buygoods Transaction",
"resource": {
"id": "18f8da83-5d95-45f9-9670-1958a8fe1e30",
"amount": "500.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "APR202126",
"till_number": "K000000",
"origination_time": "2021-04-19T08:19:00+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": "",
"sender_phone_number": "+254799999999"
}
}
],
"scope": "Company",
"scope_reference": null,
"_links": {
"callback_url": "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e",
"self": "https://sandbox.kopokopo.com/api/v2/polling/d4849121-d7d4-49f8-881f-b41601a7fe43"
}
}
}
}
{
"data": {
"id": "d4849121-d7d4-49f8-881f-b41601a7fe43",
"type": "polling",
"attributes": {
"status": "Success",
"created_at": "2021-04-28T11:25:53.497+03:00",
"from_time": "2021-04-12T08:50:22+03:00",
"to_time": "2021-04-19T08:50:22+03:00",
"transactions": [
{
"type": "Buygoods Transaction",
"resource": {
"id": "c4fbb520-9155-406e-aee8-661a07a49f86",
"amount": "500.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "APR202119",
"till_number": "000000",
"origination_time": "2021-04-19T08:19:00+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": "",
"sender_phone_number": "+254799999999"
}
},
{
"type": "Buygoods Transaction",
"resource": {
"id": "18f8da83-5d95-45f9-9670-1958a8fe1e30",
"amount": "500.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "APR202126",
"till_number": "K000000",
"origination_time": "2021-04-19T08:19:00+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": "",
"sender_phone_number": "+254799999999"
}
}
],
"scope": "Company",
"scope_reference": null,
"_links": {
"callback_url": "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e",
"self": "https://sandbox.kopokopo.com/api/v2/polling/d4849121-d7d4-49f8-881f-b41601a7fe43"
}
}
}
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"id" => "d4849121-d7d4-49f8-881f-b41601a7fe43",
"type" => "polling",
"status" => "Success",
"createdAt" => "2021-04-28T11:25:53.497+03:00",
"fromTime" => "2021-04-12T08:50:22+03:00",
"toTime" => "2021-04-19T08:50:22+03:00",
"scope" => "Company",
"scopeReference" => null,
"transactions" => [
[
"type" => "Buygoods Transaction",
"resource" => [
"id" => "c4fbb520-9155-406e-aee8-661a07a49f86",
"amount" => "500.0",
"status" => "Received",
"system" => "Lipa Na M-PESA",
"currency" => "KES",
"reference" => "APR202119",
"till_number" => "000000",
"origination_time" => "2021-04-19T08:19:00+03:00",
"sender_last_name" => "Doe",
"sender_first_name" => "Jane",
"sender_middle_name" => "",
"sender_phone_number" => "+254799999999"
]
],
[
"type" => "Buygoods Transaction",
"resource" => [
"id" => "18f8da83-5d95-45f9-9670-1958a8fe1e30",
"amount" => "500.0",
"status" => "Received",
"system" => "Lipa Na M-PESA",
"currency" => "KES",
"reference" => "APR202126",
"till_number" => "K000000",
"origination_time" => "2021-04-19T08:19:00+03:00",
"sender_last_name" => "Doe",
"sender_first_name" => "Jane",
"sender_middle_name" => "",
"sender_phone_number" => "+254799999999"
]
]
],
"linkSelf" => "https://sandbox.kopokopo.com/api/v2/polling/d4849121-d7d4-49f8-881f-b41601a7fe43",
"callbackUrl" => "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e",
]
]
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
After the Polling query is performed, a Polling Result will be posted asynchronously to the call back URL specified in the Polling API Request.
Polling Result Parameters (JSON)
Parameters contained in a successful Polling result;
| Parameter | Required | Type | Description |
|---|---|---|---|
| id | Yes | String | The ID of the Polling API Request |
| type | Yes | String | The topic of the request. polling in this instance. |
| status | Yes | String | A status string denoting the status of the Polling Request |
| from_time | Yes | Date | The from date that was specified in the request |
| to_time | Yes | Date | The to date that was specified in the request |
| transactions | No | JSON | An JSON object containing the transactions from the query with the specified parameters |
| _links | Yes | JSON | A JSON object containing links to the Polling API request |
Transactions JSON(Could be multiple)
| Parameter | Type | Description |
|---|---|---|
| type | String | The type of transaction (Buygoods Transaction) |
| resource | JSON | The resource corresponding to the event. In this case this is a Buygoods Transaction |
Resource (Buygoods Transaction) JSON
| Parameter | Type | Description |
|---|---|---|
| id | String | The api reference of the transaction |
| reference | String | The mpesa reference |
| status | String | The status of the transaction |
| origination_time | String | The transaction timestamp |
| sender_phone_number | String | The phone number that sent the payment |
| amount | Float | The amount of the transaction |
| currency | String | Currency |
| till_number | String | The till number to which the payment was made |
| system | String | The mobile money system |
| sender_first_name | String | First name of payer |
| sender_middle_name | String | Middle name of payer |
| sender_last_name | String | Last name of payer |
Query Polling API Status
GET https://sandbox.kopokopo.com/api/v2/polling/d79995cd-0111-e511-80da-0aa34a9b2388 Accept: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q Content-Type: application/json User-Agent: < product >/< product-version > < comment >
polling_url = 'https://sandbox.kopokopo.com/api/v2/polling/d4849121-d7d4-49f8-881f-b41601a7fe43'
# Using K2 Connect - https://github.com/kopokopo/k2-connect-ruby (Recommended)
k2_polling = K2Polling.new("your_access_token")
k2_polling.polling(your_input)
# Query specific resource
k2_polling.query_resource(polling_url) or k2_polling.query_resource(k2_polling.location_url)
# Query recent transaction
k2_polling.query_status
pollingUrl = 'https://sandbox.kopokopo.com/api/v2/polling/d4849121-d7d4-49f8-881f-b41601a7fe43'
# Using K2 Connect - https://github.com/kopokopo/k2-connect-python (Recommended)
k2connect.initialize(environ.get('CLIENT_ID'), environ.get('CLIENT_SECRET'), 'http://127.0.0.1:3000/')
polling_service = k2connect.Polling
polling_location = polling_service.polling_request_status(access_token, pollingUrl)
var PollingService = K2.PollingService
var pollingUrl = 'https://sandbox.kopokopo.com/api/v2/polling/d4849121-d7d4-49f8-881f-b41601a7fe43'
PollingService
.getStatus({accessToken: 'myRand0mAcc3ssT0k3n', location: pollingUrl})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
<?
$polling = $K2->PollingService();
$options = [
'location' => 'https://sandbox.kopokopo.com/api/v2/polling/d4849121-d7d4-49f8-881f-b41601a7fe43',
'accessToken' => 'myRand0mAcc3ssT0k3n',
];
$response = $polling->getStatus($options);
echo $response
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
The request above results the following JSON payload when a Polling Result exists
{
"data": {
"id": "d4849121-d7d4-49f8-881f-b41601a7fe43",
"type": "polling",
"attributes": {
"status": "Success",
"created_at": "2021-04-28T11:25:53.497+03:00",
"from_time": "2021-04-12T08:50:22+03:00",
"to_time": "2021-04-19T08:50:22+03:00",
"transactions": [
{
"type": "Buygoods Transaction",
"resource": {
"id": "c4fbb520-9155-406e-aee8-661a07a49f86",
"amount": "500.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "APR202119",
"till_number": "000000",
"origination_time": "2021-04-19T08:19:00+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": "",
"sender_phone_number": "+254799999999"
}
},
{
"type": "Buygoods Transaction",
"resource": {
"id": "18f8da83-5d95-45f9-9670-1958a8fe1e30",
"amount": "500.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "APR202126",
"till_number": "K000000",
"origination_time": "2021-04-19T08:19:00+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": "",
"sender_phone_number": "+254799999999"
}
}
],
"scope": "Company",
"scope_reference": null,
"_links": {
"callback_url": "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e",
"self": "https://sandbox.kopokopo.com/api/v2/polling/d4849121-d7d4-49f8-881f-b41601a7fe43"
}
}
}
}
{
"data": {
"id": "d4849121-d7d4-49f8-881f-b41601a7fe43",
"type": "polling",
"attributes": {
"status": "Success",
"created_at": "2021-04-28T11:25:53.497+03:00",
"from_time": "2021-04-12T08:50:22+03:00",
"to_time": "2021-04-19T08:50:22+03:00",
"transactions": [
{
"type": "Buygoods Transaction",
"resource": {
"id": "c4fbb520-9155-406e-aee8-661a07a49f86",
"amount": "500.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "APR202119",
"till_number": "000000",
"origination_time": "2021-04-19T08:19:00+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": "",
"sender_phone_number": "+254799999999"
}
},
{
"type": "Buygoods Transaction",
"resource": {
"id": "18f8da83-5d95-45f9-9670-1958a8fe1e30",
"amount": "500.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "APR202126",
"till_number": "K000000",
"origination_time": "2021-04-19T08:19:00+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": "",
"sender_phone_number": "+254799999999"
}
}
],
"scope": "Company",
"scope_reference": null,
"_links": {
"callback_url": "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e",
"self": "https://sandbox.kopokopo.com/api/v2/polling/d4849121-d7d4-49f8-881f-b41601a7fe43"
}
}
}
}
{
"data": {
"id": "d4849121-d7d4-49f8-881f-b41601a7fe43",
"type": "polling",
"attributes": {
"status": "Success",
"created_at": "2021-04-28T11:25:53.497+03:00",
"from_time": "2021-04-12T08:50:22+03:00",
"to_time": "2021-04-19T08:50:22+03:00",
"transactions": [
{
"type": "Buygoods Transaction",
"resource": {
"id": "c4fbb520-9155-406e-aee8-661a07a49f86",
"amount": "500.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "APR202119",
"till_number": "000000",
"origination_time": "2021-04-19T08:19:00+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": "",
"sender_phone_number": "+254799999999"
}
},
{
"type": "Buygoods Transaction",
"resource": {
"id": "18f8da83-5d95-45f9-9670-1958a8fe1e30",
"amount": "500.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "APR202126",
"till_number": "K000000",
"origination_time": "2021-04-19T08:19:00+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": "",
"sender_phone_number": "+254799999999"
}
}
],
"scope": "Company",
"scope_reference": null,
"_links": {
"callback_url": "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e",
"self": "https://sandbox.kopokopo.com/api/v2/polling/d4849121-d7d4-49f8-881f-b41601a7fe43"
}
}
}
}
{
"data": {
"id": "d4849121-d7d4-49f8-881f-b41601a7fe43",
"type": "polling",
"attributes": {
"status": "Success",
"created_at": "2021-04-28T11:25:53.497+03:00",
"from_time": "2021-04-12T08:50:22+03:00",
"to_time": "2021-04-19T08:50:22+03:00",
"transactions": [
{
"type": "Buygoods Transaction",
"resource": {
"id": "c4fbb520-9155-406e-aee8-661a07a49f86",
"amount": "500.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "APR202119",
"till_number": "000000",
"origination_time": "2021-04-19T08:19:00+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": "",
"sender_phone_number": "+254799999999"
}
},
{
"type": "Buygoods Transaction",
"resource": {
"id": "18f8da83-5d95-45f9-9670-1958a8fe1e30",
"amount": "500.0",
"status": "Received",
"system": "Lipa Na M-PESA",
"currency": "KES",
"reference": "APR202126",
"till_number": "K000000",
"origination_time": "2021-04-19T08:19:00+03:00",
"sender_last_name": "Doe",
"sender_first_name": "Jane",
"sender_middle_name": "",
"sender_phone_number": "+254799999999"
}
}
],
"scope": "Company",
"scope_reference": null,
"_links": {
"callback_url": "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e",
"self": "https://sandbox.kopokopo.com/api/v2/polling/d4849121-d7d4-49f8-881f-b41601a7fe43"
}
}
}
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"id" => "d4849121-d7d4-49f8-881f-b41601a7fe43",
"type" => "polling",
"status" => "Success",
"createdAt" => "2021-04-28T11:25:53.497+03:00",
"fromTime" => "2021-04-12T08:50:22+03:00",
"toTime" => "2021-04-19T08:50:22+03:00",
"scope" => "Company",
"scopeReference" => null,
"transactions" => [
[
"type" => "Buygoods Transaction",
"resource" => [
"id" => "c4fbb520-9155-406e-aee8-661a07a49f86",
"amount" => "500.0",
"status" => "Received",
"system" => "Lipa Na M-PESA",
"currency" => "KES",
"reference" => "APR202119",
"till_number" => "000000",
"origination_time" => "2021-04-19T08:19:00+03:00",
"sender_last_name" => "Doe",
"sender_first_name" => "Jane",
"sender_middle_name" => "",
"sender_phone_number" => "+254799999999"
]
],
[
"type" => "Buygoods Transaction",
"resource" => [
"id" => "18f8da83-5d95-45f9-9670-1958a8fe1e30",
"amount" => "500.0",
"status" => "Received",
"system" => "Lipa Na M-PESA",
"currency" => "KES",
"reference" => "APR202126",
"till_number" => "K000000",
"origination_time" => "2021-04-19T08:19:00+03:00",
"sender_last_name" => "Doe",
"sender_first_name" => "Jane",
"sender_middle_name" => "",
"sender_phone_number" => "+254799999999"
]
]
],
"linkSelf" => "https://sandbox.kopokopo.com/api/v2/polling/d4849121-d7d4-49f8-881f-b41601a7fe43",
"callbackUrl" => "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e",
]
]
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
With an Polling location url, you can query what the status of the Polling API is. If a corresponding Polling Result
exists, it will be bundled in the payload of the result.
HTTP Request
GET https://sandbox.kopokopo.com/api/v2/polling/ Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
Query Parameters
| Parameter | Required | Type | Description |
|---|---|---|---|
| ID | Yes | String | The reference / ID of the Polling to retrieve |
HTTP Response
Transactions JSON(Could be multiple)
| Parameter | Type | Description |
|---|---|---|
| type | String | The type of transaction (Buygoods Transaction) |
| resource | JSON | The resource corresponding to the event. In this case this is a Buygoods Transaction |
Resource (Buygoods Transaction) JSON
| Parameter | Type | Description |
|---|---|---|
| id | String | The api reference of the transaction |
| reference | String | The mpesa reference |
| status | String | The status of the transaction |
| origination_time | String | The transaction timestamp |
| sender_phone_number | String | The phone number that sent the payment |
| amount | Float | The amount of the transaction |
| currency | String | Currency |
| till_number | String | The till number to which the payment was made |
| system | String | The mobile money system |
| sender_first_name | String | First name of payer |
| sender_middle_name | String | Middle name of payer |
| sender_last_name | String | Last name of payer |
Transaction SMS Notifications
Transaction SMS Notifications API Requests (Deprecated)
Send sms notifications to your customer after you have received a payment from them.
POST https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications Content-Type: application/json Accept: application/json Authorization: Bearer < AccessToken > User-Agent: "< product >/< product-version > < comment >"
{
"webhook_event_reference": "e51438e9-c42b-4bf2-a261-faeaf189e3ed",
"message": "Your message here",
"_links": {
"callback_url": "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e"
}
}
# Using K2Connect - https://github.com/kopokopo/k2-connect-ruby (Recommended)
your_input =
{
webhook_event_reference: "e51438e9-c42b-4bf2-a261-faeaf189e3ed",
message: "Your message here",
callback_url: 'https://call_back_to_your_app.your_application.com'
}
k2_notification = k2Notification.new("your_access_token")
k2_notification.transaction_sms_notifications(your_input)
k2_notification.location_url # => "https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/247b1bd8-f5a0-4b71-a898-f62f67b8ae1c"
request_body =
{
"access_token": ACCESS_TOKEN,
"callback_url": "https://webhook.site/52fd1913-778e-4ee1-bdc4-74517abb758d",
"webhook_event_reference": "e51438e9-c42b-4bf2-a261-faeaf189e3ed",
"message": "Your message here"
}
# Using K2Connect - https://github.com/kopokopo/k2-connect-python (Recommended)
k2connect.initialize(environ.get('CLIENT_ID'), environ.get('CLIENT_SECRET'), 'http://127.0.0.1:3000/')
notification_service = k2connect.SmsNotificationService
notification_location = notification_service.transaction_sms_notifications(request_body)
notification_location # => 'https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/247b1bd8-f5a0-4b71-a898-f62f67b8ae1c'
const SmsNotificationService = K2.SmsNotificationService
var notificationOptions = {
webhookEventReference: 'e51438e9-c42b-4bf2-a261-faeaf189e3ed',
message: 'Your message here',
callbackUrl: 'https://callback_to_your_app.your_application.com/endpoint',
accessToken: 'myRand0mAcc3ssT0k3n'
}
SmsNotificationService
.sendTransactionSmsNotification(notificationOptions)
.then( response => {
console.log(response)
// => 'https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/247b1bd8-f5a0-4b71-a898-f62f67b8ae1c'
})
.catch( error => {
console.log(error)
})
<?
$sms_notifications = $K2->SmsNotificationService();
$response = $sms_notifications->sendTransactionSmsNotification([
'webhookEventReference' => 'e51438e9-c42b-4bf2-a261-faeaf189e3ed',,
'message' => 'Your message here',
'callbackUrl' => 'https://callback_to_your_app.your_application.com/endpoint',
'accessToken' => 'myRand0mAcc3ssT0k3n',
]);
if($response['status'] == 'success')
{
echo "The resource location is:" . json_encode($response['location']);
// => 'https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/247b1bd8-f5a0-4b71-a898-f62f67b8ae1c'
}
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
HTTP Request
POST https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
Request Parameters (JSON)
| Parameter | Required | Type | Description |
|---|---|---|---|
| webhook_event_reference | yes | String | This is the id of the webhook payload you got |
| message | Yes | String | A string containing the message you want to send to the customer |
| _links | Yes | JSON | A JSON object containing the callback_url where the result of the Transaction Notification will be posted |
HTTP Response
Successful Response
Upon a successful request a HTTP Status 201 will be returned and the location HTTP Header will contain the URL of the newly created Transaction Notification API Request
HTTP/1.1 201 Created
Location: https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/247b1bd8-f5a0-4b71-a898-f62f67b8ae1c
Error Response
This will have a HTTP Status code indicating the error and it might have a json that contains the error code and an error message specifying the error that occured. Please note that the error response might not be present depending on the type of error that occured.
If the error json response is present, it will look as follows:
HTTP/1.1 400 Bad Request
{ "error_code": 400, "error_message": "Message can't be blank" }
Process Transaction Notification API Result
POST https://your-callback-url.com/api/v1/transaction_notification_result Content-Type: application/json X-KopoKopo-Signature: 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
{
"data": {
"id": "a48ad0a7-b43b-48c5-9ff8-509552d603af",
"type": "transaction_sms_notification",
"attributes": {
"status": "Success",
"message": "Your message here",
"webhook_event_reference": "4b46f88a-31f6-4af2-8795-b11ef1f3b846",
"_links": {
"callback_url": "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e",
"self": "https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/a48ad0a7-b43b-48c5-9ff8-509552d603af"
}
}
}
}
transaction_sms_notifications = K2Client.new("API_KEY")
transaction_sms_notifications.parse_request(request)
transaction_notification_object = K2ProcessResult.process(transaction_sms_notifications.hash_body, API_KEY, transaction_sms_notifications.k2_signature)
# Processed transaction_sms_notifications result in json format
{
"data": {
"id": "a48ad0a7-b43b-48c5-9ff8-509552d603af",
"type": "transaction_sms_notification",
"attributes": {
"status": "Success",
"message": "Your message here",
"webhook_event_reference": "4b46f88a-31f6-4af2-8795-b11ef1f3b846",
"_links": {
"callback_url": "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e",
"self": "https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/a48ad0a7-b43b-48c5-9ff8-509552d603af"
}
}
}
}
k2connect.initialize(CLIENT_ID, CLIENT_SECRET, BASE_URL)
result_handler = k2connect.ResultHandler
processed_payload = result_handler.process(request)
decomposed_result = payload_decomposer.decompose(processed_payload)
# Processed transaction_sms_notifications result in json format
{
"data": {
"id": "a48ad0a7-b43b-48c5-9ff8-509552d603af",
"type": "transaction_sms_notification",
"attributes": {
"status": "Success",
"message": "Your message here",
"webhook_event_reference": "4b46f88a-31f6-4af2-8795-b11ef1f3b846",
"_links": {
"callback_url": "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e",
"self": "https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/a48ad0a7-b43b-48c5-9ff8-509552d603af"
}
}
}
}
{
"data": {
"id": "a48ad0a7-b43b-48c5-9ff8-509552d603af",
"type": "transaction_sms_notification",
"attributes": {
"status": "Success",
"message": "Your message here",
"webhook_event_reference": "4b46f88a-31f6-4af2-8795-b11ef1f3b846",
"_links": {
"callback_url": "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e",
"self": "https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/a48ad0a7-b43b-48c5-9ff8-509552d603af"
}
}
}
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"id" => "a48ad0a7-b43b-48c5-9ff8-509552d603af",
"type" => "transaction_sms_notification",
"status" => "Success",
"message" =>"Your message here",
"webhookEventReference" => "4b46f88a-31f6-4af2-8795-b11ef1f3b846",
"linkSelf" => "https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/a48ad0a7-b43b-48c5-9ff8-509552d603af",
"callbackUrl" => "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e",
]
]
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
After the transaction notification is sent, a Transaction Notification Result will be posted asynchronously to the call back URL specified in the Transaction Notification request.
Transaction Notification Result Parameters (JSON)
Parameters contained in a transaction notification result;
| Parameter | Required | Type | Description |
|---|---|---|---|
| id | Yes | String | The ID of the Transaction Notification API Request |
| type | Yes | String | The topic of the request. transaction_sms_notifications in this instance. |
| status | Yes | String | A status string denoting the status of the Transaction Notification Request |
| message | Yes | String | A string containing the message you sent |
| webhook_event_reference | No | String | An JSON object containing the transactions from the query with the specified parameters |
| _links | Yes | JSON | A JSON object containing links to the Transaction Notification API request |
Query Transaction Notification API Status
GET https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/d79995cd-0111-e511-80da-0aa34a9b2388 Accept: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q Content-Type: application/json User-Agent: < product >/< product-version > < comment >
notification_url = 'https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/a48ad0a7-b43b-48c5-9ff8-509552d603af'
# Using K2 Connect - https://github.com/kopokopo/k2-connect-ruby (Recommended)
k2_notification = k2Notification.new("your_access_token")
k2_notification.transaction_sms_notifications(your_input)
# Query specific resource
k2_notification.query_resource(notification_url) or k2_notification.query_resource(k2_notification.location_url)
# Query recent transaction
k2_notification.query_status
notificationUrl = 'https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/a48ad0a7-b43b-48c5-9ff8-509552d603af'
# Using K2 Connect - https://github.com/kopokopo/k2-connect-python (Recommended)
k2connect.initialize(environ.get('CLIENT_ID'), environ.get('CLIENT_SECRET'), 'http://127.0.0.1:3000/')
notification_service = k2connect.SmsNotificationService
notification_location = notification_service.notification_status(access_token, notificationUrl)
var SmsNotificationService = K2.SmsNotificationService
var notificationUrl = 'https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/a48ad0a7-b43b-48c5-9ff8-509552d603af'
SmsNotificationService
.getStatus({accessToken: 'myRand0mAcc3ssT0k3n', location: notificationUrl})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
<?
$sms_notifications = $K2->SmsNotificationService();
$options = [
'location' => 'https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/a48ad0a7-b43b-48c5-9ff8-509552d603af',
'accessToken' => 'myRand0mAcc3ssT0k3n',
];
$response = $transaction_sms_notifications->getStatus($options);
echo $response
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
The request above results the following JSON payload when a Transaction Notification Result exists
{
"data": {
"id": "a48ad0a7-b43b-48c5-9ff8-509552d603af",
"type": "transaction_sms_notification",
"attributes": {
"status": "Success",
"message": "Your message here",
"webhook_event_reference": "4b46f88a-31f6-4af2-8795-b11ef1f3b846",
"_links": {
"callback_url": "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e",
"self": "https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/a48ad0a7-b43b-48c5-9ff8-509552d603af"
}
}
}
}
{
"data": {
"id": "a48ad0a7-b43b-48c5-9ff8-509552d603af",
"type": "transaction_sms_notification",
"attributes": {
"status": "Success",
"message": "Your message here",
"webhook_event_reference": "4b46f88a-31f6-4af2-8795-b11ef1f3b846",
"_links": {
"callback_url": "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e",
"self": "https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/a48ad0a7-b43b-48c5-9ff8-509552d603af"
}
}
}
}
{
{
"data": {
"id": "a48ad0a7-b43b-48c5-9ff8-509552d603af",
"type": "transaction_sms_notification",
"attributes": {
"status": "Success",
"message": "Your message here",
"webhook_event_reference": "4b46f88a-31f6-4af2-8795-b11ef1f3b846",
"_links": {
"callback_url": "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e",
"self": "https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/a48ad0a7-b43b-48c5-9ff8-509552d603af"
}
}
}
}
{
"data": {
"id": "a48ad0a7-b43b-48c5-9ff8-509552d603af",
"type": "transaction_sms_notification",
"attributes": {
"status": "Success",
"message": "Your message here",
"webhook_event_reference": "4b46f88a-31f6-4af2-8795-b11ef1f3b846",
"_links": {
"callback_url": "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e",
"self": "https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/a48ad0a7-b43b-48c5-9ff8-509552d603af"
}
}
}
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"id" => "a48ad0a7-b43b-48c5-9ff8-509552d603af",
"type" => "transaction_sms_notification",
"status" => "Success",
"message" =>"Your message here",
"webhookEventReference" => "4b46f88a-31f6-4af2-8795-b11ef1f3b846",
"linkSelf" => "https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/a48ad0a7-b43b-48c5-9ff8-509552d603af",
"callbackUrl" => "https://webhook.site/a67f60b8-8c26-40a2-866c-99f5314a3e0e",
]
]
// Not Supported
// This feature is not currently available in the Flutter SDK.
// Please use one of the other SDKs (PHP, Ruby, Python, NodeJs) or the REST API.
With an Transaction Sms Notification location url, you can query what the status of the Transaction Notification is. If a corresponding Transaction Sms Notification Result
exists, it will be bundled in the payload of the result.
HTTP Request
GET https://sandbox.kopokopo.com/api/v1/transaction_sms_notifications/ Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
Query Parameters
| Parameter | Required | Type | Description |
|---|---|---|---|
| ID | Yes | String | The reference / ID of the Transaction Sms Notification to retrieve |
Reversals
Reverse Incoming Transactions
Initiate reversals for Incoming Transactions made within the last 30 days.
POST https://sandbox.kopokopo.com/api/api/v2/reversals Content-Type: application/json Accept: application/json Authorization: Bearer
User-Agent: " / "
{
"transaction_reference": "5d894b0f-b07e-4304-ab4a-d54b80bc7286",
"reason": "Testing Reversals",
"metadata": {
"name": "Test"
},
"_links": {
"callback_url": "https://callback_to_your_app.your_application.com"
}
}
reversal_params = {
transaction_reference: "Y7T2990R11",
reason: "Erroneous payment",
metadata: {
order_no: "ORD192832",
},
callback_url: "https://example.com/callback",
}
access_token = K2ConnectRuby::K2Entity::K2Token.new("client_id", "client_secret").request_token
k2_reversal = K2ConnectRuby::K2Entity::Reversal.new(access_token)
k2_reversal.initiate_reversal(reversal_params)
# initialize service
reversal_service = k2connect.Reversals(access_token=access_token)
# initiating a reversal request
request_payload = {
"transaction_reference": "CX83943KH",
"reason": "Wrong payment",
"callback_url": "https://webhook.site/52fd1913-778e-4ee1-bdc4-74517abb758d",
}
reversal_resource_location_url = reversal_service.initiate_reversal(request_payload)
# https://sandbox.kopokopo.com/api/v2/reversals/247b1bd8-f5a0-4b71-a898-f62f67b8ae1c
const ReversalService = K2.ReversalService
const reversalOpts = {
transactionReference: "transaction_reference",
reason: "reason",
callbackUrl: "https://8650bfeddc80.ngrok.io/reversals/result",
metadata: {
notes: "Sample Reversal transaction",
customId: "custom123"
},
accessToken: "access_token",
};
ReversalService
.initiateReversal(reversalOpts)
.then(response => {
console.log(response) // => 'https://sandbox.kopokopo.com/api/v2/reversals/cc438b3e-ecf0-4600-b9cc-edba32ae7019'
})
.catch(error => {
console.log(error)
})
// Using KopoKopoConnect - https://github.com/kopokopo/k2-connect-php (Recommended)
$reversalService = $K2->ReversalService();
$options = [
"transactionReference" => "transactionReference",
"reason" => "reason",
"callbackUrl" => "callbackUrl",
"accessToken" => $accessToken,
];
$response = $reversalService->initiateReversal($options);
if($response['status'] == 'success')
{
echo "The resource location is:" . json_encode($response['location']);
// => 'https://sandbox.kopokopo.com/api/v2/reversals/cc438b3e-ecf0-4600-b9cc-edba32ae7019'
}
HTTP Request
POST https://sandbox.kopokopo.com/api/api/v2/reversals
Request Parameters (JSON)
| Parameter | Required | Type | Description |
|---|---|---|---|
| transaction_reference | yes | String | The reference of the transaction to be reversed. |
| reason | yes | String | The reason for initiating the reversal. |
| metadata | No | String | A JSON object containing additional information. |
| _links | Yes | JSON | A JSON object containing the callback_url where the reversal result will be posted. |
HTTP Response
Successful Response
Upon a successful request a HTTP Status 201 will be returned and the location HTTP Header will contain the URL of the newly created Reversal Request.
HTTP/1.1 201 Created
Location: https://sandbox.kopokopo.com/api/v2/reversals/247b1bd8-f5a0-4b71-a898-f62f67b8ae1c
Error Response
This will have a HTTP Status code indicating the error and it might have a json that contains the error code and an error message specifying the error that occurred. Please note that the error response might not be present depending on the type of error that occurred.
If the error json response is present, it will look as follows:
HTTP/1.1 400 Bad Request
{
"error_code": 400,
"error_message": [
"You cannot reverse a transaction in Pending Reversal"
]
}
Process Reversal Request API Result
POST https://your-callback-url.com/api/v2/reversal_results Content-Type: application/json X-KopoKopo-Signature: 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
{
"data": {
"id": "67b1bb87-b89b-4366-93c9-a2bb6944ec99",
"type": "reversals",
"attributes": {
"status": "Processed",
"created_at": "2025-10-31T16:32:54.952+03:00",
"transaction_reference": "059278a2-8ffe-4f31-b3b4-d6c76770c72f",
"reason": "Testing Reversals",
"reversal_bulk_payment": {
"amount": "400.0",
"status": "Transferred",
"origination_time": "2025-10-31T12:55:18.000+03:00",
"transaction_reference": "ce430292-899b-4543-beb8-4195875dc063"
},
"errors":null,
"metadata": {
"name": "Test"
},
"_links": {
"callback_url": "https://your_callback_url.com/",
"self": "https://sandbox.kopokopo.com/api/v2/reversals/67b1bb87-b89b-4366-93c9-a2bb6944ec99"
}
}
}
}
{
"data": {
"id": "67b1bb87-b89b-4366-93c9-a2bb6944ec99",
"type": "reversals",
"attributes": {
"status": "Processed",
"created_at": "2025-10-31T16:32:54.952+03:00",
"transaction_reference": "059278a2-8ffe-4f31-b3b4-d6c76770c72f",
"reason": "Testing Reversals",
"reversal_bulk_payment": {
"amount": "400.0",
"status": "Transferred",
"origination_time": "2025-10-31T12:55:18.000+03:00",
"transaction_reference": "ce430292-899b-4543-beb8-4195875dc063"
},
"errors": nil,
"metadata": {
"name": "Test"
},
"_links": {
"callback_url": "https://your_callback_url.com/",
"self": "https://sandbox.kopokopo.com/api/v2/reversals/67b1bb87-b89b-4366-93c9-a2bb6944ec99"
}
}
}
}
{
"data": {
"id": "67b1bb87-b89b-4366-93c9-a2bb6944ec99",
"type": "reversals",
"attributes": {
"status": "Processed",
"created_at": "2025-10-31T16:32:54.952+03:00",
"transaction_reference": "059278a2-8ffe-4f31-b3b4-d6c76770c72f",
"reason": "Testing Reversals",
"reversal_bulk_payment": {
"amount": "400.0",
"status": "Transferred",
"origination_time": "2025-10-31T12:55:18.000+03:00",
"transaction_reference": "ce430292-899b-4543-beb8-4195875dc063"
},
"errors":null,
"metadata": {
"name": "Test"
},
"_links": {
"callback_url": "https://your_callback_url.com/",
"self": "https://sandbox.kopokopo.com/api/v2/reversals/67b1bb87-b89b-4366-93c9-a2bb6944ec99"
}
}
}
}
{
"data": {
"id": "67b1bb87-b89b-4366-93c9-a2bb6944ec99",
"type": "reversals",
"attributes": {
"status": "Processed",
"created_at": "2025-10-31T16:32:54.952+03:00",
"transaction_reference": "059278a2-8ffe-4f31-b3b4-d6c76770c72f",
"reason": "Testing Reversals",
"reversal_bulk_payment": {
"amount": "400.0",
"status": "Transferred",
"origination_time": "2025-10-31T12:55:18.000+03:00",
"transaction_reference": "ce430292-899b-4543-beb8-4195875dc063"
},
"errors":null,
"metadata": {
"name": "Test"
},
"_links": {
"callback_url": "https://your_callback_url.com/",
"self": "https://sandbox.kopokopo.com/api/v2/reversals/67b1bb87-b89b-4366-93c9-a2bb6944ec99"
}
}
}
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"data" => [
"id" => "67b1bb87-b89b-4366-93c9-a2bb6944ec99",
"type" => "reversals",
"attributes" => [
"status" => "Processed",
"created_at" => "2025-10-31T16:32:54.952+03:00",
"transaction_reference" => "059278a2-8ffe-4f31-b3b4-d6c76770c72f",
"reason" => "Testing Reversals",
"reversal_bulk_payment" => [
"amount" => "400.0",
"status" => "Transferred",
"origination_time" => "2025-10-31T12:55:18.000+03:00",
"transaction_reference" => "ce430292-899b-4543-beb8-4195875dc063"
],
"errors" => null,
"metadata" => [
"name" => "Test"
],
"_links" => [
"callback_url" => "https://your_callback_url.com/",
"self" => "https://sandbox.kopokopo.com/api/v2/reversals/67b1bb87-b89b-4366-93c9-a2bb6944ec99"
]
]
]
]
Unsuccessful Reversal
{
"data": {
"id": "c5486bd6-54c5-4d38-9e8a-e5a3597cd704",
"type": "reversals",
"attributes": {
"status": "Processed",
"created_at": "2025-11-24T13:11:13.255+03:00",
"transaction_reference": "8b275328-3b33-4144-9163-b2badbfb5de3",
"reason": "Testing Reversals",
"reversal_bulk_payment": {
"amount": "1300.0",
"status": "Cancelled",
"origination_time": "2025-11-24T13:01:18.000+03:00",
"transaction_reference":null
},
"errors": ["The balance is insufficient for the transaction"],
"metadata": {
"name": "Test"
},
"_links": {
"callback_url": "https://your_callback_url.com/",
"self": "https://sandbox.kopokopo.com/api/v2/reversals/c5486bd6-54c5-4d38-9e8a-e5a3597cd704"
}
}
}
}
{
"data": {
"id": "c5486bd6-54c5-4d38-9e8a-e5a3597cd704",
"type": "reversals",
"attributes": {
"status": "Processed",
"created_at": "2025-11-24T13:11:13.255+03:00",
"transaction_reference": "8b275328-3b33-4144-9163-b2badbfb5de3",
"reason": "Testing Reversals",
"reversal_bulk_payment": {
"amount": "1300.0",
"status": "Cancelled",
"origination_time": "2025-11-24T13:01:18.000+03:00",
"transaction_reference":nil
},
"errors": ["The balance is insufficient for the transaction"],
"metadata": {
"name": "Test"
},
"_links": {
"callback_url": "https://your_callback_url.com/",
"self": "https://sandbox.kopokopo.com/api/v2/reversals/c5486bd6-54c5-4d38-9e8a-e5a3597cd704"
}
}
}
}
{
"data": {
"id": "c5486bd6-54c5-4d38-9e8a-e5a3597cd704",
"type": "reversals",
"attributes": {
"status": "Processed",
"created_at": "2025-11-24T13:11:13.255+03:00",
"transaction_reference": "8b275328-3b33-4144-9163-b2badbfb5de3",
"reason": "Testing Reversals",
"reversal_bulk_payment": {
"amount": "1300.0",
"status": "Cancelled",
"origination_time": "2025-11-24T13:01:18.000+03:00",
"transaction_reference":null
},
"errors": ["The balance is insufficient for the transaction"],
"metadata": {
"name": "Test"
},
"_links": {
"callback_url": "https://your_callback_url.com/",
"self": "https://sandbox.kopokopo.com/api/v2/reversals/c5486bd6-54c5-4d38-9e8a-e5a3597cd704"
}
}
}
}
{
"data": {
"id": "c5486bd6-54c5-4d38-9e8a-e5a3597cd704",
"type": "reversals",
"attributes": {
"status": "Processed",
"created_at": "2025-11-24T13:11:13.255+03:00",
"transaction_reference": "8b275328-3b33-4144-9163-b2badbfb5de3",
"reason": "Testing Reversals",
"reversal_bulk_payment": {
"amount": "1300.0",
"status": "Cancelled",
"origination_time": "2025-11-24T13:01:18.000+03:00",
"transaction_reference":null
},
"errors": ["The balance is insufficient for the transaction"],
"metadata": {
"name": "Test"
},
"_links": {
"callback_url": "https://your_callback_url.com/",
"self": "https://sandbox.kopokopo.com/api/v2/reversals/c5486bd6-54c5-4d38-9e8a-e5a3597cd704"
}
}
}
}
[
"data" =>[
"id" =>"c5486bd6-54c5-4d38-9e8a-e5a3597cd704",
"type" =>"reversals",
"attributes" =>[
"status" =>"Processed",
"created_at" =>"2025-11-24T13:11:13.255+03:00",
"transaction_reference" =>"8b275328-3b33-4144-9163-b2badbfb5de3",
"reason" =>"Testing Reversals",
"reversal_bulk_payment" =>[
"amount" =>"1300.0",
"status" =>"Cancelled",
"origination_time" =>"2025-11-24T13:01:18.000+03:00",
"transaction_reference" =>null
],
"errors" => ["The balance is insufficient for the transaction"],
"metadata" =>[
"name" =>"Test"
],
"_links" =>[
"callback_url" =>"https://your_callback_url.com/",
"self" =>"https://sandbox.kopokopo.com/api/v2/reversals/c5486bd6-54c5-4d38-9e8a-e5a3597cd704"
]
]
]
]
After a Reversal Request is initiated, a Reversal API Result will be posted asynchronously to the call back URL specified in the Reversal Request.
Reversal Result Parameters (JSON)
Parameters contained in a successful Reversal result;
| Parameter | Required | Type | Description |
|---|---|---|---|
| id | Yes | String | The ID of the reversal request |
| type | Yes | String | The type of the request (reversals) |
| status | Yes | String | Status of the reversal request |
| created_at | Yes | Date | Date and time the reversal request was created |
| transaction_reference | Yes | String | Transaction reference being reversed |
| reason | Yes | String | Reason for reversal |
| metadata | Yes | JSON | Metadata sent with the reversal request |
| _links | Yes | JSON | Object containing links to the reversal request |
| reversal_bulk_payment | Yes | JSON | Object containing the reversal transaction |
| errors | Yes | JSON | Object containing errors if any |
Reversal Bulk Payment JSON
| Parameter | Required | Type | Description |
|---|---|---|---|
| amount | Yes | Float | The amount reversed |
| status | Yes | String | The status of the bulk payment(Transfered means reversed, Cancelled is failed) |
| origination_time | Yes | String | The transaction timestamp |
| transaction_reference | Yes | String | The M-PESA reference |
Query Reversal API Status
GET https://sandbox.kopokopo.com/api/v2/reversals/d79995cd-0111-e511-80da-0aa34a9b2388 Accept: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q Content-Type: application/json User-Agent: < product >/< product-version > < comment >
{
"data": {
"id": "3a5ed056-988d-4ea6-824b-67f523939b92",
"type": "reversals",
"attributes": {
"status": "Scheduled",
"created_at": "2025-10-22T14:53:55.930+03:00",
"transaction_reference": "20251016125940",
"reason": "Testing Reversals",
"errors": null,
"metadata": {
"name": "Test"
},
"_links": {
"callback_url": "https://your.callback.url.com/",
"self": "https://sandbox.kopokopo.com/api/v2/reversals/3a5ed056-988d-4ea6-824b-67f523939b92"
}
}
}
}
access_token = K2ConnectRuby::K2Entity::K2Token.new("client_id", "client_secret").request_token
k2_reversal = K2ConnectRuby::K2Entity::Reversal.new(access_token)
location_url = k2_reversal.initiate_reversal(reversal_params)
# Get status of current reversal request
k2_reversal.query_status
# Get status of specific reversal request
k2_reversal.query_resource(location_url)
# initialize service
reversal_service = k2connect.Reversals(access_token=access_token)
reversal_resource_location_url = reversal_service.initiate_reversal(request_payload)
# https://sandbox.kopokopo.com/api/v2/reversals/247b1bd8-f5a0-4b71-a898-f62f67b8ae1c
# get reversal status
request_body = {
"reversal-reference": "247b1bd8-f5a0-4b71-a898-f62f67b8ae1c"
}
reversal_resource = reversal_service.get_status(request_body)
const ReversalService = K2.ReversalService
const reversalOpts = {
location: 'https://sandbox.kopokopo.com/api/v2/reversals/cc438b3e-ecf0-4600-b9cc-edba32ae7019',
accessToken: 'myRand0mAcc3ssT0k3n'
}
ReversalService.getStatus(reversalOpts)
// Using KopoKopoConnect - https://github.com/kopokopo/k2-connect-php (Recommended)
$reversalService = $K2->ReversalService();
$statusOptions = [
'location' => 'cc438b3e-ecf0-4600-b9cc-edba32ae7019',
'accessToken' => 'myRand0mAcc3ssT0k3n'
]
$response = $reversalService->getStatus($statusOptions);
echo $response;
With an Reversal location url, you can query what the status of the Reversal is. If a corresponding Reversal Result
exists, it will be bundled in the payload of the result.
HTTP Request
GET https://sandbox.kopokopo.com/api/v2/reversals/ Accept: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
Query Parameters
| Parameter | Required | Type | Description |
|---|---|---|---|
| ID | Yes | String | The reference / ID of the Reversal to retrieve |
Payment Links
Payment links are a way to create a link that can be used to pay for a product or service via M-PESA.
Create a payment link
POST https://sandbox.kopokopo.com/api/v2/payment_links Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
{
"till_number": "till_number",
"currency": "KES",
"amount": 10,
"payment_reference": "order number or invoice number",
"note": "Notes",
"metadata": {
"something": "test",
"something_else": "Test data"
},
"_links": {
"callback_url": "https://webhook.site/e69b9144-530b-46ea-b3ed-ba110e189ca9"
}
}
your_input = {
till_number: 'till_number',
currency: 'KES',
amount: 10,
payment_reference: 'order number or invoice number',
note: 'Notes',
metadata: {},
callback_url: 'https://webhook.site/cc438b3e-ecf0-4600-b9cc-edba32ae7019'
}
# Using K2Connect - https://github.com/kopokopo/k2-connect-ruby (Recommended)
access_token = K2ConnectRuby.new('CLIENT_ID', 'CLIENT_SECRET').request_token
k2_payment_link = K2ConnectRuby::K2Entity::PaymentLink.new(access_token)
k2_payment_link.create_payment_link(your_input)
k2_payment_link.location_url # => "https://sandbox.kopokopo.com/api/v2/payment_links/cc438b3e-ecf0-4600-b9cc-edba32ae7019"
your_input = {
"till_number": "till_number",
"currency": "KES",
"amount": 10,
"payment_reference": "order number or invoice number",
"note": "Notes",
"metadata": {},
"callback_url": "https://webhook.site/cc438b3e-ecf0-4600-b9cc-edba32ae7019"
}
# Using K2Connect - https://github.com/kopokopo/k2-connect-python (Recommended)
payment_links_service = k2connect.PaymentLinks(access_token=access_token)
payment_link_location = payment_links_service.create_payment_link(your_input)
payment_link_location # => "https://sandbox.kopokopo.com/api/v2/payment_links/cc438b3e-ecf0-4600-b9cc-edba32ae7019"
const PaymentLinkService = K2.PaymentLinkService
const paymentLinkOptions = {
tillNumber: 'till_number',
currency: 'KES',
amount: 10,
paymentReference: 'order number or invoice number',
note: 'Notes',
metadata: {},
callbackUrl: 'https://webhook.site/cc438b3e-ecf0-4600-b9cc-edba32ae7019',
accessToken: 'myRand0mAcc3ssT0k3n'
}
PaymentLinkService
.createPaymentLink(paymentLinkOptions)
.then(response => {
console.log(response) // => 'https://sandbox.kopokopo.com/api/v2/payment_links/cc438b3e-ecf0-4600-b9cc-edba32ae7019'
})
.catch(error => {
console.log(error)
})
<?
// Using KopoKopoConnect - https://github.com/kopokopo/k2-connect-php (Recommended)
$paymentLink = $K2->PaymentLinkService();
$paymentLinkOptions = [
'tillNumber' => 'till_number',
'currency' => 'KES',
'amount' => 10,
'paymentReference' => 'order number or invoice number',
'note' => 'Notes',
'metadata' => [],
'callbackUrl' => 'https://webhook.site/cc438b3e-ecf0-4600-b9cc-edba32ae7019',
'accessToken' => 'myRand0mAcc3ssT0k3n'
];
$response = $paymentLink->createPaymentLink($paymentLinkOptions);
if($response['status'] == 'success')
{
echo "The resource location is:" . json_encode($response['location']);
// => 'https://sandbox.kopokopo.com/api/v2/payment_links/cc438b3e-ecf0-4600-b9cc-edba32ae7019'
}
HTTP Request
POST https://sandbox.kopokopo.com/api/v2/payment_links Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
Request Parameters (JSON)
| Parameter | Required | Type | Description |
|---|---|---|---|
| till_number | yes | string | The till number of the till you want to create the payment link for |
| currency | yes | string | The currency of the payment link |
| amount | yes | number | The amount of the payment link |
| payment_reference | no | string | Unique reference for tracking the payment such as order number or invoice number |
| note | no | string | The note of the payment link to be seen by the customer |
| metadata | no | json | The metadata of the payment link |
| _links | yes | json | Object containing callback URL to the payment link API request |
HTTP Response
Successful Response
Upon a successful request a HTTP Status 201 will be returned and the location HTTP Header will contain the URL of the newly created Payment Link.
HTTP/1.1 201 Created
Location: https://sandbox.kopokopo.com/api/v2/payment_links/cc438b3e-ecf0-4600-b9cc-edba32ae7019
Error Response
This will have a HTTP Status code indicating the error and it might have a json that contains the error code and an error message specifying the error that occured. Please note that the error response might not be present depending on the type of error that occured.
If the error json response is present, it will look as follows:
HTTP/1.1 400 Bad Request
{ "error_code": 400, "error_message": "Till number can't be blank" }
Payment link status
GET https://sandbox.kopokopo.com/api/v2/payment_links/cc438b3e-ecf0-4600-b9cc-edba32ae7019 Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
payment_link_reference = 'cc438b3e-ecf0-4600-b9cc-edba32ae7019'
# Using K2Connect - https://github.com/kopokopo/k2-connect-ruby (Recommended)
access_token = K2ConnectRuby.new('CLIENT_ID', 'CLIENT_SECRET').request_token
k2_payment_link = K2ConnectRuby::K2Entity::PaymentLink.new(access_token)
k2_payment_link.query_resource(payment_link_reference)
# Using K2Connect - https://github.com/kopokopo/k2-connect-python (Recommended)
your_input = {
"payment-link-reference": "cc438b3e-ecf0-4600-b9cc-edba32ae7019"
}
payment_links_service = k2connect.PaymentLinks(access_token=access_token)
payment_link_status = payment_links_service.fetch_payment_link(your_input)
// Using KopoKopoConnect - https://github.com/kopokopo/k2-connect-node (Recommended)
const PaymentLinkService = K2.PaymentLinkService
const paymentLinkOptions = {
location: 'https://sandbox.kopokopo.com/api/v2/payment_links/cc438b3e-ecf0-4600-b9cc-edba32ae7019',
accessToken: 'myRand0mAcc3ssT0k3n'
}
PaymentLinkService.getStatus(paymentLinkOptions)
<?
// Using KopoKopoConnect - https://github.com/kopokopo/k2-connect-php (Recommended)
$paymentLink = $K2->PaymentLinkService();
$statusOptions = [
'location' => 'cc438b3e-ecf0-4600-b9cc-edba32ae7019',
'accessToken' => 'myRand0mAcc3ssT0k3n'
]
$response = $paymentLink->getStatus($statusOptions);
echo $response;
The request above results in the following JSON payload
{
"data": {
"id": "bb611130-0219-472e-869a-7eb31c453f22",
"type": "payment_link",
"attributes": {
"status": "Processed",
"created_at": "2026-02-10T07:35:43.850+03:00",
"till_name": "DiJon Dinin'",
"till_number": "112233",
"payment_reference": "test",
"currency": "KES",
"amount": 200,
"note": "Notes",
"payment_link": {
"status": "Active",
"expires_at": "2026-02-17T07:35:43.989+03:00",
"link": "http://localhost:3000/links/ef407998-c69b-4a57-a944-74ffb2131da2"
},
"errors": null,
"metadata": {
"something": "test",
"something_else": "Test data"
},
"_links": {
"callback_url": "https://webhook.site/6009e351-fd56-4d82-8d37-bd1da68eb8bc",
"self": "https://sandbox.kopokopo.com/api/v2/payment_links/bb611130-0219-472e-869a-7eb31c453f22"
}
}
}
}
{
"data": {
"id": "bb611130-0219-472e-869a-7eb31c453f22",
"type": "payment_link",
"attributes": {
"status": "Processed",
"created_at": "2026-02-10T07:35:43.850+03:00",
"till_name": "DiJon Dinin'",
"till_number": "112233",
"payment_reference": "test",
"currency": "KES",
"amount": 200,
"note": "Notes",
"payment_link": {
"status": "Active",
"expires_at": "2026-02-17T07:35:43.989+03:00",
"link": "http://localhost:3000/links/ef407998-c69b-4a57-a944-74ffb2131da2"
},
"errors": null,
"metadata": {
"something": "test",
"something_else": "Test data"
},
"_links": {
"callback_url": "https://webhook.site/6009e351-fd56-4d82-8d37-bd1da68eb8bc",
"self": "https://sandbox.kopokopo.com/api/v2/payment_links/bb611130-0219-472e-869a-7eb31c453f22"
}
}
}
}
{
"data": {
"id": "bb611130-0219-472e-869a-7eb31c453f22",
"type": "payment_link",
"attributes": {
"status": "Processed",
"created_at": "2026-02-10T07:35:43.850+03:00",
"till_name": "DiJon Dinin'",
"till_number": "112233",
"payment_reference": "test",
"currency": "KES",
"amount": 200,
"note": "Notes",
"payment_link": {
"status": "Active",
"expires_at": "2026-02-17T07:35:43.989+03:00",
"link": "http://localhost:3000/links/ef407998-c69b-4a57-a944-74ffb2131da2"
},
"errors": null,
"metadata": {
"something": "test",
"something_else": "Test data"
},
"_links": {
"callback_url": "https://webhook.site/6009e351-fd56-4d82-8d37-bd1da68eb8bc",
"self": "https://sandbox.kopokopo.com/api/v2/payment_links/bb611130-0219-472e-869a-7eb31c453f22"
}
}
}
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"id" => "2eab4ca0-1724-4c90-a734-0fb5ffc4391c",
"type" => "payment_link",
"attributes" => [
"status" => "Processed",
"created_at" => "2026-02-10T07:35:43.850+03:00",
"till_name" => "DiJon Dinin'",
"till_number" => "112233",
"payment_reference" => "test",
"currency" => "KES",
"amount" => 200,
"note" => "Notes",
"payment_link" => [
"status" => "Active",
"expires_at" => "2026-02-17T07:35:43.989+03:00",
"link" => "http://localhost:3000/links/ef407998-c69b-4a57-a944-74ffb2131da2"
],
"errors" => null,
"metadata" => [
"something" => "test",
"something_else" => "Test data"
],
"_links" => [
"callback_url" => "https://webhook.site/6009e351-fd56-4d82-8d37-bd1da68eb8bc",
"self" => "https://sandbox.kopokopo.com/api/v2/payment_links/bb611130-0219-472e-869a-7eb31c453f22"
]
]
]
]
{
"data": {
"id": "bb611130-0219-472e-869a-7eb31c453f22",
"type": "payment_link",
"attributes": {
"status": "Processed",
"created_at": "2026-02-10T07:35:43.850+03:00",
"till_name": "DiJon Dinin'",
"till_number": "112233",
"payment_reference": "test",
"currency": "KES",
"amount": 200,
"note": "Notes",
"payment_link": {
"status": "Active",
"expires_at": "2026-02-17T07:35:43.989+03:00",
"link": "http://localhost:3000/links/ef407998-c69b-4a57-a944-74ffb2131da2"
},
"errors": null,
"metadata": {
"something": "test",
"something_else": "Test data"
},
"_links": {
"callback_url": "https://webhook.site/6009e351-fd56-4d82-8d37-bd1da68eb8bc",
"self": "https://sandbox.kopokopo.com/api/v2/payment_links/bb611130-0219-472e-869a-7eb31c453f22"
}
}
}
}
HTTP Request
GET https://sandbox.kopokopo.com/api/v2/payment_links/{payment_link_reference} Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
Request Parameters (JSON)
| Parameter | Required | Type | Description |
|---|---|---|---|
| payment_link_reference | yes | string | The reference of the payment link to view |
HTTP Response
Successful Response Result (JSON)
| Parameter | Type | Description |
|---|---|---|
| id | string | The ID of the payment link |
| type | string | The type of the payment link |
| attributes | object | The attributes of the payment link |
Attributes JSON
| Parameter | Type | Description |
|---|---|---|
| status | string | The status of the payment link |
| created_at | string | The date and time the payment link was created |
| till_name | string | The name of the till the payment link is for |
| till_number | string | The number of the till the payment link is for |
| payment_reference | string | The payment reference of the payment link |
| currency | string | The currency of the payment link |
| amount | number | The amount of the payment link |
| note | string | The note of the payment link |
| metadata | object | The metadata of the payment link |
| payment_link | object | The payment link object |
| errors | object | The errors of the payment link |
| _links | object | The links of the payment link |
Payment Link JSON
| Parameter | Type | Description |
|---|---|---|
| status | string | The status of the payment link |
| expires_at | string | The date and time the payment link will expire |
| link | string | The URL of the payment link |
Links JSON
| Parameter | Type | Description |
|---|---|---|
| callback_url | string | The URL of the callback url |
| self | string | The URL of the payment link |
{
"data": {
"id": "2eab4ca0-1724-4c90-a734-0fb5ffc4391c",
"type": "payment_link",
"attributes": {
"status": "Created",
"created_at": "2025-10-28T09:58:42.363+03:00",
"account_name": "UAT Testing",
"account_number": "K112233",
"initiator_name": "David Kariuki Mwangi",
"expires_at": "2025-11-04T09:58:42.429+03:00",
"payment_link": "http://localhost:3000/links/d60f5e34-8a36-49c3-8d56-fe0320538dbc",
"payment_link_status": "active",
"merchant_payment_reference": "test",
"currency": "KES",
"amount": 240001,
"note": "Notes",
"errors": null,
"_links": {
"self": "https://sandbox.kopokopo.com/api/v2/payment_links/2eab4ca0-1724-4c90-a734-0fb5ffc4391c"
}
}
}
}
Error Response
This will have a HTTP Status code indicating the error and it might have a json that contains the error code and an error message specifying the error that occured. Please note that the error response might not be present depending on the type of error that occured.
If the error json response is present, it will look as follows:
HTTP/1.1 404 Not Found
{ "error_code": 404, "error_message": "Payment link not found" }
Process Payment link API Result
After a Payment link request is initiated, a Payment link API result will be posted asynchronously to the callback URL specified in the initial request, once the payment link is paid, cancelled or expired.
POST https://your-callback-url.com/api/v2/payment_links Content-Type: application/json X-KopoKopo-Signature: 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
{
"data": {
"id": "55f74f06-5dea-4f1a-afba-e3decea28e03",
"type": "payment_link",
"attributes": {
"status": "Processed",
"created_at": "2026-04-27T00:58:43.389+03:00",
"till_name": "Till name",
"till_number": "till_number",
"payment_reference": "daud",
"currency": "KES",
"amount": 350,
"note": "Notes",
"payment_link": {
"status": "Paid",
"expires_at": "2026-05-04T00:58:43.424+03:00",
"link": "https://sandbox.kopokopo.com/links/d1a13e07-e92f-4c01-b49e-05294049793e",
"transaction_reference": "DAVSTK1777240982",
"sender_phone_number": "254996930902",
"origination_time": "2026-04-27T01:02:34.000+03:00"
},
"errors": null,
"metadata": {
"something": "test",
"something_else": "Test data"
},
"_links": {
"callback_url": "https://webhook.site/1e8e3abf-76c2-4149-9a72-6b4d97e39646",
"self": "https://sandbox.kopokopo.com/api/v2/payment_links/55f74f06-5dea-4f1a-afba-e3decea28e03"
}
}
}
}
{
"data": {
"id": "55f74f06-5dea-4f1a-afba-e3decea28e03",
"type": "payment_link",
"attributes": {
"status": "Processed",
"created_at": "2026-04-27T00:58:43.389+03:00",
"till_name": "Till name",
"till_number": "till_number",
"payment_reference": "daud",
"currency": "KES",
"amount": 350,
"note": "Notes",
"payment_link": {
"status": "Paid",
"expires_at": "2026-05-04T00:58:43.424+03:00",
"link": "https://sandbox.kopokopo.com/links/d1a13e07-e92f-4c01-b49e-05294049793e",
"transaction_reference": "DAVSTK1777240982",
"sender_phone_number": "254996930902",
"origination_time": "2026-04-27T01:02:34.000+03:00"
},
"errors": null,
"metadata": {
"something": "test",
"something_else": "Test data"
},
"_links": {
"callback_url": "https://webhook.site/1e8e3abf-76c2-4149-9a72-6b4d97e39646",
"self": "https://sandbox.kopokopo.com/api/v2/payment_links/55f74f06-5dea-4f1a-afba-e3decea28e03"
}
}
}
}
{
"data": {
"id": "55f74f06-5dea-4f1a-afba-e3decea28e03",
"type": "payment_link",
"attributes": {
"status": "Processed",
"created_at": "2026-04-27T00:58:43.389+03:00",
"till_name": "Till name",
"till_number": "till_number",
"payment_reference": "daud",
"currency": "KES",
"amount": 350,
"note": "Notes",
"payment_link": {
"status": "Paid",
"expires_at": "2026-05-04T00:58:43.424+03:00",
"link": "https://sandbox.kopokopo.com/links/d1a13e07-e92f-4c01-b49e-05294049793e",
"transaction_reference": "DAVSTK1777240982",
"sender_phone_number": "254996930902",
"origination_time": "2026-04-27T01:02:34.000+03:00"
},
"errors": null,
"metadata": {
"something": "test",
"something_else": "Test data"
},
"_links": {
"callback_url": "https://webhook.site/1e8e3abf-76c2-4149-9a72-6b4d97e39646",
"self": "https://sandbox.kopokopo.com/api/v2/payment_links/55f74f06-5dea-4f1a-afba-e3decea28e03"
}
}
}
}
{
"data": {
"id": "55f74f06-5dea-4f1a-afba-e3decea28e03",
"type": "payment_link",
"attributes": {
"status": "Processed",
"created_at": "2026-04-27T00:58:43.389+03:00",
"till_name": "Till name",
"till_number": "till_number",
"payment_reference": "daud",
"currency": "KES",
"amount": 350,
"note": "Notes",
"payment_link": {
"status": "Paid",
"expires_at": "2026-05-04T00:58:43.424+03:00",
"link": "https://sandbox.kopokopo.com/links/d1a13e07-e92f-4c01-b49e-05294049793e",
"transaction_reference": "DAVSTK1777240982",
"sender_phone_number": "254996930902",
"origination_time": "2026-04-27T01:02:34.000+03:00"
},
"errors": null,
"metadata": {
"something": "test",
"something_else": "Test data"
},
"_links": {
"callback_url": "https://webhook.site/1e8e3abf-76c2-4149-9a72-6b4d97e39646",
"self": "https://sandbox.kopokopo.com/api/v2/payment_links/55f74f06-5dea-4f1a-afba-e3decea28e03"
}
}
}
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"data" => [
"id" => "55f74f06-5dea-4f1a-afba-e3decea28e03",
"type" => "payment_link",
"attributes" => [
"status" => "Processed",
"created_at" => "2026-04-27T00:58:43.389+03:00",
"till_name" => "Till name",
"till_number" => "till_number",
"payment_reference" => "daud",
"currency" => "KES",
"amount" => 350,
"note" => "Notes",
"payment_link" => [
"status" => "Paid",
"expires_at" => "2026-05-04T00:58:43.424+03:00",
"link" => "https://sandbox.kopokopo.com/links/d1a13e07-e92f-4c01-b49e-05294049793e",
"transaction_reference" => "DAVSTK1777240982",
"sender_phone_number" => "254996930902",
"origination_time" => "2026-04-27T01:02:34.000+03:00"
],
"errors" => null,
"metadata" => [
"something" => "test",
"something_else" => "Test data"
],
"_links" => [
"callback_url" => "https://webhook.site/1e8e3abf-76c2-4149-9a72-6b4d97e39646",
"self" => "https://sandbox.kopokopo.com/api/v2/payment_links/55f74f06-5dea-4f1a-afba-e3decea28e03"
]
]
]
]
Unsuccessful Payment Link
{
"data": {
"id": "3e5fb59e-f236-4d58-9bce-12691a610c95",
"type": "payment_link",
"attributes": {
"status": "Processed",
"created_at": "2026-04-27T01:05:34.026+03:00",
"till_name": "Till name",
"till_number": "Till number",
"payment_reference": "daud",
"currency": "KES",
"amount": 350,
"note": "Notes",
"payment_link": {
"status": "Active",
"expires_at": "2026-05-04T01:05:34.037+03:00",
"link": "https://sandbox.kopokopo.com/links/157d9213-3ac4-4f63-85a3-ae19c08e81b3",
"transaction_reference": null,
"sender_phone_number": null,
"origination_time": null
},
"errors": ["The balance is insufficient for the transaction"],
"metadata": {
"something": "test",
"something_else": "Test data"
},
"_links": {
"callback_url": "https://webhook.site/1e8e3abf-76c2-4149-9a72-6b4d97e39646",
"self": "https://sandbox.kopokopo.com/api/v2/payment_links/3e5fb59e-f236-4d58-9bce-12691a610c95"
}
}
}
}
{
"data": {
"id": "3e5fb59e-f236-4d58-9bce-12691a610c95",
"type": "payment_link",
"attributes": {
"status": "Processed",
"created_at": "2026-04-27T01:05:34.026+03:00",
"till_name": "Till name",
"till_number": "Till number",
"payment_reference": "daud",
"currency": "KES",
"amount": 350,
"note": "Notes",
"payment_link": {
"status": "Active",
"expires_at": "2026-05-04T01:05:34.037+03:00",
"link": "https://sandbox.kopokopo.com/links/157d9213-3ac4-4f63-85a3-ae19c08e81b3",
"transaction_reference": nil,
"sender_phone_number": nil,
"origination_time": nil
},
"errors": ["The balance is insufficient for the transaction"],
"metadata": {
"something": "test",
"something_else": "Test data"
},
"_links": {
"callback_url": "https://webhook.site/1e8e3abf-76c2-4149-9a72-6b4d97e39646",
"self": "https://sandbox.kopokopo.com/api/v2/payment_links/3e5fb59e-f236-4d58-9bce-12691a610c95"
}
}
}
}
{
"data": {
"id": "3e5fb59e-f236-4d58-9bce-12691a610c95",
"type": "payment_link",
"attributes": {
"status": "Processed",
"created_at": "2026-04-27T01:05:34.026+03:00",
"till_name": "Till name",
"till_number": "Till number",
"payment_reference": "daud",
"currency": "KES",
"amount": 350,
"note": "Notes",
"payment_link": {
"status": "Active",
"expires_at": "2026-05-04T01:05:34.037+03:00",
"link": "https://sandbox.kopokopo.com/links/157d9213-3ac4-4f63-85a3-ae19c08e81b3",
"transaction_reference": null,
"sender_phone_number": null,
"origination_time": null
},
"errors": ["The balance is insufficient for the transaction"],
"metadata": {
"something": "test",
"something_else": "Test data"
},
"_links": {
"callback_url": "https://webhook.site/1e8e3abf-76c2-4149-9a72-6b4d97e39646",
"self": "https://sandbox.kopokopo.com/api/v2/payment_links/3e5fb59e-f236-4d58-9bce-12691a610c95"
}
}
}
}
{
"data": {
"id": "3e5fb59e-f236-4d58-9bce-12691a610c95",
"type": "payment_link",
"attributes": {
"status": "Processed",
"created_at": "2026-04-27T01:05:34.026+03:00",
"till_name": "Till name",
"till_number": "Till number",
"payment_reference": "daud",
"currency": "KES",
"amount": 350,
"note": "Notes",
"payment_link": {
"status": "Active",
"expires_at": "2026-05-04T01:05:34.037+03:00",
"link": "https://sandbox.kopokopo.com/links/157d9213-3ac4-4f63-85a3-ae19c08e81b3",
"transaction_reference": null,
"sender_phone_number": null,
"origination_time": null
},
"errors": ["The balance is insufficient for the transaction"],
"metadata": {
"something": "test",
"something_else": "Test data"
},
"_links": {
"callback_url": "https://webhook.site/1e8e3abf-76c2-4149-9a72-6b4d97e39646",
"self": "https://sandbox.kopokopo.com/api/v2/payment_links/3e5fb59e-f236-4d58-9bce-12691a610c95"
}
}
}
}
[
"data" => [
"id" => "3e5fb59e-f236-4d58-9bce-12691a610c95",
"type" => "payment_link",
"attributes" => [
"status" => "Processed",
"created_at" => "2026-04-27T01:05:34.026+03:00",
"till_name" => "Till name",
"till_number" => "Till number",
"payment_reference" => "daud",
"currency" => "KES",
"amount" => 350,
"note" => "Notes",
"payment_link" => [
"status" => "Active",
"expires_at" => "2026-05-04T01:05:34.037+03:00",
"link" => "https://sandbox.kopokopo.com/links/157d9213-3ac4-4f63-85a3-ae19c08e81b3",
"transaction_reference" => null,
"sender_phone_number" => null,
"origination_time" => null
],
"errors" => ["The balance is insufficient for the transaction"],
"metadata" => [
"something" => "test",
"something_else" => "Test data"
],
"_links" => [
"callback_url" => "https://webhook.site/1e8e3abf-76c2-4149-9a72-6b4d97e39646",
"self" => "https://sandbox.kopokopo.com/api/v2/payment_links/3e5fb59e-f236-4d58-9bce-12691a610c95"
]
]
]
]
Payment link Result Parameters (JSON)
Parameters contained in a successful Payment link result;
| Parameter | Required | Type | Description |
|---|---|---|---|
| id | Yes | String | The ID of the payment_link request |
| type | Yes | String | The type of the API request (payment_link) |
| status | Yes | String | Status of the payment_link request |
| created_at | Yes | Date | Date and time the payment_link request was created |
| till_name | Yes | String | Till name where funds will be credited to |
| till_number | Yes | String | Till number where funds will be credited to |
| payment_reference | Yes | String | Payment reference that you provided |
| currency | Yes | String | Currency |
| amount | Yes | Float | The amount you provide for the payment_link request |
| note | Yes | String | Note sent with payment_link request |
| metadata | Yes | JSON | Metadata sent with the payment_link request |
| _links | Yes | JSON | Object containing links associated to the payment_link request |
| payment_link | Yes | JSON | Object containing the payment link details |
| errors | Yes | JSON | Object containing errors if any |
Payment link JSON
| Parameter | Required | Type | Description |
|---|---|---|---|
| status | Yes | String | The status of the payment link(Paid, Cancelled or Expired) |
| expires_at | Yes | Date | Date and time of when the payment link will expire |
| link | Yes | String | The URL that can be shared and used to make payment |
| transaction_reference | Yes | String | The reference for the transaction that paid the payment link |
| sender_phone_number | Yes | String | The phone number associated to the payment link |
| origination_time | Yes | Date | Date and time of when the transaction that paid the payment link occurred |
Cancel Payment Link
Cancel a payment link.
HTTP Request
POST https://sandbox.kopokopo.com/api/v2/payment_links/cc438b3e-ecf0-4600-b9cc-edba32ae7019/cancel Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
payment_link_reference = 'https://sandbox.kopokopo.com/api/v2/payment_links/cc438b3e-ecf0-4600-b9cc-edba32ae7019'
# Using K2Connect - https://github.com/kopokopo/k2-connect-ruby (Recommended)
access_token = K2ConnectRuby.new('CLIENT_ID', 'CLIENT_SECRET').request_token
k2_payment_link = K2ConnectRuby::K2Entity::PaymentLink.new(access_token)
k2_payment_link.cancel_payment_link(payment_link_reference)
payment_link_reference = 'cc438b3e-ecf0-4600-b9cc-edba32ae7019'
# Using K2Connect - https://github.com/kopokopo/k2-connect-python (Recommended)
payment_links_service = k2connect.PaymentLinks(access_token=access_token)
your_input = {
"payment-link-reference": "cc438b3e-ecf0-4600-b9cc-edba32ae7019"
}
payment_links_service.cancel_payment_link(your_input)
const PaymentLinkService = K2.PaymentLinkService
const paymentLinkCancelOptions = {
location: 'https://sandbox.kopokopo.com/api/v2/payment_links/cc438b3e-ecf0-4600-b9cc-edba32ae7019',
accessToken: 'myRand0mAcc3ssT0k3n'
}
PaymentLinkService.cancelPaymentLink(paymentLinkCancelOptions)
<?
// Using KopoKopoConnect - https://github.com/kopokopo/k2-connect-php (Recommended)
$paymentLink = $K2->PaymentLinkService();
$cancelOptions = [
'location' => 'https://sandbox.kopokopo.com/api/v2/payment_links/cc438b3e-ecf0-4600-b9cc-edba32ae7019',
'accessToken' => 'myRand0mAcc3ssT0k3n'
]
$response = $paymentLink->cancelPaymentLink($cancelOptions);
echo $response;
The request above results in the following JSON payload
{
"message": "Payment link cancelled."
}
{
"message": "Payment link cancelled."
}
{
"message": "Payment link cancelled."
}
{
"message": "Payment link cancelled."
}
<?
// The payload from the k2-connect-php SDK will look like this.
[
"status" => "success",
"data" => [
"message" => "Payment link cancelled."
]
]
To cancel a payment link, you need to send a POST request to the payment link cancel endpoint.
Request Parameters (JSON)
| Parameter | Required | Type | Description |
|---|---|---|---|
| payment_link_reference | yes | string | The reference of the payment link to cancel |
POST https://sandbox.kopokopo.com/api/v2/payment_links/cc438b3e-ecf0-4600-b9cc-edba32ae7019/cancel Accept: application/json Content-Type: application/json Authorization: Bearer 0Sn0W6kzNicvoWhDbQcVSKLRUpGjIdlPSEYyrHqrDDoRnQwE7Q User-Agent: < product >/< product-version > < comment >
HTTP Response
Successful Response
Upon a successful request a HTTP Status 200 will be returned and the response will contain the payment link details.
HTTP/1.1 200 OK
{ "message": "Payment link cancelled." }
Error Response
This will have a HTTP Status code indicating the error and it might have a json that contains the error code and an error message specifying the error that occured. Please note that the error response might not be present depending on the type of error that occured.
If the error json response is present, it will look as follows:
HTTP/1.1 400 Bad Request
{ "error_code": 400, "error_message": "Only active payment links can be cancelled." }
Errors
The Kopo Kopo API uses the following error codes:
| Error Code | Meaning |
|---|---|
| 400 | Bad Request -- Your request is invalid. |
| 401 | Unauthorized -- Your API key is wrong. |
| 403 | Forbidden -- The resource requested cannot be accessed. |
| 404 | Not Found -- The specified resource could not be found. |
| 405 | Method Not Allowed -- You tried to access a resource with an invalid method. |
| 406 | Not Acceptable -- You requested a format that isn't valid json. |
| 410 | Gone -- The resource requested has been moved. |
| 418 | I'm a teapot. |
| 429 | Too Many Requests -- Request threshold has been exceeded. |
| 500 | Internal Server Error -- We had a problem with our server. Try again later. |
| 503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |