Skip to content

Releases: kepas-tech/daraja-js

@kepas/daraja-js@1.6.3

Choose a tag to compare

@github-actions github-actions released this 17 Sep 13:28
466615f

Patch Changes

  • 7c7b563: Catalogue TP40153 for b2c, b2b, balance and reversal: the API operator that signed the request has no permission for this API, or is not in this organisation. Safaricom returns it as plain text today, so a caller gets the ResultDesc with no meaning, no retriable hint and no terminal hint attached. The proof is a production integration's own operator classification (production-code), the same class of proof as the 2001 handler entry; Safaricom publishes no reference for it, so nothing is claimed beyond what that integration handles. Only these four scopes carry it — an endpoint that has not shown the code keeps passing it through verbatim.

@kepas/daraja-js@1.6.2

Choose a tag to compare

@github-actions github-actions released this 16 Sep 17:57
a2fa2c7

Patch Changes

  • 74bf3d9: Bill Manager: a 401 Invalid Access Token on the documented path (/v1/billmanager-invoice/…) is sent once more on the path Safaricom's go-live email lists for the production product (/v1/billmanager-invoice/v1/billmanager-invoice/…). On a production app with the product ticked, the documented path is refused at the gateway while the same token runs every other product. A 401 never reaches Bill Manager, so nothing can be sent twice. Proof and the email's full list in docs/specs/bill-manager.md.

@kepas/daraja-js@1.6.1

Choose a tag to compare

@github-actions github-actions released this 16 Sep 17:36
4bea32c

Patch Changes

  • ead6290: hakikisha.lookup: when Safaricom answers HTTP 400 with its own envelope (body.message, e.g. "The customer does not exist."), the thrown DarajaAPIError now carries that message and the request id, the same as a 200 with header.status 400, instead of a bare "Daraja request failed (HTTP 400)".

@kepas/daraja-js@1.6.0

Choose a tag to compare

@github-actions github-actions released this 16 Sep 16:57
ea65265

Minor Changes

  • 8f6e53a: B2C Hakikisha: hakikisha.lookup({ phone }) returns a customer's registered name (first name in the clear, middle and last masked by Safaricom) from a phone number before a payout. Synchronous, retryable; a non-200 header.status throws DarajaAPIError with Safaricom's body.message. Spec proof in docs/specs/b2c-hakikisha.md.

Patch Changes

  • 7819028: A 401 from Daraja's gateway now discards the cached OAuth token (memory and the shared TokenStore) and sends the request once more with a fresh one. Daraja binds a token to the API products the app had when it was issued, so after a product is added on the portal every call to it answered 401 "Invalid Access Token" for up to an hour. The second send is safe for every call: a 401 is refused at the gateway before M-Pesa sees the request. A second 401 with the fresh token still throws DarajaAuthError.

@kepas/daraja-js@1.5.1

Choose a tag to compare

@github-actions github-actions released this 16 Sep 15:41
9aa9baf

Patch Changes

  • 412f4ee: A 401 from Daraja keeps the gateway's own errorMessage in DarajaAuthError.message (for example "Invalid Access Token" or "Invalid API call as no apiproduct match found"), so a caller can tell a bad token from a product that is not enabled on the app. The response body still lives only in the non-enumerable raw.

@kepas/daraja-js@1.5.0

Choose a tag to compare

@github-actions github-actions released this 06 Sep 16:42
3b9e67b

Minor Changes

  • eca78c8: Transaction Status by OriginatorConversationID, B2C v3, and initiator-credential codes.

    • status.transaction accepts originatorConversationId in place of (or alongside) transactionId, so a transaction that never returned a receipt can still be queried. Neither id → DarajaValidationError. The receipt-only body is unchanged.
    • parseStatusResult lifts transactionStatus and receipt (from the TransactionStatus / ReceiptNo result parameters, key spelling tolerated) onto StatusResult; params is untouched.
    • b2c.send accepts originatorConversationId; when given the request goes to /mpesa/b2c/v3/paymentrequest with OriginatorConversationID in the body. Omitted → v1 exactly as before.
    • Catalog: b2c entries for 2001 (initiator information invalid) and 8006 (security credential locked), and a b2b entry for 2001, proof safaricom-docs (docs/specs/business-to-pochi.md, docs/specs/b2c-account-topup.md, docs/specs/tax-remittance.md). b2b 8006 is not catalogued yet (no Safaricom document for a b2b endpoint lists it); the SDK passes Safaricom's ResultDesc through verbatim.
    • status.transaction now rejects blank or whitespace-only ids locally with DarajaValidationError (1.4.1 sent an empty TransactionID to Safaricom and surfaced the rejection as DarajaAPIError).
    • Type note: TransactionStatusInput.transactionId is now optional (string | undefined); callers that only read the type may need a narrowing.

@kepas/daraja-js@1.4.1

Choose a tag to compare

@github-actions github-actions released this 02 Sep 22:42
b75eb48

Patch Changes

  • 4ea2ebf: Repository moved to the KEPAS Technologies organization: github.com/kepas-tech/daraja-js. Package metadata (repository, homepage, bugs), the API reference URL, and all community links now point at the new home. No runtime changes.

@kepas/daraja-js@1.4.0

Choose a tag to compare

Minor Changes

  • f368fa2: Sync all documentation to v1.3.0 code reality and add the proven Lipa na Bonga result codes.

    • Add Bonga catalog entries to CATALOG (sync 200; processing 6000/6001/6004–6009/6011/1037/1031/2001/17, proof=safaricom-docs) so the declared bonga scope is no longer hollow.
    • docs/ERROR_CODES.md now renders all 13 scopes (was missing billmanager, ratiba, b2bexpress, bonga).
    • README "What's covered" lists every shipped namespace/method (the 8 v1.3.0 APIs were absent); the roadmap no longer advertises shipped features as "post-1.0". ROADMAP.md rewritten to reflect shipped reality.
    • CI now fails if docs/ERROR_CODES.md drifts from the catalog, and a unit test asserts every catalogued scope is rendered — making doc drift impossible to merge.

Patch Changes

  • 16bfea6: Add PREREQUISITES.md — a per-API guide to the exact Safaricom credentials, Daraja product enablement, operator roles, and Go-Live each capability requires (auth tiers grounded in the SDK's own guards; product/role facts from the official specs). Linked from the README and shipped in the npm tarball.

@kepas/daraja-js@1.3.0

Choose a tag to compare

Minor Changes

  • 9eac3d6: Add B2B Express Checkout (daraja.express.checkout) — vendor-initiated USSD push to a merchant's till (/v1/ussdpush/get-msisdn). OAuth-only, camelCase body, code/status sync ack; auto-generates RequestRefID (UUID) when omitted. Adds parseExpressCallback for the FLAT async callback (top-level resultCode, no Result{} envelope). New b2bexpress catalog scope (0, 4104, 4102 sync; 0, 4001 async).
  • 9eac3d6: Add b2b.topUp (B2C Account Top Up — BusinessPayToBulk, loads a B2C shortcode's Utility account; optional requester) and b2b.remitTax (Tax Remittance to KRA — PayTaxToKRA, PartyB fixed 572572, prn sent as AccountReference, own /mpesa/b2b/v1/remittax endpoint). Both reuse the b2b initiator guard, ack, and parseB2bResult. Verified live against production: topUp rejected an invalid PartyB synchronously; remitTax accepted (ResponseCode 0).
  • 9eac3d6: Add Bill Manager support (daraja.billManager): optIn, updateOptIn, sendInvoice, sendBulkInvoices (≤1000), cancelInvoice, cancelBulkInvoices, acknowledgePayment, plus parseBillManagerPayment (inbound payment push) and billManagerAck. Bill Manager uses its own success convention (string rescode "200", not ResponseCode "0") and an app_key header obtained from optIn (pass per-call as appKey or set config.billManagerAppKey). http.post now accepts an additive headers option; fixed auth/content-type headers always win the merge. New billmanager catalog scope (200/409).
  • 9eac3d6: Add Lipa na Bonga (daraja.bonga): calculatePoints (read-only points→KES conversion, retryable) and redeem (redeem Bonga points as payment to a paybill/till). OAuth-only, nested header/body envelope, success is header.responseCode 200. The redemption result settles on the existing C2B confirmation callback (parseC2bConfirmation) — no Bonga-specific result parser. New bonga catalog scope.
  • 9eac3d6: Add Query Organization Info (daraja.orgInfo.query) — synchronous, read-only shortcode validation (/sfcverify/v1/query/info) returning org name, tariff (ChargeProfileID), and a success flag. OAuth-only, idempotent (retryable). identifierType maps paybill→4 / till→2. Success is gated on ResponseMessage === "Success" + an OrganizationName (the spec's numeric success code is contradictory — 4000 vs 0 — so the raw code is exposed verbatim, not asserted).
  • 9eac3d6: Add Business To Pochi (daraja.b2c.toPochi) — pay a customer's business wallet (pochi la biashara) via /mpesa/b2pochi/v1/paymentrequest + BusinessPayToPochi. Reuses B2C auth, the ResponseCode "0" ack, and parseB2cResult. Caller-supplied originatorConversationId (dedupe guard, auto-generated UUID if omitted) and optional occasion (sent as Safaricom's misspelled Occassion).
  • 9eac3d6: Add M-Pesa Ratiba support (daraja.ratiba.create) — create a customer standing order (recurring collection) via /standingorder/v1/createStandingOrderExternal. OAuth-only; success is the nested ResponseHeader.responseCode "200". Adds parseRatibaCallback for the async result (nested responseBody.responseData[] name/value pairs, parsed case-insensitively), RatibaFrequency (1–8), and paybill/buygoods transaction-type mapping (the latter sends Safaricom's misspelled Standing Order Customer Pay Marchant). New ratiba catalog scope (200, 0, 1037, 1032, 2001, 1050, 1051).

v1.0.0 — @kepas/daraja-js

Choose a tag to compare

@nellylemmy nellylemmy released this 29 May 19:24

First stable release. @kepas/daraja-js on npm; API reference.

npm install @kepas/daraja-js

Complete Daraja coverage

STK Push · C2B (register + parse) · B2C · B2B + float transfers · Account Balance · Transaction Status (sync + async) · Reversal · Dynamic QR · Pull Transactions — every endpoint a production PayBill uses.

Plus: generateSecurityCredential, Stripe-compatible webhooks (sign/verify, sync + edge), a pluggable cross-process token cache (tokenStore, e.g. Redis — optional, in-memory by default), and the full DarajaError hierarchy.

Quality

  • 130 tests, CI green on Node 20/22/24 × ubuntu/macOS/Windows.
  • Published via npm OIDC Trusted Publishing with provenance; SBOM attached per release.
  • Passed an independent pre-1.0 security review — no blocking findings. Hardening: DarajaError.raw is non-enumerable (won't dump customer PII into logs); webhook verification is raw-body + constant-time + replay-windowed; retries never re-send a timed-out payment POST (no double-charge).
  • Encodes 16 production gotchas distilled from a live PayBill.

Stability

The public API is now under SemVer — breaking changes bump the major.