Payments · Convex component
convex-paystack
Accept payments and subscriptions with Paystack in your Convex app. Reactive transactions, subscription state, and webhook ingestion.
npm install convex-paystack20downloads last week
712downloads last 12 months
v0.0.5latest, Sep 18, 2026
5releases since Sep 12, 2026
Downloads
Download history
Loading download history…
Build this
Build with convex-paystack
The install and setup steps from the package documentation.
- 1
Install
bashnpm install convex-paystackRequirements: Convex v1.34.1 or later, Node.js 18+, a account
- 2
Quick Start
Five steps to add Paystack to your Convex app.
1. Add the component
In
convex/convex.config.ts:tsimport { defineApp } from "convex/server"; import convexPaystack from "convex-paystack/convex.config"; const app = defineApp(); app.use(convexPaystack); export default app;2. Set environment variables
bashnpx convex env set PAYSTACK_SECRET_KEY sk_live_xxxxxxxxxxxx3. Mount the webhook handler
In
convex/http.ts:tsimport { httpRouter } from "convex/server"; import { components } from "./_generated/api"; import { Paystack } from "convex-paystack"; const paystack = new Paystack(components.convexPaystack, { secretKey: process.env.PAYSTACK_SECRET_KEY!, }); const http = httpRouter(); http.route({ path: "/webhooks/paystack", method: "POST", handler: paystack.webhookHandler, }); export default http;4. Register the webhook in Paystack
- In Paystack Dashboard → Settings → API Keys & Webhooks
- Set the webhook URL:
https://your-deployment.convex.site/webhooks/paystack - Save. Paystack sends every event to this URL — the handler ignores events it doesn't recognize.
Your Convex site URL is in the Convex dashboard under Settings → URL & Deploy Key — it ends in
.convex.site.5. Initialize the client
In
convex/payments.ts:tsimport { components } from "./_generated/api"; import { Paystack } from "convex-paystack"; export const paystack = new Paystack(components.convexPaystack, { secretKey: process.env.PAYSTACK_SECRET_KEY!, });Import
paystackfrom this file in any Convex function that needs payments. - 3
Setup
convex/payments.ts— your central payments module:tsimport { components } from "./_generated/api"; import { Paystack } from "convex-paystack"; import { action } from "./_generated/server"; import { v } from "convex/values"; export const paystack = new Paystack(components.convexPaystack, { secretKey: process.env.PAYSTACK_SECRET_KEY!, }); export const checkout = action({ args: { email: v.string(), amount: v.number() }, handler: async (ctx, args) => paystack.initializeTransaction(ctx, args), });convex/http.ts— webhook entry point (shown in ). - 4
Usage
Start a checkout
tsexport const checkout = action({ args: { email: v.string(), amount: v.number() }, handler: async (ctx, args) => { return await paystack.initializeTransaction(ctx, { email: args.email, amount: args.amount, // subunit — kobo for NGN, pesewas for GHS, cents for USD callbackUrl: "https://yourapp.com/payment/callback", }); }, }); // Returns: { authorizationUrl, accessCode, reference } // Redirect the customer to authorizationUrl.Verify a transaction
tsexport const confirmPayment = action({ args: { reference: v.string() }, handler: async (ctx, args) => { return await paystack.verifyTransaction(ctx, args); }, }); // Returns: { status, reference, amount, currency, channel, paidAt, customerEmail, ... }Read a transaction reactively
tsexport const getTransaction = query({ args: { reference: v.string() }, handler: async (ctx, args) => { return await paystack.getTransaction(ctx, args); }, }); // Returns: Transaction | nullList a customer's transactions
tsexport const getHistory = query({ args: { customerEmail: v.string() }, handler: async (ctx, args) => { return await paystack.listTransactions(ctx, { customerEmail: args.customerEmail, limit: 20, }); }, }); // Returns: Transaction[] ordered newest first