PalmPesa Payment API
Production-grade REST API for mobile money, pay-by-link, and card operations across Tanzania. Built and maintained by Eagle Star Technology.
For the complete interactive reference visit the PalmPesa API Reference on Apidog ↗. This document is optimised for cURL integration workflows.
Getting Started
You need two credentials before making any API call:
-
1Create your account
Register at palmpesa.drmlelwa.co.tz and complete the developer registration form.
-
2Receive your credentials
Your
user_idandAPI Tokenare issued after account verification. Never expose them client-side. -
3Make your first test call
Start with a small amount (200–500 TZS) and verify the callback response before going live.
Never include your API token in client-side JavaScript, public repositories, or frontend code. Always make API calls from your server backend.
Authentication
All API requests must include a Bearer token in the
HTTP Authorization header.
Authorization: Bearer YOUR_API_TOKEN Content-Type: application/json Accept: application/json
Replace YOUR_API_TOKEN with the exact token issued
during registration. The Bearer prefix is required
and case-sensitive.
Base URL
Prepend this base URL to every endpoint path. Example:
https://palmpesa.drmlelwa.co.tz/api/process-payment
- Use Tanzanian phone format starting with 06 or 07 (no + sign), or country code 255
-
Your
callback_urlmust return HTTP 200 OK within 10 seconds and be publicly reachable - After initiating a payment, poll Get Order Status or listen on your webhook to confirm the final state
- Always test with small amounts (200–1000 TZS) before processing live transactions
Pay by Link
Endpoint 01Generate a shareable hosted payment page. The buyer completes their preferred payment method on the PalmPesa-hosted checkout.
Request Headers
| Header | Required | Value |
|---|---|---|
| Authorization | Required | Bearer YOUR_API_TOKEN |
| Content-Type | Required | application/json |
| Accept | Required | application/json |
Request Body
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| user_id | integer | Required | Your PalmPesa developer User ID | 25 |
| vendor | string | Required |
Vendor identifier — use TILL61103867 unless
instructed otherwise
|
"TILL61103867" |
| order_id | string | Required | Unique ID per transaction | "ORDER-100" |
| buyer_email | string | Required | Buyer email address | "user@example.com" |
| buyer_name | string | Required | Full name of the buyer | "Sephania Nathan" |
| buyer_phone | string | Required | Phone with country code, no + sign | "255744000000" |
| amount | integer | Required | Transaction amount in TZS | 500 |
| currency | string | Required | Currency code | "TZS" |
| redirect_url | string | Required | URL after successful payment | "https://yourdomain.com/success" |
| cancel_url | string | Required | URL if payment is cancelled | "https://yourdomain.com/cancel" |
| webhook | string | Required | Webhook URL for async payment status updates | "https://yourdomain.com/webhook" |
| buyer_remarks | string | Required | Buyer notes | "Online Delivery" |
| merchant_remarks | string | Required | Description of items or service | "Starlink Kit" |
| no_of_items | integer | Required | Number of items in order | 1 |
Example Request
curl -X POST 'https://palmpesa.drmlelwa.co.tz/api/process-payment' \ -H 'Authorization: Bearer YOUR_API_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -d '{ "user_id": 25, "vendor": "TILL61103867", "order_id": "TEST-ORDER-100", "buyer_email": "sephania@eaglestar.com", "buyer_name": "Sephania Nathan", "buyer_phone": "255744000000", "amount": 500, "currency": "TZS", "redirect_url": "https://yourdomain.com/success", "cancel_url": "https://yourdomain.com/cancel", "webhook": "https://yourdomain.com/webhook", "buyer_remarks": "Online Delivery", "merchant_remarks": "Starlink Kit", "no_of_items": 1 }'
Response 200 OK
{
"error": "sharable payment link",
"raw": {
"payment_gateway_url": "https://tz.selcom.online/paymentgw/checkout/VVNKSzVQWFpmRDBa..."
}
}
Callback / Webhook Payload
{
"reference": "0927530628",
"resultcode": "000",
"data": [{
"order_id": "SELCOM17454039012135",
"creation_date": "2025-04-23 13:26:54",
"amount": "500",
"payment_status": "COMPLETED",
"transid": "805613901007",
"channel": "AIRTELMONEY",
"reference": "0927530628",
"msisdn": "255693662424"
}]
}
This endpoint returns a hosted checkout URL only. Final payment
status arrives asynchronously via your webhook URL
or by polling Get Order Status.
Webhook Payment using phone number
Endpoint 02The Result May
This endpoint initiates a direct payment request to the user's mobile money wallet (typically via USSD push or prompt). The user will receive a payment prompt on their phone to approve the transaction.
Remember you can monitor the payment status via your
callback_url (webhook) or by polling the
Get Order Status endpoint using the provided
transaction_id.
Headers
| Parameter | Required | Example Value |
|---|---|---|
| Authorization | Required | Bearer YOUR_API_TOKEN |
| Content-Type | Required | application/json |
| Accept | Recommended | application/json |
Request Body Parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| name | string | Required | Full name of the payer / buyer | "Sara John" |
| string | Required | Email address of the payer | "john@example.com" | |
| phone | string | Required | Phone number to receive the payment prompt (Tanzania format with country code, no +) | "0693662424" |
| amount | integer / number | Required | Amount to charge in TZS | 200 |
| transaction_id | string | Required | Your unique transaction / order identifier | "2775" |
| address | string | Required | Address or location of the payer | "Dar es Salaam" |
| postcode | string | Required | Postcode / postal code | "11111" |
| callback_url | string | Required | Your server webhook / callback URL to receive payment status updates (must be publicly accessible) | "http://anord.site/your-test-url" |
Example Request Body
{
"name": "Sara John",
"email": "john@example.com",
"phone": "0693662424",
"amount": 200,
"transaction_id": "2775",
"address": "Dar es Salaam",
"postcode": "11111",
"callback_url": "http://anord.site/your-test-url"
}
cURL Example
curl --location --request POST \ 'https://palmpesa.drmlelwa.co.tz/api/palmpesa/initiate' \ --header 'Authorization: Bearer YOUR_API_TOKEN' \ --header 'Content-Type: application/json' \ --data-raw '{ "name": "Sara John", "email": "john@example.com", "phone": "0693662424", "amount": 200, "transaction_id": "2775", "address": "Dar es Salaam", "postcode": "11111", "callback_url": "http://anord.site/your-test-url" }'
Response when Payment initiated 200 OK
Make sure you also store this order id safely for later reconciliation and status checks.
{
"message": "Payment initiated. Processing will continue asynchronously.",
"order_id": "PALMPESA17682869972044"
}
This is a Callback Response
{
"order_id": "PALMPESA17683440586334",
"payment_status": "PENDING" // COMPLETED | FAILED | PENDING
}
Pay via Mobile / USSD
Endpoint 03Directly initiate a mobile money payment push without a hosted checkout page.
Request Body
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| user_id | string | Required | Your PalmPesa User ID | "2" |
| name | string | Required | Full name of the buyer | "Alune Kyusa" |
| string | Required | Buyer email address | "alune@example.com" | |
| phone | string | Required | Phone with country code, no + sign | "255744000000" |
| amount | integer | Required | Amount in TZS | 500 |
| transaction_id | string | Required | Unique transaction identifier | "TXN1234567891" |
| address | string | Required | Buyer address | "Mbeya" |
| postcode | string | Required | Postal code | "53127" |
| buyer_uuid | integer | Required | Unique buyer identifier in your system | 988776 |
Example Request
curl -X POST 'https://palmpesa.drmlelwa.co.tz/api/pay-via-mobile' \ -H 'Authorization: Bearer YOUR_API_TOKEN' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -d '{ "user_id": "2", "name": "Alune Kyusa", "email": "alune@example.com", "phone": "255744000000", "amount": 500, "transaction_id": "TXN1234567891", "address": "Mbeya", "postcode": "53127", "buyer_uuid": 988776 }'
Response 200 OK
{
"message": "Payment request sent to user's phone",
"order_id": "SELCOM17458294939723",
"response": {
"reference": "S19997158895",
"transid": "TXN1745829493",
"resultcode": "000",
"result": "SUCCESS",
"message": "Wallet push successful",
"data": []
}
}
Get Order Status
Endpoint 04
Poll for the current status of any payment order using its
order_id.
Request Body
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| order_id | string | Required | Order ID returned during payment initiation | "PALMPESA17458309277044" |
Example Request
curl -X POST 'https://palmpesa.drmlelwa.co.tz/api/order-status' \ -H 'Authorization: Bearer YOUR_API_TOKEN' \ -H 'Content-Type: application/json' \ -d '{"order_id": "PALMPESA17458309277044"}'
Response 200 OK
{
"reference": "0927530628",
"resultcode": "000",
"result": "SUCCESS",
"message": "Order fetch successful",
"data": [{
"order_id": "SELCOM17454039012135",
"creation_date": "2025-04-23 13:26:54",
"amount": "500",
"payment_status": "COMPLETED", // COMPLETED | PENDING | FAILED
"transid": "805613901007",
"channel": "AIRTELMONEY",
"reference": "0927530628",
"msisdn": "255693662424"
}]
}
Check data[0].payment_status. Values:
COMPLETED, PENDING,
FAILED. Use exponential backoff when polling.
Get Transaction List
Endpoint 05Retrieve a paginated list of all transactions associated with your account.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| page | integer | Optional | Page number (default: 1) |
| per_page | integer | Optional | Results per page (default: 20, max: 100) |
curl -X GET \ 'https://palmpesa.drmlelwa.co.tz/api/transactions?page=1&per_page=20' \ -H 'Authorization: Bearer YOUR_API_TOKEN' \ -H 'Accept: application/json'
Palm Card Operations
Endpoint 06Issue virtual Palm Cards, deposit funds, and manage card activation status.
Create Palm Card
curl -X POST 'https://palmpesa.drmlelwa.co.tz/api/cards' \ -H 'Authorization: Bearer YOUR_API_TOKEN' \ -H 'Content-Type: application/json' \ -d '{"pin": "1234"}'
Deposit Money to Palm Card
curl -X POST 'https://palmpesa.drmlelwa.co.tz/api/card/add-money' \ -H 'Authorization: Bearer YOUR_API_TOKEN' \ -H 'Content-Type: application/json' \ -d '{"phone": "0744000000", "amount": "500"}'
Toggle Card Status (Enable / Disable)
curl -X POST \ 'https://palmpesa.drmlelwa.co.tz/api/cards/10/toggle-status' \ -H 'Authorization: Bearer YOUR_API_TOKEN' \ -H 'Content-Type: application/json'
Send Money (Card → Card)
Endpoint 07Transfer funds from your Palm Card to another Palm Card instantly.
Request Body
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| card_number | string | Required | Recipient Palm Card number | "3410020000" |
| amount | integer | Required | Amount to transfer in TZS | 500 |
| pin | string | Required | Sender 4-digit card PIN | "1234" |
curl -X POST 'https://palmpesa.drmlelwa.co.tz/api/send-to-card' \ -H 'Authorization: Bearer YOUR_API_TOKEN' \ -H 'Content-Type: application/json' \ -d '{ "card_number": "3410020000", "amount": 500, "pin": "1234" }'
User Registration & Login
Endpoint 08Create new user accounts and authenticate to obtain API tokens programmatically.
Register New User
curl -X POST 'https://palmpesa.drmlelwa.co.tz/api/register' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -d '{ "name": "Sephania Nathan", "phoneNumber": "0744000000", "location": "Dar es Salaam", "gender": "male", "role": "Normal", "nida_number": "123456789012341", "email": "sephania@eaglestar.com", "password": "StrongPassword123!", "password_confirmation": "StrongPassword123!" }'
User Login
curl -X POST 'https://palmpesa.drmlelwa.co.tz/api/login' \ -H 'Content-Type: application/json' \ -H 'Accept: application/json' \ -d '{ "email": "sephania@eaglestar.com", "password": "StrongPassword123!" }'
Support & Resources
Our team is available to help you integrate PalmPesa into your platform.
Integration Checklist
- Test with small amounts (200–500 TZS) before going to production
- Implement both webhook listeners and Order Status polling for reliability
-
Generate cryptographically unique
order_idper transaction (e.g. UUID v4) - Log all API requests and responses with timestamps for audit trails
-
Ensure your
callback_urlis publicly accessible and returns HTTP 200 promptly - Never hard-code credentials — use environment variables or a secrets manager