Radon/SDKs/Payments
@radonsdk/payments24 providers

One charge() across 24 processors.

Global, African, and crypto — Stripe to Flutterwave to Coinbase Commerce. Provider quirks (auth schemes, minor vs major units, wildly different webhooks) are absorbed inside each adapter and never leak into your code.

$npm i @radonsdk/payments
payments.ts
import { RadonPayments, money } from "@radonsdk/payments";

const payments = new RadonPayments({
  providers: { stripe: {} },
  defaultProvider: "stripe",
});

const charge = await payments.charge({
  amount: money(1999, "USD"),
  customer: { email: "ada@example.com" },
});
01what you get
01

24 providers, one API

charge, refund, subscriptions, and webhooks — every provider implements the same typed shape.

02

Money done right

Amounts are integer minor units plus an ISO-4217 currency. Zero-decimal (JPY) and three-decimal (KWD) currencies are handled for you.

03

Normalized webhooks

Every provider's events collapse into one schema. One handler — payments.webhooks.handle(req) — verifies the signature and normalizes.

04

Provider-agnostic coupons

A built-in coupon engine: validate, apply, and redeem — percentage or fixed, currency-aware, usage-limited.

05

Hooks & middleware

Composable lifecycle hooks and around-style middleware, bundled into shareable plugins (fraud checks, analytics, tax).

06

Escape hatch

result.raw always holds the untouched provider response, and BaseProvider lets you register your own processor.

02providers

5 free, 19 on Pro — same call for every one.

5 freeproduction-grade, no license
StripeStripePaystackPaystackPayPalPayPalOPayOPayBachsBachs
19 Proone key unlocks all
BraintreeBraintreeAdyenAdyenCheckout.comCheckout.comSquareSquareAuthorize.NetAuthorize.NetRazorpayRazorpayMollieMollieGoCardlessGoCardlessKlarnaKlarnaSkrillSkrillFlutterwaveFlutterwaveKorapayKorapayFincraFincraCoinbaseCoinbaseNOWPaymentsNOWPaymentsOpenNodeOpenNodeAfterpayAfterpayMercado PagoMercado PagoPayUPayU
03the API

A small, typed surface.

  • payments.charge({ amount, customer }): Promise<ChargeResult>

    One-time charge; returns a normalized result with status and redirectUrl.

  • payments.refund({ chargeId, amount? }): Promise<RefundResult>

    Full or partial refund on any provider.

  • payments.subscriptions.create(input): Promise<SubscriptionResult>

    Create, cancel, and retrieve recurring subscriptions.

  • payments.webhooks.handle(request): Promise<NormalizedEvent>

    Verify + normalize a provider webhook into one event schema.

  • payments.coupons.apply(code, amount): Promise<DiscountResult>

    Validate and apply a coupon to an amount before charging.

  • money(1999, "USD")

    Build a Money value in integer minor units — $19.99 here.

04Handle a webhook
payments-example.ts
const event = await payments.webhooks.handle({
  body: req.rawBody,          // exact bytes, not parsed JSON
  headers: req.headers,
});

if (event.type === "charge.succeeded") {
  await fulfill(event.data.reference);
}

Minor units, and raw webhook bytes

money(1999, "USD") is $19.99 — pass a float and it throws; use majorMoney(19.99, "USD"). And webhook signatures are computed over the exact bytes received — pass req.rawBody, never parsed-and-re-serialized JSON, or verification fails.