convex-paystack integrates Paystack payments and subscriptions into Convex with reactive state, webhook ingestion, HMAC verification, and idempotent event handl
npm install convex-paystackconvex-paystack integrates Paystack payments and subscriptions into a Convex backend by handling webhook ingestion, HMAC signature verification, and database persistence automatically. It exposes reactive queries for transaction and subscription state, so connected clients update in real time as webhooks arrive. Developers get checkout initialization, server-side transaction verification, plan management, subscription lifecycle control, and idempotent webhook processing without writing any of that infrastructure themselves.
convex-paystack provides an initializeTransaction action that calls Paystack's Initialize Transaction endpoint, records a pending transaction in Convex, and returns the hosted checkout URL. After the customer completes payment, call verifyTransaction with the reference to confirm the final status server-side. The charge.success webhook also updates transaction state reactively in Convex.
convex-paystack exposes a webhookHandler that you mount on Convex's HTTP router at a path like /webhooks/paystack. It performs HMAC signature verification on every incoming request, skips unrecognized events, and deduplicates repeated deliveries of the same event automatically. You register the Convex site URL ending in .convex.site as the webhook endpoint in the Paystack dashboard.
Create a billing plan with createPlan specifying the amount, interval, and currency, then pass the returned planCode to initializeTransaction. When the customer's first payment succeeds, Paystack fires a subscription.create webhook that convex-paystack stores locally. Use hasActiveSubscription, getSubscription, and listSubscriptions as reactive Convex queries to read subscription state in real time.
convex-paystack provides a hasActiveSubscription query that accepts a customerEmail and returns true if that customer has a subscription in active or non-renewing status stored in Convex. Subscription state is kept in sync via webhooks and can also be refreshed on demand using syncCustomerSubscriptions if webhooks were missed during setup.
convex-paystack processes charge.success, subscription.create, subscription.disable, and invoice-related events from Paystack. Events it does not recognize are silently ignored. Each processed event is deduplicated so repeated webhook deliveries of the same event do not cause duplicate writes to Convex.
convex-paystack includes a syncCustomerSubscriptions action that fetches a customer's live subscriptions directly from Paystack's Fetch Customer endpoint and upserts them into Convex. This is useful during initial setup when the webhook URL was not yet registered in the Paystack dashboard and events were never delivered.
After a payment or subscription action in Paystack, there is typically a few seconds delay before Paystack delivers the webhook to your Convex deployment. Once the webhook arrives, Convex's real-time reactivity propagates the updated state to all active subscribers instantly. You can also call verifyTransaction immediately after the callback redirect for server-side confirmation without waiting for the webhook.
convex-paystack supports any currency enabled on your Paystack account. Amounts are specified in the smallest subunit for each currency, such as kobo for NGN, pesewas for GHS, and cents for USD. You can call listBalances to see which currencies are active on your account. Charging a currency not enabled on your account throws a Currency not supported by merchant error.
convex-paystack requires Convex v1.34.1 or later, Node.js 18 or later, and a Paystack account with a secret key. Install it with npm install convex-paystack, register the component in convex.config.ts, mount the webhook handler in convex/http.ts, and set the PAYSTACK_SECRET_KEY environment variable using npx convex env set.