Files
skills/docs/money/payment/payment/README.md
2026-05-29 08:20:56 +01:00

10 KiB

@suaveplan/payment - Universal payment intent lifecycle, state-machine enforcement, webhook signature verification, receipt generation, fraud scoring, refund tracking, tax calculation, retry orchestration, reconciliation, and card tokenization. Provider-agnostic — concrete gateway adapters (Stripe, PayPal, Test) ship in this package; bring-your-own PaymentProvider for everything else.

Universal payment intent lifecycle, webhook signature verification, receipt generation, fraud scoring, refund tracking, tax calculation, retry orchestration, reconciliation, and PCI-conscious card tokenisation. Provider-agnostic — drop in TestGateway, StripeGateway, PayPalGateway, or any custom PaymentProvider. Zero browser- or Node-only imports; runs on Bun, Node ≥ 18, modern browsers, and Web Workers.

Documentation tree

  • engine — Orchestrates the full payment intent lifecycle on top of an injected PaymentProvider. Owns the state machine (`VALID_…
    • engine — Orchestrates the full payment intent lifecycle on top of an injected PaymentProvider. Owns the state machine (`VALID_…
  • error-codes — Stable, namespaced error registry and discriminated PaymentError class for the payment package. Every failure path in…
    • error-codes — Stable, namespaced error registry and discriminated PaymentError class for the payment package. Every failure path in…
  • fraud — Risk-scoring helper that flags suspicious payment attempts before they reach the provider. Four built-in rules — veloci…
    • fraud — Risk-scoring helper that flags suspicious payment attempts before they reach the provider. Four built-in rules — veloci…
  • paypal — PayPal REST adapter for the abstract PaymentGateway contract. Talks to the Orders API v2 via injected fetch, caches…
  • stripe — Stripe REST adapter for the abstract PaymentGateway contract. Talks to the Payment Intents API directly via injected…
  • test — In-memory PaymentGateway implementation used by tests, fixtures, and local development. Records every operation in ch…
  • types — Defines the abstract PaymentGateway contract every concrete adapter (the in-memory TestGateway, the Stripe REST ada…
  • hooks — Tiny generic hooks bus owned by the payment package. It powers the payment:processing pipeline that fires inside `Pay…
    • hooks — Tiny generic hooks bus owned by the payment package. It powers the payment:processing pipeline that fires inside `Pay…
  • receipt — Generates structured Receipt objects from PaymentIntent plus caller- supplied line items, then provides a minimal p…
    • receipt — Generates structured Receipt objects from PaymentIntent plus caller- supplied line items, then provides a minimal p…
  • reconciliation — Reconciles a batch of internal payment records against gateway transaction records, matches them by id, surfaces amount…
    • reconciliation — Reconciles a batch of internal payment records against gateway transaction records, matches them by id, surfaces amount…
  • refund — Tracks per-intent refund history with balance validation, partial-refund support, and reason categorisation. The `Refun…
    • refund — Tracks per-intent refund history with balance validation, partial-refund support, and reason categorisation. The `Refun…
  • retry — Generic retry helper for payment operations. Wraps any async function with exponential backoff + jitter, honours a non-…
    • retry — Generic retry helper for payment operations. Wraps any async function with exponential backoff + jitter, honours a non-…
  • tax — In-memory tax-rate registry and line-item calculator. Supports tax-inclusive (price-includes-tax) and tax-exclusive (pr…
    • tax — In-memory tax-rate registry and line-item calculator. Supports tax-inclusive (price-includes-tax) and tax-exclusive (pr…
  • tokenization — PCI-conscious card tokeniser. Validates the PAN with the Luhn check, rejects malformed expiry data and expired cards as…
    • tokenization — PCI-conscious card tokeniser. Validates the PAN with the Luhn check, rejects malformed expiry data and expired cards as…
  • types — Shared type contracts for the payment lifecycle: status union, payment-method descriptors, refund and dispute records,…
    • payment — Shared type contracts for the payment lifecycle: status union, payment-method descriptors, refund and dispute records,…
  • webhook — Universal webhook signature verifier. Computes an HMAC over a timestamp.body envelope using `@suaveplan/crypto-h…
    • webhook — Universal webhook signature verifier. Computes an HMAC over a timestamp.body envelope using `@suaveplan/crypto-h…

Install

bun add @suaveplan/payment

Quick start

import {
 PaymentEngine,
 ReceiptGenerator,
 TestGateway,
 WebhookVerifier,
} from "@suaveplan/payment";

const gateway = new TestGateway();
const engine = new PaymentEngine({
 provider: {
  name: gateway.name,
  createIntent: async (input) => ({
   id: "pi_001",
   status: "created",
   amount: input.amount,
   capturedAmount: { amount: 0n, currency: input.amount.currency },
   refundedAmount: { amount: 0n, currency: input.amount.currency },
   captureMethod: input.captureMethod ?? "automatic",
   refunds: [],
   createdAt: new Date().toISOString(),
   updatedAt: new Date().toISOString(),
  }),
  confirmIntent: async () => {
   throw new Error("not used in quick start");
  },
  captureIntent: async () => {
   throw new Error("not used in quick start");
  },
  cancelIntent: async () => {
   throw new Error("not used in quick start");
  },
  refund: async () => {
   throw new Error("not used in quick start");
  },
  getIntent: async () => {
   throw new Error("not used in quick start");
  },
 },
});

engine.on("intent.created", (intent) =>
 console.log("created", intent.id, intent.amount)
);

const intent = await engine.createIntent({
 amount: { amount: 5000n, currency: "USD" },
 captureMethod: "automatic",
});

const verifier = new WebhookVerifier({ secret: "whsec_test" });
const ts = Date.now();
const body = JSON.stringify({
 id: "evt_001",
 type: "payment.captured",
 timestamp: ts,
 data: { intentId: intent.id },
});
const sig = verifier.sign(body, ts);
const { payload } = verifier.verify(body, sig, ts);

const receiptGen = new ReceiptGenerator({ merchantName: "Acme" });
const receipt = receiptGen.generate({
 intent,
 lineItems: [
  {
   description: "Widget",
   quantity: 1,
   unitPrice: intent.amount,
   total: intent.amount,
  },
 ],
 subtotal: intent.amount,
 total: intent.amount,
});
console.log(receiptGen.toPlainText(receipt), payload.type);

Modules

Features

  • Payment intent lifecycle — 9-state machine (created → pending → authorized → captured → partially_refunded / refunded / disputed / canceled / failed) with VALID_TRANSITIONS enforcement.
  • Typed lifecycle events — intent.created, intent.confirmed, intent.captured, intent.canceled, intent.failed, refund.created, refund.succeeded, refund.failed, dispute.opened, dispute.closed.
  • Webhook verification — HMAC over timestamp.body, configurable algorithm (SHA-256/384/512), constant-time compare, replay window.
  • Receipt generation — structured records + plain-text fallback.
  • Concrete gateway adapters — StripeGateway (Payment Intents API), PayPalGateway (Orders API v2 + OAuth token cache), TestGateway in-memory.
  • Fraud scoring — velocity, amount, customer, new-method heuristics.
  • Refund manager — partial refunds, balance ledger, reason filtering.
  • Retry orchestration — exponential backoff + jitter, non-retryable blocklist.
  • Tax calculator — region/country lookup, inclusive + exclusive pricing, exempt items.
  • Card tokenisation — Luhn check, brand detection, HMAC-SHA-256 token via Web Crypto.
  • Reconciliation — match / discrepancy / unmatched report with normalised status compare.
  • Typed errors — PaymentError extends SuaveplanError<PaymentErrorCode> carrying optional intentId / currentStatus / targetStatus / ageMs discriminants.

License

MIT