@alexasomba/better-auth-paystack

中文文档
3.1.1发布于 2026/07/29MITTypeScriptES Module构建来源已验证近 30 天下载 2187

Production-ready Paystack billing plugin for Better Auth. Supports subscriptions, one-time payments, organization billing, secure webhooks and more

此软件包已被标记为弃用

Deprecated: use the unscoped better-auth-paystack package instead. Install with: npm install better-auth-paystack. Update imports to better-auth-paystack.

原始使用文档
文档目录52 节
  1. AI Agent Skills
  2. Features
  3. Quick Start
  4. Prerequisites
  5. 1. Install Plugin & SDKs
  6. 2. Configure Environment Variables
  7. 3. Setup Server Plugin
  8. 4. Configure Client Plugin
  9. 5. Migrate Database Schema
  10. Migration Guide
  11. Old
  12. New
  13. Billing Patterns
  14. 1. Subscriptions
  15. 2. One-Time Payments
  16. Limits & Seat Management
  17. Member Seat Limits
  18. Resource Limits (e.g., Teams)
  19. Subscription Groups
  20. Currency Support
  21. Advanced Usage
  22. Organization Billing
  23. Inline Popup Modal
  24. Scheduled Changes & Cancellation
  25. Mid-Cycle Proration ( prorateAndCharge )
  26. Restricting Subscription Payment Channels
  27. Webhook Security
  28. Trial Abuse Prevention
  29. Lifecycle Hooks
  30. Trusted Server Operations
  31. Authorization & Security
  32. Client SDK Reference
  33. authClient.subscription.upgrade / create
  34. authClient.paystack.transaction.initialize
  35. authClient.subscription.list
  36. authClient.subscription.cancel / restore
  37. Schema Reference
  38. user
  39. organization
  40. subscription
  41. paystackTransaction
  42. paystackProduct
  43. Troubleshooting
  44. Database Indexing
  45. Syncing Products
  46. SDK Compatibility Note
  47. 🏗️ Development & Contributing
  48. License
  49. Roadmap
  50. v1.1.0 - Manual Recurring Subscriptions (Available Now)
  51. Future Considerations
  52. Links

Better Auth Paystack Plugin

A TypeScript-first plugin that integrates Paystack into Better Auth, providing a production-ready billing system with support for subscriptions (native & local), one-time payments, trials, organization billing, and secure webhooks.

npm downloads GitHub stars GitHub release bundlephobia Follow on Twitter GitHub License

Live Demo (Tanstack Start) | Source Code

AI Agent Skills

This package publishes agent skills so AI coding agents can load package-specific guidance for setup, subscriptions, organization billing, TanStack Start integration, client APIs, webhooks, local subscription lifecycle, schema changes, and testing.

Use TanStack Intent when you want to explicitly list or load individual skills:

npx @tanstack/intent@latest list
npx @tanstack/intent@latest load @alexasomba/better-auth-paystack#better-auth-paystack-setup
npx @tanstack/intent@latest load @alexasomba/better-auth-paystack#paystack-testing-fixtures

If you use an AI agent, run npx @tanstack/intent@latest install in your project so the agent knows how to discover package skills.

This package also ships skills in the npm package under skills/*/SKILL.md, so projects can use skills-npm to symlink installed package skills for compatible agents:

npm install @alexasomba/better-auth-paystack
npx skills-npm --yes

For this repository, maintainers can run pnpm run skills:dry-run to preview discovery through the TanStack example fixture or pnpm run skills:install to create local agent skill symlinks from that fixture.

Features

  • Billing Patterns: Support for Paystack-native plans, local-managed subscriptions, and one-time payments (products/amounts).
  • Auto Customer Creation: Optional Paystack customer creation on user sign up or organization creation.
  • Trial Management: Configurable trial periods with built-in abuse prevention logic.
  • Organization Billing: Associate subscriptions with organizations and authorize access via roles.
  • Subscription Channel Controls: Restrict subscription checkout to specific Paystack payment channels such as card-only.
  • Enforced Limits & Seats: Automatic enforcement of member seat upgrades and resource limits (teams).
  • Scheduled Changes: Defer subscription updates or cancellations to the end of the billing cycle.
  • Proration: Immediate mid-cycle prorated upgrades for local plans, using saved-card charges when possible and checkout fallback when interactive payment is required.
  • Popup Modal Flow: Optional support for Paystack's inline checkout experience via @alexasomba/paystack-inline.
  • Webhook Security: Pre-configured signature verification (HMAC-SHA512) and optional IP whitelisting.
  • Transaction History: Built-in support for listing and viewing local transaction records.

Quick Start

Prerequisites

  • Node.js: v22.0.0 or higher.
  • Better Auth: v1.6.9 or higher.

1. Install Plugin & SDKs

npm install better-auth @alexasomba/better-auth-paystack @alexasomba/paystack-node

Optional: Browser SDK (for Popup Modals)

npm install @alexasomba/paystack-inline

2. Configure Environment Variables

PAYSTACK_SECRET_KEY=sk_test_...
BETTER_AUTH_SECRET=...
BETTER_AUTH_URL=http://localhost:8787

3. Setup Server Plugin

import { betterAuth } from "better-auth";
import { paystack } from "@alexasomba/better-auth-paystack";
import { createPaystack } from "@alexasomba/paystack-node";
import { admin } from "better-auth/plugins";

const paystackClient = createPaystack({
  secretKey: process.env.PAYSTACK_SECRET_KEY!,
});

export const auth = betterAuth({
  plugins: [
    admin(),
    paystack({
      paystackClient,
      secretKey: process.env.PAYSTACK_SECRET_KEY!,
      createCustomerOnSignUp: true,
      subscription: {
        enabled: true,
        allowedPaymentChannels: ["card"], // Optional: enforce card-only subscriptions
        plans: [
          {
            name: "pro",
            group: "workspace", // Optional: one active/trialing subscription per group
            planCode: "PLN_pro_123", // Native: Managed by Paystack
            freeTrial: { days: 14 },
            limits: { teams: 5, seats: 10 }, // Custom resource & member limits
          },
          {
            name: "starter",
            amount: 50000, // Local: Managed by your app (500 NGN)
            currency: "NGN",
            interval: "monthly",
          },
        ],
      },
      products: {
        products: [{ name: "credits_50", amount: 200000, currency: "NGN" }],
      },
    }),
  ],
});

Paystack signs webhook payloads with the same PAYSTACK_SECRET_KEY used for API authentication; there is no separate webhook secret. Legacy webhook.secret and paystackWebhookSecret options are accepted for source compatibility but ignored.

4. Configure Client Plugin

import { createAuthClient } from "better-auth/client";
import { paystackClient } from "@alexasomba/better-auth-paystack/client";
import { adminClient } from "better-auth/client/plugins";

export const client = createAuthClient({
  plugins: [adminClient(), paystackClient({ subscription: true })],
});

5. Migrate Database Schema

npx better-auth migrate

Migration Guide

Version 2.0.0 contains a security-focused breaking change.

  • Removed public/client operator actions:
    • authClient.paystack.syncProducts()
    • authClient.paystack.syncPlans()
    • authClient.paystack.chargeRecurringSubscription(...)
  • Removed public Better Auth endpoints for:
    • /paystack/sync-products
    • /paystack/sync-plans
    • /paystack/charge-recurring
  • Added trusted server operations:
    • chargeSubscriptionRenewal
    • syncPaystackProducts
    • syncPaystackPlans

Old

await authClient.paystack.syncProducts();
await authClient.paystack.syncPlans();
await authClient.paystack.chargeRecurringSubscription({
  subscriptionId: "sub_123",
});

New

import {
  chargeSubscriptionRenewal,
  syncPaystackPlans,
  syncPaystackProducts,
  type ChargeRecurringSubscriptionResult,
  type PaystackSyncResult,
} from "@alexasomba/better-auth-paystack";

const ctx = { context: await auth.$context } as any;
const paystackOptions = {
  secretKey: process.env.PAYSTACK_SECRET_KEY!,
  paystackClient,
};

await syncPaystackProducts(ctx, paystackOptions);
await syncPaystackPlans(ctx, paystackOptions);
await chargeSubscriptionRenewal(ctx, paystackOptions, {
  subscriptionId: "sub_123",
});

These operations are intentionally server-only. Do not expose them through browser-triggered auth client calls.


Billing Patterns

1. Subscriptions

Use planCode from your Paystack Dashboard. Paystack handles the recurring logic and emails.

{ name: "pro", planCode: "PLN_xxx" }

Local

Use amount and interval. The plugin stores the status locally, allowing you to manage custom recurring logic or one-off "access periods".

{ name: "starter", amount: 50000, interval: "monthly" }

2. One-Time Payments

Fixed Products

Define pre-configured products in your server settings and purchase them by name.

await authClient.paystack.transaction.initialize({
  product: "credits_50",
});

Ad-hoc Amounts

Charge dynamic amounts for top-ups, tips, or custom invoices.

await authClient.paystack.transaction.initialize({
  amount: 100000, // 1000 NGN
  currency: "NGN",
  metadata: { type: "donation" },
});

Limits & Seat Management

The plugin automatically enforces limits across active and trialing subscriptions. When multiple subscription groups define the same numeric limit, the highest value wins; plan features are combined.

Member Seat Limits

Purchased seats are stored in the subscription.seats field. The plugin hooks into member.create and invitation.create to block additions once the limit is reached.

Resource Limits (e.g., Teams)

Define limits in your plan config, and they will be checked during resource creation:

plans: [{ name: "pro", limits: { teams: 5, seats: 10 } }];

The plugin natively checks the teams limit if using the Better Auth Organization plugin.

Subscription Groups

Set group on related plans when a user or organization may own independent subscriptions:

plans: [
  { name: "pro", group: "workspace", planCode: "PLN_pro" },
  { name: "priority-support", group: "support", planCode: "PLN_support" },
];

Group names are trimmed and lowercased. A reference can have one active or trialing subscription per group. Plans without group remain in the legacy default group, represented by a nullable subscription.groupId, so existing configurations keep their previous single-subscription behavior.


Currency Support

The plugin supports the following currencies with automatic minimum transaction amount validation:

CurrencyNameMinimum Amount
NGNNigerian Naira₦50.00
GHSGhanaian Cedi₵0.10
ZARSouth African RandR1.00
KESKenyan ShillingKSh 3.00
USDUnited States Dollar$2.00
XOFWest African CFA FrancCFA 100

Transactions below these thresholds will be rejected with a BAD_REQUEST error.

Advanced Usage

Organization Billing

Enable organization.enabled to bill organizations instead of users.

  • Auto Customer: Organizations get their own paystackCustomerCode.
  • Authorization: Organization owners and admins can manage billing by default. Use organization.billingRoles to extend the trusted role list, or subscription.authorizeReference when you need fully custom authorization.
paystack({
  subscription: {
    enabled: true,
    plans: [],
  },
  organization: {
    enabled: true,
    billingRoles: ["owner", "admin", "billing"],
  },
});

Inline Popup Modal

Use @alexasomba/paystack-inline for a seamless UI.

const { data } = await authClient.subscription.upgrade({ plan: "pro" });
if (data?.kind === "checkout") {
  const paystack = createPaystack({ publicKey: "pk_test_..." });
  paystack.checkout({
    accessCode: data.accessCode,
    onSuccess: (res) => authClient.paystack.transaction.verify({ reference: res.reference }),
  });
}

Scheduled Changes & Cancellation

Defer changes to the end of the current billing cycle:

  • Upgrades: Pass scheduleAtPeriodEnd: true in initializeTransaction().
  • Cancellations: Use authClient.subscription.cancel({ subscriptionCode, atPeriodEnd: true }) to keep the subscription active until the period ends.

Mid-Cycle Proration (prorateAndCharge)

The plugin can dynamically calculate the cost difference for immediate mid-cycle upgrades (like adding more seats). For locally managed plans:

  • If the subscription already has a reusable Paystack authorization code, the plugin charges the prorated delta off-session, records a local paystackTransaction, and immediately updates the subscription.
  • If there is no reusable authorization code available (for example, transfer-based payments), the plugin initializes a new checkout for the prorated delta instead of silently upgrading without payment.
  • If the prorated amount is below Paystack's minimum charge for the currency, the request is rejected so you can schedule the change for period end instead of undercharging.
const { data } = await authClient.paystack.transaction.initialize({
  plan: "pro",
  quantity: 5, // Upgrading seats
  prorateAndCharge: true, // Charges saved authorization or returns a checkout redirect for the delta
});

if (data?.kind === "checkout") {
  window.location.href = data.url;
}

if (data?.kind === "prorated") {
  console.log(data.message);
}

When the flow falls back to checkout, verify the returned transaction reference after payment. The plugin uses the stored proration metadata to apply the pending plan/seat change only after successful verification.

Restricting Subscription Payment Channels

Use subscription.allowedPaymentChannels to constrain which Paystack checkout channels can be used for subscription flows. This applies to standard subscription checkout, trial authorization flows, and interactive proration checkout fallbacks.

paystack({
  subscription: {
    enabled: true,
    allowedPaymentChannels: ["card"],
    plans: [{ name: "starter", amount: 50000, currency: "NGN", interval: "monthly" }],
  },
});

If a subscription payment is later verified with a disallowed channel, the plugin rejects activation instead of silently creating the subscription.

Webhook Security

The plugin automatically verifies the x-paystack-signature header to ensure events are authentic. For an extra layer of security, you can enable IP Whitelisting to restrict processing to Paystack's official servers.

paystack({
  secretKey: process.env.PAYSTACK_SECRET_KEY!,
  webhook: {
    verifyIP: true, // Enable IP whitelisting (defaults to false for flexible proxy support)
    trustedIPs: ["52.31.139.75", "52.49.173.169", "52.214.14.220"], // Optional: override trusted IPs
  },
});

Webhook signatures are always verified with secretKey, as required by Paystack. Do not create or configure a separate PAYSTACK_WEBHOOK_SECRET.

Trial Abuse Prevention

The plugin checks the referenceId history. If a trial was ever used (active, expired, or trialing), it will not be granted again, preventing resubscribe-abuse.

Lifecycle Hooks

React to billing events on the server by providing callbacks in your configuration:

Subscription Hooks (subscription.*)

  • onSubscriptionComplete: Called after successful transaction verification (Native or Local).
  • onSubscriptionCreated: Called when a subscription record is first initialized in the DB.
  • onSubscriptionUpdate: Called after a persisted lifecycle change.
  • onSubscriptionCancel: Called when a user or organization cancels their subscription.

Customer Hooks (top-level or organization.*)

  • onCustomerCreate: Called after the plugin successfully creates a Paystack customer.
  • getCustomerCreateParams: Return a custom object to override/extend the data sent to Paystack during customer creation.

Trial Hooks (subscription.plans[].freeTrial.*)

  • onTrialStart: Called when a new trial period begins.
  • onTrialEnd: Called when a trial converts to an active subscription.
  • onTrialExpired: Called when a trial ends without conversion.

Application callback failures are logged after billing state is persisted and do not cause an otherwise valid Paystack webhook to be replayed.

Global Hook

  • onEvent: Receives every webhook event payload sent from Paystack for custom processing.

Trusted Server Operations

Recurring renewals and Paystack catalog sync are intentionally not exposed through the browser auth client. Invoke them from trusted backend code only:

import {
  chargeSubscriptionRenewal,
  reconcilePaystackTransaction,
  syncPaystackPlans,
  syncPaystackProducts,
} from "@alexasomba/better-auth-paystack";

const ctx = { context: await auth.$context } as any;

await chargeSubscriptionRenewal(ctx, paystackOptions, {
  subscriptionId: "sub_123",
});

const settlement = await reconcilePaystackTransaction(ctx, paystackOptions, {
  reference: "PAYSTACK_REFERENCE",
  source: "queue",
  referenceId: "user_or_org_id",
});

if (settlement.ok) {
  console.log(settlement.transaction.status, settlement.subscription.updated);
}

await syncPaystackProducts(ctx, paystackOptions);
await syncPaystackPlans(ctx, paystackOptions);

Use reconcilePaystackTransaction from webhook handlers, queue retries, cron jobs, or admin actions when trusted server code needs the same verification and local transaction/subscription side effects as the browser verify endpoint.

Authorization & Security

authorizeReference

Control who can manage billing for specific references (Users or Organizations).

paystack({
  subscription: {
    authorizeReference: async ({ user, referenceId, action }) => {
      // Example: Only allow Org Admins to initialize transactions
      if (referenceId.startsWith("org_")) {
        const member = await db.findOne({
          model: "member",
          where: [
            { field: "organizationId", value: referenceId },
            { field: "userId", value: user.id },
          ],
        });
        return member?.role === "admin";
      }
      return user.id === referenceId;
    },
  },
});

Client SDK Reference

The client plugin exposes fully typed canonical methods under authClient.paystack, authClient.transaction, and authClient.subscription.

  • authClient.transaction.initialize, verify, list
  • authClient.subscription.create, upgrade, cancel, restore, list, billingPortal
  • authClient.paystack.config, listProducts, listPlans, plus the transaction/subscription helpers above

Legacy compatibility aliases remain available for migration, but new code should use the canonical methods:

  • authClient.subscription.disable(...) -> use authClient.subscription.cancel(...)
  • authClient.subscription.enable(...) -> use authClient.subscription.restore(...)

authClient.subscription.upgrade / create

Initializes a transaction to create or upgrade a subscription.

type upgradeSubscription = {
  /**
   * The name of the plan to subscribe to.
   */
  plan: string;
  /**
   * The email of the subscriber. Defaults to the current user's email.
   */
  email?: string;
  /**
   * Amount to charge (if not using a Paystack Plan Code).
   */
  amount?: number;
  /**
   * Currency code (e.g., "NGN").
   */
  currency?: string;
  /**
   * The callback URL to redirect to after payment.
   */
  callbackURL?: string;
  /**
   * Additional metadata to store with the transaction.
   */
  metadata?: Record<string, unknown>;
  /**
   * Reference ID for the subscription owner (User ID or Org ID).
   * Defaults to the current user's ID.
   */
  referenceId?: string;
  /**
   * Number of seats to purchase (for team plans).
   */
  quantity?: number;
};

authClient.paystack.transaction.initialize

Same as upgrade, but can also be used for one-time payments by omitting plan and providing amount or product.

type initializeTransaction = {
  /**
   * Plan name (for subscriptions).
   */
  plan?: string;
  /**
   * Product name (for one-time purchases).
   */
  product?: string;
  /**
   * Amount to charge (if sending raw amount).
   */
  amount?: number;
  /**
   * For existing locally managed subscriptions, calculate a mid-cycle delta and either
   * charge the saved authorization or return a checkout redirect for interactive payment.
   */
  prorateAndCharge?: boolean;
  // ... same as upgradeSubscription
};

type initializeTransactionResult =
  | {
      kind: "checkout";
      url: string;
      reference: string;
      accessCode: string;
      redirect: true;
    }
  | { kind: "scheduled"; status: "success"; message: string; scheduled: true }
  | { kind: "prorated"; status: "success"; message: string; prorated: true };

authClient.subscription.list

List subscriptions for a user or organization. Organization-scoped billing actions require an owner/admin membership by default. To allow roles such as billing, configure organization.billingRoles. For custom resources or deeper policy checks, configure subscription.authorizeReference.

type listSubscriptions = {
  query?: {
    /**
     * Filter by reference ID (User ID or Org ID).
     */
    referenceId?: string;
  };
};

authClient.subscription.cancel / restore

Cancel or restore a subscription.

  • Cancel: Sets cancelAtPeriodEnd: true. The subscription remains active until the end of the current billing period, after which it moves to canceled.
  • Restore: Reactivates a subscription that is scheduled to cancel.
type cancelSubscription = {
  /**
   * Optional reference owner (user ID or org ID) when managing another billing entity.
   */
  referenceId?: string;
  /**
   * The Paystack subscription code (e.g. SUB_...)
   */
  subscriptionCode: string;
  /**
   * The email token required by Paystack to manage the subscription.
   * Optional: The server will try to fetch it if omitted.
   */
  emailToken?: string;
  /**
   * When true, keep the subscription active until the current period ends.
   */
  atPeriodEnd?: boolean;
};

Schema Reference

The plugin extends your database with the following fields and tables.

user

FieldTypeRequiredDescription
paystackCustomerCodestringNoThe unique customer identifier from Paystack.

organization

FieldTypeRequiredDescription
paystackCustomerCodestringNoThe unique customer identifier for the organization.
emailstringNoThe billing email for the organization. fallsback to organization owner's email if absent.

subscription

FieldTypeRequiredDescription
planstringYesLowercased name of the active plan.
referenceIdstringYesAssociated User ID or Organization ID.
paystackCustomerCodestringNoThe Paystack customer code for this subscription.
paystackSubscriptionCodestringNoThe unique code for the subscription (e.g., SUB_... or LOC_...).
paystackTransactionReferencestringNoThe reference of the transaction that started the subscription.
paystackAuthorizationCodestringNoStored card authorization code for recurring charges (local plans).
statusstringYesactive, trialing, canceled, incomplete.
periodStartDateNoStart date of the current billing period.
periodEndDateNoEnd date of the current billing period.
trialStartDateNoStart date of the trial period.
trialEndDateNoEnd date of the trial period.
cancelAtPeriodEndbooleanNoWhether to cancel at the end of the current period.
seatsnumberNoPurchased seat count for team billing.

paystackTransaction

FieldTypeRequiredDescription
referencestringYesUnique transaction reference.
referenceIdstringYesAssociated User ID or Organization ID.
userIdstringYesThe ID of the user who initiated the transaction.
amountnumberYesTransaction amount in smallest currency unit.
currencystringYesCurrency code (e.g., "NGN").
statusstringYessuccess, pending, failed, abandoned.
planstringNoName of the plan associated with the transaction.
productstringNoName of the product associated with the transaction.
metadatastringNoJSON string of extra transaction metadata.
paystackIdstringNoThe internal Paystack ID for the transaction.
createdAtDateYesTransaction creation timestamp.
updatedAtDateYesTransaction last update timestamp.

paystackProduct

FieldTypeRequiredDescription
namestringYesProduct name.
descriptionstringNoProduct description.
pricenumberYesPrice in smallest currency unit.
currencystringYesCurrency code (e.g., "NGN").
quantitynumberNoAvailable stock quantity.
unlimitedbooleanNoWhether the product has unlimited stock.
paystackIdstringNoThe internal Paystack Product ID.
slugstringYesUnique slug for the product.
metadatastringNoJSON string of extra product metadata.
createdAtDateYesProduct creation timestamp.
updatedAtDateYesProduct last update timestamp.

Troubleshooting

  • Webhook Signature: Ensure PAYSTACK_SECRET_KEY matches the integration that sends the webhook. Paystack uses this API secret key for x-paystack-signature.
  • Email Verification: Use requireEmailVerification: true to prevent unverified checkouts.
  • Redirect Failures: Check your browser console; Paystack often returns 429 errors if you're hitting the test API too frequently.
  • Reference mismatches: Ensure referenceId is passed correctly for Organization billing.
  • Authorization Denied: Verify your authorizeReference logic is correctly checking user roles or organization memberships. Unauthorized attempts to verify transactions now return a 401 Unauthorized response to prevent data leaks.

Database Indexing

The plugin's schema definition includes recommended indexes and uniqueness constraints for performance. When you run npx better-auth migrate, these will be automatically applied to your database.

After upgrading, run npx better-auth migrate (or npx better-auth generate for schema-managed adapters). The additive cancelAt, canceledAt, endedAt, and billingInterval subscription columns are nullable; historical rows are populated as future lifecycle events are processed.

The following fields are indexed:

  • paystackTransaction: reference (unique), userId, referenceId.
  • subscription: paystackSubscriptionCode (unique), referenceId, paystackTransactionReference, paystackCustomerCode, plan.
  • user & organization: paystackCustomerCode.
  • paystackProduct: slug (unique), paystackId (unique).

Proration upgrades and trusted renewal charges also persist paystackTransaction rows, so local transaction history stays aligned with successful off-session charges.

Syncing Products

The plugin provides two ways to keep your product inventory aligned with Paystack:

1. Automated Inventory Sync

Whenever a successful one-time payment is made (via webhook or manual verification), the plugin automatically calls syncProductQuantityFromPaystack. This fetches the real-time remaining quantity from the Paystack API and updates your local database record, ensuring your inventory is always accurate.

2. Trusted Manual Bulk Sync

The public /paystack/sync-products endpoint was removed in 2.0.0. Run the trusted server operation from backend code instead:

import { syncPaystackProducts } from "@alexasomba/better-auth-paystack";

const ctx = { context: await auth.$context } as any;

await syncPaystackProducts(ctx, paystackOptions);

SDK Compatibility Note

The plugin now targets the official @alexasomba/paystack-node grouped client surface directly. If you inject a custom client, it should match the real SDK methods used by the plugin such as transaction.initialize, transaction.verify, transaction.chargeAuthorization, subscription.create, subscription.disable, and subscription.enable.


🏗️ Development & Contributing

This repository is powered by Vite+. You use the vp CLI to manage the entire workspace.

# Install dependencies
vp i

# Check project health (format, lint, types)
vp check --fix

# Build the core library
vp build

# Run tests
vp test

# Run the TanStack Start example
vp run examples/tanstack dev

Contributions are welcome! Please open an issue or pull request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Roadmap

Future features planned for upcoming versions:

v1.1.0 - Manual Recurring Subscriptions (Available Now)

  • Stored Authorization Codes: Securely store Paystack authorization codes from verified transactions.
  • Trusted Renewal Operation: Server-side helper to charge stored cards for renewals.
  • Card Management UI: Let users view/delete saved payment methods (masked card data only) - Upcoming
  • Renewal Scheduler Integration: Documentation for integrating with Cloudflare Workers Cron, Vercel Cron, etc. - Upcoming

Note: For local-managed subscriptions (no planCode), the plugin automatically captures and stores the authorization_code. Trigger renewals from trusted backend code with chargeSubscriptionRenewal(...).

Future Considerations

  • Multi-currency support improvements
  • Invoice generation
  • Payment retry logic for failed renewals

版本与发布记录

@alexasomba/better-auth-paystack 共发布 26 个版本,首次发布于 2025/12/16;过去 12 个月发布了 26 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
3.1.1latest2026/07/293 个月前
3.1.02026/07/293 个月前
3.0.12026/07/293 个月前
3.0.02026/06/025 个月前
2.5.02026/06/015 个月前
2.4.42026/05/135 个月前

其他发布通道:rc → 1.0.0-rc.3。

关于 @alexasomba/better-auth-paystack 的常见问题

@alexasomba/better-auth-paystack 是什么?

Production-ready Paystack billing plugin for Better Auth. Supports subscriptions, one-time payments, organization billing, secure webhooks and more注意:该包已被作者标记为弃用——Deprecated: use the unscoped better-auth-paystack package instead. Install with: npm install better-auth-paystack. Update imports to better-auth-paystack.

如何安装 @alexasomba/better-auth-paystack?

在项目目录运行 npm install @alexasomba/better-auth-paystack,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:better-auth(^1.6.25)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@alexasomba/better-auth-paystack 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@alexasomba/better-auth-paystack 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@alexasomba/better-auth-paystack 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@alexasomba/better-auth-paystack 可以商用吗?

@alexasomba/better-auth-paystack 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@alexasomba/better-auth-paystack 的下载量有多少?

根据 npm 官方下载统计,@alexasomba/better-auth-paystack 在 2026/10/06 – 2026/11/04 这 30 天内被下载 2,187 次,日均约 73 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@alexasomba/better-auth-paystack 还在维护吗?

最新版本 3.1.1 发布于 2026/07/29(3 个月前);至今共发布 26 个版本,其中过去 12 个月发布了 26 个;首次发布于 2025/12/16。作者已将其标记为弃用,新项目建议寻找替代方案。