Skip to main content

Collect payments with PalmPesa

PalmPesa (Eagle Star Technology) is a Tanzanian mobile-money collection gateway. Centipid Billing pushes a payment request to the payer’s wallet, the payer authorizes it on their handset, and the subscriber is provisioned once PalmPesa confirms the order. PalmPesa is offered to ISPs in Tanzania (TZ), alongside ClickPesa, AzamPay, PawaPay, PesaPal, Relworx, ZenoPay, PayPal, and DPO. Provider API documentation is published at documentation.palmpesa.co.tz.

Before you start

  1. Complete PalmPesa merchant onboarding in an account owned by the ISP, and have the account verified.
  2. Collect the API token from the PalmPesa dashboard.
  3. Confirm the settlement account and the currency PalmPesa will settle in.
  4. Confirm your Centipid Billing host is reachable from the public internet, so PalmPesa can deliver callbacks.

Configure the gateway

1

Open Settings → Payments → PalmPesa

Select PalmPesa from the payment marketplace to open its configuration form.
2

Enter the API token

API token (required) is issued on your PalmPesa dashboard once the account is verified. It is stored as a secret and is not echoed back into the form after saving.
3

Leave the API host blank unless PalmPesa told you otherwise

API host (optional) overrides the endpoint Centipid Billing calls. Leave it empty to use the default PalmPesa endpoint. Only set it if PalmPesa has issued your account a different host.
4

Save and switch

Saving validates the form; it does not prove the token works. Switching to PalmPesa requires the API token to be present and may require an OTP confirmation.
5

Run a controlled test payment

Pay a small amount from the captive portal. Verify the wallet prompt arrives, the payment lands in the ledger with method PalmPesa, and the subscriber’s package is applied. See the limitation below before testing from the customer portal.
The callback URL is sent to PalmPesa on every payment request, so there is nothing to register in the PalmPesa dashboard. Settings → Payments still shows it under Callback URLs (https://<your-host>/api/palmpesa/callback) so you can confirm the address PalmPesa will call, and check it is not blocked by a firewall or WAF rule.

Credentials

What the payer must provide

PalmPesa rejects a payment request that carries no email address, so Centipid Billing requires one before the request is sent.
  • Email address (required). The captive portal asks the payer for an email when your account is on PalmPesa. The customer portal does not ask — it uses the email on the subscriber’s profile, so a subscriber with no email saved cannot pay from the portal. In either case, if no valid email is available checkout stops with “A valid email address is required for PalmPesa payments” before any request reaches PalmPesa. Add an email to the subscriber’s profile before directing them to the customer portal.
  • Tanzanian phone number (required). Accepted as 07…, 06…, or with the 255 country code; the number is normalized before it is sent.
  • Amount. Rounded to a whole number before the request is sent.
Because authorization happens on the payer’s handset rather than in a hosted checkout page, no PalmPesa domain needs to be added to the captive walled garden for the payer’s browser.
Customer-portal top-ups and invoice payments report a false failure on PalmPesa. The wallet prompt is sent and the payment completes normally, but the portal shows “Unable to start the payment. Please try again.” because it cannot read PalmPesa’s reference in the shape it expects.Direct PalmPesa payers to the captive portal until this is resolved. If a subscriber has already hit the error, do not tell them to retry — check the ledger first, because the original payment may have gone through, and a retry raises a second wallet prompt.

How a payment completes

1

Request

Centipid Billing calls POST /api/palmpesa/initiate. PalmPesa answers with an order_id, which becomes the local transaction reference that everything afterwards reconciles against.
2

Authorization

The payer approves the request on their phone.
3

Confirmation

A background job polls POST /api/order-status every 5 seconds, for up to 40 attempts (about 3 minutes 20 seconds), until the order reaches a terminal state. This poller — not the callback — is what completes the payment, so a payment still completes when the payer closes the captive browser mid-checkout.
4

Provisioning

On COMPLETED, a payment is recorded with method PalmPesa and the subscriber’s package is applied asynchronously. On FAILED, the failure reason is stored against the transaction and nothing is credited.
PalmPesa’s callback carries no signature, HMAC, or shared secret, so it cannot prove it came from PalmPesa. Centipid Billing treats it as a hint only: nothing is credited from the callback body. Every credit is made against a status read from PalmPesa itself, so a spoofed “completed” callback cannot provision a subscriber.
A failed request is deliberately not retried automatically. PalmPesa documents no idempotency on the request reference, so an automatic retry after a lost response could raise a second order and prompt the payer twice. The payer retries by choice instead.

Troubleshooting

For symptoms that are not specific to PalmPesa, see Payment troubleshooting. For every other gateway’s fields, see the credential reference.