||

Getting started

Install Payweave, initialize a client, and create your first checkout in under 10 minutes.

Install

Add Payweave with your package manager of choice.

Install
npm install payweave
pnpm add payweave
yarn add payweave
bun add payweave

Payweave is ESM-only and requires Node ≥ 20.19 (native require(esm) interop). No CJS build is shipped.

Initialize — one client, any provider(s)

createPayweave takes one config object keyed by provider. Configure just the ones you use:

import { createPayweave } from "payweave"

const payweave = createPayweave({
  paystack: { secretKey: process.env.PAYSTACK_SECRET_KEY! },
})

payweave.providers       // ["paystack"]
payweave.defaultProvider // "paystack"
payweave.environment     // "test" | "live" — inferred from the key prefix
payweave.paystack        // PaystackClient — provider-native resources (Surface A)

Configure more than one provider and set defaultProvider to disambiguate which one the unified layer targets by default:

const payweave = createPayweave({
  stripe: { secretKey: process.env.STRIPE_SECRET_KEY! },
  paystack: { secretKey: process.env.PAYSTACK_SECRET_KEY! },
  defaultProvider: "paystack", // required once more than one provider is configured
})

payweave.stripe   // StripeClient
payweave.paystack // PaystackClient
// payweave.flutterwave  ->  compile-time error: not configured

Test vs live is a config change, not a code change — inferred from the key prefix:

ProviderTest prefixLive prefix
Stripesk_test_ / rk_test_sk_live_ / rk_live_
Paystacksk_test_sk_live_
Flutterwave v3FLWSECK_TEST-FLWSECK-

A malformed or unrecognized key throws PayweaveConfigError at construction, naming the expected prefixes — a request is never sent with a key that can't be classified.

Your first checkout (unified layer)

The unified layer always takes integer minor units; the adapter converts to each provider's native units for you.

const payweave = createPayweave({
  paystack: { secretKey: process.env.PAYSTACK_SECRET_KEY! },
})

const checkout = await payweave.checkout.create({
  amount: { value: 500_000, currency: "NGN" }, // ₦5,000 in kobo
  customer: { email: "ada@example.com" },
  reference: "order_8123", // → Paystack `reference` / Flutterwave `tx_ref`
  redirectUrl: "https://app.example.com/pay/callback",
})

// → { checkoutUrl, reference, providerRef, raw }
console.log(checkout.checkoutUrl)

Redirect your customer to checkoutUrl. After they return, verify before granting value:

const result = await payweave.verify({ reference: "order_8123" })
// → { status: "success" | "failed" | "pending" | "abandoned" | "reversed",
//     amount: { value, currency }, customer, paidAt, channel, raw }

if (result.status === "success") {
  // fulfil the order
}

Configure a second provider and the exact same unified code keeps working — pass { provider: "stripe" } per call to target a non-default one. Not every unified operation is supported on every provider; see capabilities.

Next steps

  • Providers — the provider-native Surface A for Stripe, Paystack, and Flutterwave.
  • Unified layer — normalized, portable operations and the capability matrix.
  • Webhooks — verify and normalize events correctly, for any configured provider.
  • Database — persist customers, subscriptions, and usage.
  • Plans & features and Metered usage — billing on top of your database.
  • CLI — scaffold a project, migrate, sync plans, and relay webhooks locally.
  • Errors & retries — typed failures and retry behavior.
Did you like the content?