Provider-agnostic TypeScript building blocks for reliable payment integrations. Patterns extracted from years of shipping fintech systems — without coupling to any specific PSP.
- Idempotency —
withIdempotency()wrapper + pluggable store interface so retried client requests never double-charge. - Double-entry ledger — minimal in-memory
Ledgerthat enforces debits == credits at post time. Use it directly, or as a reference shape for your persistent ledger. - Webhook signature verification — HMAC-SHA256 verifier with timestamp
tolerance and constant-time comparison. Compatible with the signing scheme
most providers use (Stripe-style
t=...,v1=...).
No provider SDKs. No HTTP framework. Just patterns you compose into your own service.
npm install
npm test
npm run exampleimport { InMemoryIdempotencyStore, withIdempotency, Ledger } from "payments-integration-kit";
const store = new InMemoryIdempotencyStore<{ chargeId: string }>();
const ledger = new Ledger();
const result = await withIdempotency(store, idempotencyKey, fingerprint, async () => {
ledger.post({
id: "ch_001",
currency: "ZMW",
entries: [
{ account: "customer:123", direction: "debit", amount: 5000n },
{ account: "revenue", direction: "credit", amount: 5000n },
],
});
return { chargeId: "ch_001" };
});See examples/charge-flow.ts for an end-to-end flow
combining all three primitives.
bigintfor money. No floats anywhere. Amounts are minor units (ngwee, cents). Currency is tracked separately and never mixed.- Idempotency stores its result, not just its key. Replays return the original response — that is the entire point of the pattern.
- Fingerprints catch key reuse. If the same key arrives with a different body, you get a conflict instead of silently returning a stale result.
- Webhook verification rejects on time skew. A valid signature on a 6-hour-old payload is still a replay attack.
v0.1 — minimal but real. Roadmap:
- Reconciliation helpers (compare provider settlements vs. ledger)
- Retry policy primitive (exponential backoff with jitter, dead-letter)
- Persistent store adapters (Postgres, Redis)
- Money type with currency-safe arithmetic
MIT © Penjani Mkandawire