---
name: bijection-convex-paystack
description: "Evaluate and integrate the Convex Paystack component with Bijection."
---

# Convex Paystack

Accept payments and subscriptions with Paystack in your Convex app. Reactive transactions, subscription state, and webhooks.

This is an upstream package. It has not been adapted or qualified for Bijection.

- Package: convex-paystack
- Source: https://github.com/sholajegede/convex-paystack
- npm: https://www.npmjs.com/package/convex-paystack
- Directory: https://bijection.com/components/convex-paystack

Read the upstream README for setup, license, and compatibility before using it.

## Integration workflow

1. Read the source README and package manifest at the recorded revision.
2. Confirm the required SDK, dependency availability, and runtime compatibility.
3. Follow the component's documented setup and configuration. Never invent an npm install command from a catalog package name.
4. Keep credentials in the project's existing secret store.
5. Follow the project's execution rules for verification and report what was actually checked.

## Original upstream skill

The following guidance describes convex-paystack. Its installation commands and APIs refer to the upstream package. Evaluate compatibility with the Bijection source separately.


> Agents: read this skill fully before writing code that uses Convex Paystack. Follow the installation and configuration steps exactly.

# Convex Paystack

## Instructions

convex-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.

### Installation

```bash
npm install convex-paystack
```

Current npm version: `convex-paystack@0.0.5`

## Use cases

- Adding one-time payment flows to a Convex app where transaction status needs to be reactively readable in queries without polling Paystack's API
- Building subscription-based SaaS products that need to track plan enrollment, renewal state, and cancellation in Convex-native storage
- Replacing hand-rolled webhook receivers that lack idempotency, signature verification, or automatic database writes
- Checking whether a user holds an active subscription inside a Convex query to gate access to features or content
- Syncing existing Paystack customer subscriptions into Convex when webhooks were missed or the webhook URL was not registered at project creation

## How it works

The component is registered in `convex/convex.config.ts` using `app.use(convexPaystack)`, which provisions the component's internal database tables for transactions, subscriptions, and raw webhook events. A `Paystack` class instance is constructed with `components.convexPaystack` and your Paystack secret key, and this instance is used across all action and query calls.

A webhook handler is mounted in `convex/http.ts` via `paystack.webhookHandler` on a route like `/webhooks/paystack`. When Paystack delivers an event, the handler verifies the HMAC signature, checks for duplicate delivery using stored event IDs, and writes the relevant state into the component's tables. Supported events include `charge.success`, `subscription.create`, `subscription.disable`, and invoice events.

Checkout is initiated with `initializeTransaction()`, which calls Paystack's Initialize Transaction endpoint, records a pending transaction locally, and returns `authorizationUrl` for client-side redirect. Passing a `plan` code to `initializeTransaction()` converts the checkout into a subscription flow. After the customer completes payment, `verifyTransaction()` confirms the final status server-side. Subscription data becomes available through reactive queries like `getSubscription()`, `listSubscriptions()`, and `hasActiveSubscription()` once the corresponding webhooks are processed.

For cases where webhook delivery was missed, `syncCustomerSubscriptions()` fetches live subscription data from Paystack's Fetch Customer endpoint and upserts it directly into the component's tables, bypassing the webhook path entirely.

## When NOT to use

- When a simpler built-in solution exists for your specific use case
- If you are not using Convex as your backend
- When the functionality provided by Convex Paystack is not needed

## Resources

- [npm package](https://www.npmjs.com/package/convex-paystack)
- [GitHub repository](https://github.com/sholajegede/convex-paystack)
- [Live demo](https://convex-paystack.vercel.app)
- [Convex Components Directory](https://www.convex.dev/components/convex-paystack)
- [Convex documentation](https://docs.convex.dev)