|
| 1 | +# Changelog |
| 2 | + |
| 3 | +## [0.2.0] — 2026-04-03 |
| 4 | + |
| 5 | +### Added |
| 6 | + |
| 7 | +- **Webhook relay server** (`mpesa-stk/server`) — the missing reliability layer between Safaricom and your app. Safaricom fires your `CallbackURL` once with no retry. The relay receives that callback, validates it, deduplicates it, persists it, and delivers it to your app with exponential-backoff retries (immediate → 30s → 2m → 10m → 30m → 2h → dead letter). |
| 8 | + |
| 9 | +- `createRelayServer(config)` — returns a Hono app with four routes: |
| 10 | + - `POST /apps` — register an app, get back `appId` + `signingSecret` |
| 11 | + - `PATCH /apps/:appId` — update your target URL after a deploy |
| 12 | + - `POST /hooks/:appId` — point your Safaricom `CallbackURL` here |
| 13 | + - `GET /status/:checkoutRequestId?app_id=` — query delivery status |
| 14 | + |
| 15 | +- `PostgresRelayAdapter` — relay storage over two new tables (`relay_apps`, `relay_delivery_events`). Completely separate from `mpesa_payments` — adopting the relay requires no schema changes to your existing setup. |
| 16 | + |
| 17 | +- `recoverPendingDeliveries(storage)` — call on startup to reschedule any deliveries that were in-flight when the server last stopped. The `nextAttemptAt` column persists intent to Postgres so no delivery is permanently lost to a process restart. |
| 18 | + |
| 19 | +- `signBody(body, secret)` / `verifySignature(body, secret, sig)` — HMAC-SHA256 signing helpers. The relay signs every outbound delivery; your app verifies it. Safaricom sends unsigned callbacks — without this, anyone who discovers your endpoint URL can POST fake success payloads. |
| 20 | + |
| 21 | +- **Standalone binary** (`npx mpesa-stk-relay`) — run the relay as a self-contained process with `DATABASE_URL` and `PORT`. Migrates tables on startup, recovers in-flight deliveries, and runs a 60-second sweep interval as a backstop. Logs as newline-delimited JSON. |
| 22 | + |
| 23 | +### Changed |
| 24 | + |
| 25 | +- `tsup.config.ts` split into two build targets: library (ESM + CJS + types, Hono external) and binary (bundled CJS with shebang, pg external). |
| 26 | +- `package.json` gains `bin.mpesa-stk-relay`, `exports["./server"]`, and `hono` + `@hono/node-server` as runtime dependencies. |
| 27 | + |
| 28 | +### Notes |
| 29 | + |
| 30 | +The core `MpesaStk` class, all adapters, and the full test suite are unchanged. This release is purely additive — existing integrations require no changes. |
| 31 | + |
| 32 | +--- |
| 33 | + |
| 34 | +## [0.1.1] — 2026-03-26 |
| 35 | + |
| 36 | +### Fixed |
| 37 | + |
| 38 | +- Corrected repository URL in `package.json` to `ronnyabuto/mpesa-stk`. |
| 39 | +- Switched build tool to `tsup` for dual CJS + ESM output with proper `.d.ts` generation. |
| 40 | + |
| 41 | +--- |
| 42 | + |
| 43 | +## [0.1.0] — 2026-03-24 |
| 44 | + |
| 45 | +### Added |
| 46 | + |
| 47 | +- `MpesaStk` class — idempotent STK Push initiation, callback processing, polling fallback, reconciliation. |
| 48 | +- `PostgresAdapter` — storage over `mpesa_payments` table with atomic `settlePayment` (compare-and-swap deduplication). |
| 49 | +- `MemoryAdapter` — in-memory adapter for testing. |
| 50 | +- Phone number normalisation accepting 6 input formats → `254xxxxxxxxx`. |
| 51 | +- Result code mapping: `0` → SUCCESS, `1032` → CANCELLED, `1037` → TIMEOUT, `1019` → EXPIRED, others → FAILED. `TIMEOUT` is explicitly not a failure — money may have moved. |
| 52 | +- Callback amount validation with ±1 KES tolerance. |
| 53 | +- `StorageAdapter` interface for custom storage backends. |
0 commit comments