Pesalink - To Mobile Number
Test URL
Live URL
This web service enables an application to send money to mobile.
📘 PesaLink Participating Banks
To check whether your recipient's bank is participating on PesaLink, go to partners link (opens in a new tab) here.
200 Success Response Schema
| Field Name | Field Type | Field Description |
|---|---|---|
status | bool | Response status |
code | number | Response code |
message | string | Response message |
data | object | Response data |
transactionId | string | unique transaction id |
status | string | transaction status |
description | string | description |
Example Request
In the example below, please remember to replace the variables enclosed within curly brackets {{ }} with the actual values.
transfer.amount+transfer.currencyCode+transfer.reference+destination.name+source.accountNumberRequest Parameters
| Field Name | Data Type | Required | Description |
|---|---|---|---|
source.countryCode | string | Yes | Source account country code (e.g., KE for Kenya). |
source.name | string | Yes | Source account name. |
source.accountNumber | string | Yes | Source account number. |
destination.type | string | Yes | Type of destination (e.g., mobile). |
destination.countryCode | string | Yes | Destination account country code (e.g., KE for Kenya). |
destination.name | string | Yes | Name of the recipient. |
destination.bankCode | string | Yes | Bank code of the recipient's bank (e.g., 01 for a bank). |
destination.mobileNumber | string | Yes | Recipient's mobile number (e.g., 0722000000). |
transfer.type | string | Yes | Transfer type (e.g., PesaLink). |
transfer.amount | string | Yes | Transfer amount. |
transfer.currencyCode | string | Yes | Transfer currency code (e.g., KES for Kenyan Shillings). |
transfer.reference | string | Yes | Unique transaction reference number. |
transfer.date | string | Yes | Transaction date (e.g., 2019-05-01). |
transfer.description | string | Yes | Transaction description or remarks. |
curl -X POST \
-d '{
"source": {
"countryCode": "KE",
"name": "John Doe",
"accountNumber": "0011547896523"
},
"destination": {
"type": "mobile",
"countryCode": "KE",
"name": "Tom Doe",
"bankCode": "01",
"mobileNumber": "0722000000"
},
"transfer": {
"type": "PesaLink",
"amount": "40.00",
"currencyCode": "KES",
"reference": "692194625798",
"date": "2019-05-01",
"description": "Some remarks here"
}
}' \
-H 'Authorization: Bearer {access_token}' \
-H 'Content-Type: application/json' \
-H 'signature: e967CLKebZyLfa73/YYltjW5M4cHoyWeHi/5VDKJ64gOwKBvzHJRqJJrBBc34v2m4jyKkDMBtfRJeFlxbNisMAeBtkw0TRcD2LThFK27EOqLM3m8rQYa+7CJ2FhPhK+iOa4RUY+vTfkRX5JXuqOW7a3GHds8qyPaPe19cKUY33eAJL3upXnGnA3/PEhzjhb0pqk2zCI7aRzvjjVUGwUdT6LO73NVhDSWvGpLEsP0dH/stC5BoTPNNt9nY8yvGUPV7fmaPSIFn68W4L04WgePQdYkmD1UPApGcrl+L2ALY3lPaRfI6/N+0Y3NIWQyLgix+69k7V4EGolqejWdion+9A==' \
-L 'https://uat.finserve.africa/v3-apis/transaction-api/v3.0/remittance/pesalinkMobile'Example Response
{
"status": true,
"code": 0,
"message": "success",
"data": {
"description": "Confirmed. Ksh 100.0 sent to 254764000000- John Doe from your account 1464968850106 on Fri Jun 24 11:07:02 EAT 2022. Ref 041108128674. Thank you",
"transactionId": "041108128674",
"status": "SUCCESS"
}
}Error Responses
400 Bad Request
Missing or invalid parameters in the request body.
{
"status": false,
"code": 400,
"message": "Invalid request parameters",
"error_code": "INVALID_REQUEST"
}401 Unauthorized
Invalid or expired access token.
{
"status": false,
"code": 401,
"message": "Invalid or expired access token",
"error_code": "UNAUTHORIZED"
}403 Forbidden
Valid credentials but invalid signature or insufficient permissions.
{
"status": false,
"code": 403,
"message": "Invalid signature or insufficient permissions",
"error_code": "FORBIDDEN"
}404 Not Found
Account not found or invalid account number.
{
"status": false,
"code": 404,
"message": "Source or destination account not found",
"error_code": "ACCOUNT_NOT_FOUND"
}Transaction Status Errors
| Response Status | Response Code | Response Message |
|---|---|---|
| false | 111102 | Transaction with the passed reference cannot be found |
📖 Step-by-Step Guide
Step 1: 🔑 Set Up Security Keys
Generate your private and public key pair and share your public key with Finserve. See the Security & Signatures Documentation (opens in a new tab) for detailed instructions.
Step 2: 🎫 Authenticate
Obtain an access token using the authentication endpoint. See the Authentication API documentation (opens in a new tab) for details.
Step 3: 📋 Prepare Transaction Details
Gather all required information.
Step 4: ✍️ Generate Signature
Create the signature string by concatenating in this exact order:
transfer.amount+transfer.currencyCode+transfer.reference+destination.name+source.accountNumberSign this string using your private key, then Base64 encode the result.
Step 5: 📝 Set Up Headers
Include the following headers in your request:
Content-Type: application/jsonAuthorization: Bearer [your_access_token]Signature: [your_base64_encoded_signature]
Step 6: 🔧 Construct Request Body
Create a JSON object with all required fields following the structure shown in the example request.
Step 7: 🚀 Send POST Request
Make a POST request to the internal bank transfer endpoint with your headers and body.
🌍 Supported Countries & Currencies
| Country | Country Code | Common Currency Codes |
|---|---|---|
| Kenya | KE | KES |
| Uganda | UG | UGX |
| Tanzania | TZ | TZS |
| Rwanda | RW | RWF |
| South Sudan | SS | USD |
| DRC | DRC | USD |
Best Practices
-
** Security**
- Store your private key securely and never expose it in client-side code or version control
- Always use HTTPS for API requests
- Store access tokens securely
- Regenerate signatures for each request
-
** Signature Generation**
- Ensure exact string concatenation order:
transfer.amount+transfer.currencyCode+transfer.reference+destination.name+source.accountNumber - Do not include spaces, separators, or special characters in the concatenated string
- Always Base64 encode the signature before including it in headers
- Verify the values in the signature match exactly with the request body values
- Ensure exact string concatenation order:
-
** Transaction Reference**
- Use unique reference numbers for each transaction
- Implement a reference generation system to avoid duplicates
- Store reference numbers for reconciliation and audit purposes
- Never reuse reference numbers, even for failed transactions
-
Amount Formatting
- Always use decimal format with two decimal places (e.g., "500.00")
- Pass amounts as strings, not numbers
- Ensure the amount is positive and within allowed limits
- Verify amount matches exactly in signature and request body
-
Error Handling
- Implement retry logic with exponential backoff for transient errors
- Log transaction attempts and responses for audit purposes
- Handle signature validation errors by regenerating the signature
-
Testing
- Always test with the UAT endpoint before using the live endpoint
- Use test account numbers provided in the documentation
- Verify signature generation with sample data first
- Test error scenarios to ensure proper handling
-
Data Validation
- Validate all account numbers match the expected format
- Verify country codes are valid and supported
- Ensure transfer dates are in the correct format (YYYY-MM-DD)
- Validate currency codes match the destination country
Troubleshooting
Invalid Signature Error (403)
If you receive a 403 error with "Invalid signature":
- Verify the concatenation order:
transfer.amount+transfer.currencyCode+transfer.reference+destination.name+source.accountNumber - Ensure no spaces or separators are included in the concatenated string
- Check that the signature is Base64 encoded
- Verify your public key is correctly registered with us
- Ensure the values in the signature match exactly with the request body values
Common Signature Mistakes
- Using wrong concatenation order
- Adding spaces or separators between values
- Not Base64 encoding the final signature
- Values in signature don't match request body values
Support
For questions or issues with this API:
- Email: support@finserve.africa