Transactions
Log, commit, track and cancel transfers. See Transaction flow for the order of calls per channel.
Log a Mobile Transfer
Log a transfer to a mobile wallet. No money moves until you call
commitTransaction.
Run getMobileSubscriberDetails first and keep the
tracking_id from its callback.
Warning: Check result.status before you commit. 409 returns the existing
transaction_id (see Idempotency).
Request Body
KES. Payout currencyyyyymmddNational ID, Passport, Military ID.254712345678yyyymmddyyyymmddyyyymmdd"<currency>,<rate>,<original amount>", e.g. "USD,129.5,100"Request Body Example
{
"jsonrpc": "2.0",
"method": "transactions@logMobileTranscation",
"params": {
"request_id": "TXN-20261012-000184",
"tracking_id": "AG_20261012_2030166ee8992ece3dc4",
"callback_url": "https://partner.example.com/afrisend/payments",
"currency_code": "KES",
"send_amount": 12950,
"sender_first_name": "Joseph",
"sender_last_name": "Mwangi",
"sender_phone": "971501234567",
"sender_date_of_birth": "19850312",
"sender_nationality": "KE",
"sender_country_iso": "AE",
"sender_id_number": "784198512345678",
"sender_id_type": "Passport",
"sender_address": "Al Nahda, Dubai",
"recipient_first_name": "Wanjiru",
"recipient_last_name": "Kamau",
"recipient_msisdn": "254712345678",
"recipient_address": "Kiambu",
"foreign_currency": "USD,129.5,100",
"purpose": "Family support",
"source_of_funds": "Salary"
},
"id": "1"
}Check result.status before committing.
Response Fields
200 accepted, 409 duplicate, 422 outside limits, 400 or 404 commit refusedExample Response — Logged
{
"jsonrpc": "2.0",
"result": {
"transaction_id": "in8447D7EC98",
"status": 200,
"message": "transaction logged successfully"
},
"id": "1"
}Example Response — Duplicate request_id
{
"jsonrpc": "2.0",
"result": {
"transaction_id": "in8447D7EC98",
"status": 409,
"message": "A transaction with a similar request_id has already been recorded."
},
"id": "1"
}Example Response — Similar Transaction Within the Last Hour
{
"jsonrpc": "2.0",
"result": {
"transaction_id": "in8447D7EC98",
"status": 409,
"message": "A similar transaction was logged within the last hour. Please verify your transaction details before retrying."
},
"id": "1"
}Example Response — Validation Error
{
"jsonrpc": "2.0",
"error": {
"code": 400,
"message": "{\"sender_phone\":[\"The sender phone field is required.\"]}"
},
"id": "1"
}The bearer token is missing, invalid or expired. The response is plain JSON with HTTP
401, not a JSON-RPC envelope. Log in again and retry once.
Response Fields
401.Example Response
{
"status": 401,
"message": "Failed, Not authorized"
}Log a Bank Transfer
Log a transfer to a bank account. Get valid bank codes from
getAllBanks. Verify the account holder's name first with
getBankSubscriberDetails.
Warning: Check result.status before you commit. 409 returns the existing
transaction_id (see Idempotency).
Request Body
KES. Payout currencyyyyymmdd254712345678yyyymmddRequest Body Example
{
"jsonrpc": "2.0",
"method": "transactions@logBankTranscation",
"params": {
"request_id": "TXN-20261012-000185",
"callback_url": "https://partner.example.com/afrisend/payments",
"currency_code": "KES",
"send_amount": 85000,
"destination_bank_code": "40401000",
"destination_account": "1182736450",
"sender_first_name": "Grace",
"sender_last_name": "Achieng",
"sender_msisdn": "447700900123",
"sender_date_of_birth": "19900415",
"sender_nationality": "KE",
"sender_id_number": "A12345678",
"sender_id_type": "Passport",
"recipient_first_name": "Brian",
"recipient_last_name": "Odhiambo",
"recipient_msisdn": "254722334455",
"recipient_address": "Kisumu",
"purpose": "School fees",
"source_of_funds": "Salary"
},
"id": "1"
}Check result.status before committing.
Response Fields
200 accepted, 409 duplicate, 422 outside limits, 400 or 404 commit refusedExample Response — Logged
{
"jsonrpc": "2.0",
"result": {
"transaction_id": "in8447D7EC98",
"status": 200,
"message": "transaction logged successfully"
},
"id": "1"
}Example Response — Duplicate request_id
{
"jsonrpc": "2.0",
"result": {
"transaction_id": "in8447D7EC98",
"status": 409,
"message": "A transaction with a similar request_id has already been recorded."
},
"id": "1"
}Example Response — Similar Transaction Within the Last Hour
{
"jsonrpc": "2.0",
"result": {
"transaction_id": "in8447D7EC98",
"status": 409,
"message": "A similar transaction was logged within the last hour. Please verify your transaction details before retrying."
},
"id": "1"
}Example Response — Validation Error
{
"jsonrpc": "2.0",
"error": {
"code": 400,
"message": "{\"sender_phone\":[\"The sender phone field is required.\"]}"
},
"id": "1"
}The bearer token is missing, invalid or expired. The response is plain JSON with HTTP
401, not a JSON-RPC envelope. Log in again and retry once.
Response Fields
401.Example Response
{
"status": 401,
"message": "Failed, Not authorized"
}Log a Cash Pickup Transfer
Log a cash pickup transfer.
Warning: Check result.status before you commit. 409 returns the existing
transaction_id (see Idempotency).
Request Body
KES or USD. One of: KES, USD.yyyymmdd254712345678yyyymmddRequest Body Example
{
"jsonrpc": "2.0",
"method": "transactions@logCashTranscation",
"params": {
"request_id": "TXN-20261012-000186",
"callback_url": "https://partner.example.com/afrisend/payments",
"currency_code": "KES",
"send_amount": 20000,
"sender_first_name": "Peter",
"sender_last_name": "Kiprono",
"sender_msisdn": "12025550147",
"sender_date_of_birth": "19780921",
"sender_nationality": "KE",
"sender_id_number": "29384756",
"recipient_first_name": "Mercy",
"recipient_last_name": "Wambui",
"recipient_msisdn": "254733445566",
"recipient_address": "Nakuru"
},
"id": "1"
}Check result.status before committing.
Response Fields
200 accepted, 409 duplicate, 422 outside limits, 400 or 404 commit refusedExample Response — Logged
{
"jsonrpc": "2.0",
"result": {
"transaction_id": "in8447D7EC98",
"status": 200,
"message": "transaction logged successfully"
},
"id": "1"
}Example Response — Duplicate request_id
{
"jsonrpc": "2.0",
"result": {
"transaction_id": "in8447D7EC98",
"status": 409,
"message": "A transaction with a similar request_id has already been recorded."
},
"id": "1"
}Example Response — Similar Transaction Within the Last Hour
{
"jsonrpc": "2.0",
"result": {
"transaction_id": "in8447D7EC98",
"status": 409,
"message": "A similar transaction was logged within the last hour. Please verify your transaction details before retrying."
},
"id": "1"
}Example Response — Validation Error
{
"jsonrpc": "2.0",
"error": {
"code": 400,
"message": "{\"sender_phone\":[\"The sender phone field is required.\"]}"
},
"id": "1"
}The bearer token is missing, invalid or expired. The response is plain JSON with HTTP
401, not a JSON-RPC envelope. Log in again and retry once.
Response Fields
401.Example Response
{
"status": 401,
"message": "Failed, Not authorized"
}Commit Transaction
Confirm a LOGGED transaction and start the payout. Afrisend checks your balance at this
point. The final result arrives at the callback_url you gave when you logged the
transaction.
status | message | What to do |
|---|---|---|
| 400 | Partner balance and overdraw limit surpassed | Top up, then commit again |
| 400 | Top up partner balance | Top up, then commit again |
| 400 | Partner should request account creation | Contact Afrisend: no account exists in this currency |
| 404 | Partner not found / Partner balance not found | Contact Afrisend |
Request Body
{} if there are none.Request Body Example
{
"jsonrpc": "2.0",
"method": "transactions@commitTransaction",
"params": {
"transaction_id": "in8447D7EC98"
},
"id": "1"
}| Error code | Message |
|---|---|
| 404 | transaction not found |
| 409 | Transaction already committed (the transaction is not LOGGED) |
Response Fields
200 accepted, 409 duplicate, 422 outside limits, 400 or 404 commit refusedExample Response — Commit Accepted
{
"jsonrpc": "2.0",
"result": {
"transaction_id": "in8447D7EC98",
"status": 200,
"message": "Service request has been received"
},
"id": "1"
}Example Response — Insufficient Balance
{
"jsonrpc": "2.0",
"result": {
"transaction_id": "in8447D7EC98",
"status": 400,
"message": "Top up partner balance"
},
"id": "1"
}Example Response — Already Committed
{
"jsonrpc": "2.0",
"error": {
"code": 409,
"message": "Transaction already committed"
},
"id": "1"
}The bearer token is missing, invalid or expired. The response is plain JSON with HTTP
401, not a JSON-RPC envelope. Log in again and retry once.
Response Fields
401.Example Response
{
"status": 401,
"message": "Failed, Not authorized"
}Callback — Final Transaction Status
Sent as POST to your callback_url.
Callback Fields
Callback Example
{
"transaction_id": "in8447D7EC98",
"tracking_id": "AG_20261012_20106e210e4e0c5f1202",
"status": "success",
"status_message": "The service request is processed successfully."
}Check Transaction Status
Get the current status of a transaction. Use it when a callback is late or missing.
Request Body
{} if there are none.Request Body Example
{
"jsonrpc": "2.0",
"method": "transactions@checkTransactionStatus",
"params": {
"transaction_id": "in8447D7EC98"
},
"id": "1"
}| Error code | Message |
|---|---|
| 400 | transaction not found |
Response Fields
LOGGED, COMMITTED, INPROGRESS, PENDING, COLLECTED, FAILED, REVERSED, CANCELLED.Example Response
{
"jsonrpc": "2.0",
"result": {
"transaction_id": "in8447D7EC98",
"status": "COLLECTED",
"remark": "Transaction successfully processed"
},
"id": "1"
}The bearer token is missing, invalid or expired. The response is plain JSON with HTTP
401, not a JSON-RPC envelope. Log in again and retry once.
Response Fields
401.Example Response
{
"status": 401,
"message": "Failed, Not authorized"
}Get Transaction by Request ID
Find a transaction by your request_id. Use it to recover the transaction_id after a log
request times out.
Request Body
{} if there are none.request_id you sent when loggingRequest Body Example
{
"jsonrpc": "2.0",
"method": "transactions@getTransactionByRequestId",
"params": {
"request_id": "TXN-20261012-000184"
},
"id": "1"
}| Error code | Message |
|---|---|
| 404 | transaction not found (safe to log the transaction again with the same request_id) |
Response Fields
LOGGED, COMMITTED, INPROGRESS, PENDING, COLLECTED, FAILED, REVERSED, CANCELLED.Example Response
{
"jsonrpc": "2.0",
"result": {
"transaction_id": "in8447D7EC98",
"status": "LOGGED",
"tracking_id": "in8447D7EC98",
"remark": "Transaction logged"
},
"id": "1"
}The bearer token is missing, invalid or expired. The response is plain JSON with HTTP
401, not a JSON-RPC envelope. Log in again and retry once.
Response Fields
401.Example Response
{
"status": 401,
"message": "Failed, Not authorized"
}Cancel Transaction
Cancel a transaction that is logged but not committed. Only LOGGED transactions can be
cancelled. Otherwise the response returns the current status with the remark
cannot cancel transaction.
Request Body
{} if there are none.Request Body Example
{
"jsonrpc": "2.0",
"method": "transactions@cancelTransaction",
"params": {
"transaction_id": "in8447D7EC98"
},
"id": "1"
}| Error code | Message |
|---|---|
| 404 | transaction not found |
Response Fields
LOGGED, COMMITTED, INPROGRESS, PENDING, COLLECTED, FAILED, REVERSED, CANCELLED.Example Response — Cancelled
{
"jsonrpc": "2.0",
"result": {
"transaction_id": "in8447D7EC98",
"status": "CANCELLED",
"remark": "cancelled by partner"
},
"id": "1"
}Example Response — Not Cancellable (Already Committed)
{
"jsonrpc": "2.0",
"result": {
"transaction_id": "in8447D7EC98",
"status": "COMMITTED",
"remark": "cannot cancel transaction"
},
"id": "1"
}The bearer token is missing, invalid or expired. The response is plain JSON with HTTP
401, not a JSON-RPC envelope. Log in again and retry once.
Response Fields
401.Example Response
{
"status": 401,
"message": "Failed, Not authorized"
}