Skip to content

Lipa na Bonga ​

Lets customers pay your paybill or till with Safaricom Bonga points, at KES 0.2 a point. No initiator is needed.

The flow:

  1. Work out what the points are worth with calculatePoints.
  2. Ask the customer to redeem them with redeem. Daraja sends the customer an M-Pesa prompt.
  3. Once the points are deducted, M-Pesa pays your shortcode. The payment arrives as an ordinary C2B confirmation, on the URLs registered with c2b.registerUrls; read it with parseC2BNotification.

Calculate points ​

ts
const quote = await mpesa.bonga.calculatePoints({ points: 40 });
console.log(quote.amountCents, quote.rate); // 800, 0.2
FieldDaraja fieldNotes
pointspointsWhole points, at least 1.

If Daraja's body can't be read (a non-numeric or non-positive amount, non-integer points, a non-positive rate), calculatePoints throws ValidationError with body. paths, after the request was sent.

The response (BongaCalculateResponse) has amountCents (what the points are worth, in cents), points, rate (shillings per point), requestRefId, responseCode, customerMessage and raw.

Redeem ​

ts
await mpesa.bonga.redeem({
  phoneNumber: '0720776155',
  shortCode: 888880,
  accountNumber: 'INV-7',
  points: quote.points,
  amount: quote.amountCents / 100,
  rate: quote.rate,
});
FieldDaraja fieldNotes
phoneNumbermsisdnThe customer paying: 07…, 01…, +254… or 254…, sent as 254….
shortCodeshortCodeYour paybill or till, which is paid.
accountNumberaccountNumberThe account number at your paybill.
pointsbongaPointsWhole points, at least 1.
amountamountShillings, at most 2 decimal places; normally points × rate.
rateconversionRateShillings per point, as calculatePoints returned it.

Pass the values calculatePoints returned, so amount is points × rate. The SDK doesn't enforce that: the portal's own redeem sample sends KES 50 for 20 points at 0.2, and whether Daraja accepts a mismatch hasn't been tested, so Daraja decides. amount must be positive with at most 2 decimal places. The response (BongaRedeemResponse) has requestRefId, responseCode, responseMessage and raw. It only confirms the request was received.

Every response carries header.responseCode; anything but 200 throws DarajaApiError. The SDK doesn't send the Username and Password headers the portal lists for "Bonga Everywhere".

Tested live ​

Not yet. Both endpoints answered HTTP 404 with an empty body for the sandbox app, most likely because the app doesn't have the Lipa na Bonga product. Both calls are tested against the portal's samples.

Released under the MIT License.