https://github.com/alexasomba/paystack-node
A comprehensive and up-to-date TypeScript-first Paystack API client for Node.js, designed to make integrating Paystack’s payment services seamless and developer-friendly. It is generated directly from Paystack’s API specification, ensuring that the SDK stays aligned with the official API surface.
https://github.com/alexasomba/paystack-node
nodejs payments paystack paystack-api paystack-charge paystack-checkout paystack-library paystack-node paystack-plans paystack-sdk paystack-subaccounts paystack-subscriptions paystack-transaction-split paystack-webhook retry-logic secure-payments transactions typescript
Last synced: about 1 month ago
JSON representation
A comprehensive and up-to-date TypeScript-first Paystack API client for Node.js, designed to make integrating Paystack’s payment services seamless and developer-friendly. It is generated directly from Paystack’s API specification, ensuring that the SDK stays aligned with the official API surface.
- Host: GitHub
- URL: https://github.com/alexasomba/paystack-node
- Owner: alexasomba
- License: mit
- Created: 2026-02-02T15:06:21.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-04-16T07:45:47.000Z (about 1 month ago)
- Last Synced: 2026-04-16T08:38:58.971Z (about 1 month ago)
- Topics: nodejs, payments, paystack, paystack-api, paystack-charge, paystack-checkout, paystack-library, paystack-node, paystack-plans, paystack-sdk, paystack-subaccounts, paystack-subscriptions, paystack-transaction-split, paystack-webhook, retry-logic, secure-payments, transactions, typescript
- Language: TypeScript
- Homepage:
- Size: 6.11 MB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# @alexasomba/paystack-node
[](https://www.npmjs.com/package/@alexasomba/paystack-node)
[](https://github.com/alexasomba/paystack-node/blob/main/LICENSE)
[](https://bundlephobia.com/package/@alexasomba/paystack-node)
TypeScript-first Paystack API client for Node.js, generated from the official Paystack OpenAPI spec.
## Features
- **Spec-driven Accuracy**: Generated directly from the Paystack OpenAPI specification.
- **100% Type-safe**: Full TypeScript support with generated types for every endpoint, request, and response.
- **Smart Retries**: Automatic retries for transient failures with exponential backoff and jitter.
- **Retry-After Compliance**: Automatically respects Paystack `Retry-After` headers on rate limit responses.
- **Sophisticated Idempotency**: Built-in support for manual, static, or automatic UUID-based idempotency keys on POST requests.
- **Detailed Error Handling**: `PaystackApiError` includes `status`, `url`, and Paystack `requestId`.
- **Webhook Verification**: Timing-safe webhook signature verification helper included.
## Install
```bash
pnpm add @alexasomba/paystack-node
```
Authenticate requests with your Paystack secret key:
```ts
process.env.PAYSTACK_SECRET_KEY = "sk_test_...";
```
## Quick Start
```ts
import { createPaystack, assertOk } from "@alexasomba/paystack-node";
const paystack = createPaystack({
secretKey: process.env.PAYSTACK_SECRET_KEY!,
idempotencyKey: "auto",
});
const result = await paystack.transaction_initialize({
body: {
email: "customer@example.com",
amount: 5000,
},
});
const data = assertOk(result);
console.log(data.authorization_url);
```
`assertOk` returns the successful Paystack payload and throws a structured `PaystackApiError` for non-2xx responses.
## API Basics
- Base URL: `https://api.paystack.co`
- HTTPS is required for all requests.
- Requests and responses are JSON-based.
- Most successful responses follow the `status`, `message`, `data`, and optional `meta` envelope described in `Paystack-API/0a-Introduction.md`.
- Amounts are usually sent in currency subunits such as kobo, pesewas, or cents. Check the module docs for currency-specific rules.
## Authentication & Environments
- Server-side SDKs should use your secret key (`sk_test_*` or `sk_live_*`).
- Browser SDKs should use only your public key (`pk_test_*` or `pk_live_*`).
- Send server-side API credentials as `Authorization: Bearer YOUR_SECRET_KEY`.
- Test and live modes use different keys and isolated environments.
- Rotate keys if they are exposed, and never commit secret keys to source control.
- If you enable IP whitelisting in Paystack, requests from non-whitelisted IPs will be blocked.
## Advanced Configuration
The `createPaystack` helper accepts `PaystackClientOptions`:
```ts
const paystack = createPaystack({
secretKey: "sk_...",
timeoutMs: 30_000,
retry: {
retries: 3,
minDelayMs: 500,
retryOnStatuses: [429, 500, 503],
},
idempotencyKey: "auto",
headers: {
"X-My-App": "v1.0.0",
},
});
```
### Webhooks
Use the webhook helper when validating server-to-server events from Paystack. Pass the raw request body, not a parsed JSON object.
```ts
import { verifyPaystackWebhookSignature } from "@alexasomba/paystack-node/webhooks";
const isValid = verifyPaystackWebhookSignature({
rawBody: req.body,
signature: req.headers["x-paystack-signature"],
secret: process.env.PAYSTACK_SECRET_KEY!,
});
```
### Handling Pagination
List endpoints expose pagination controls through query params like `perPage`, `page`, `next`, and `previous`. Response headers are still available when you need manual pagination control.
## Pagination
- Paystack supports both offset pagination and cursor pagination.
- Offset pagination uses `page` and `perPage`.
- Cursor pagination uses `use_cursor=true` plus `next` or `previous` cursors returned in `meta`.
- Cursor pagination is especially useful for large or frequently changing datasets.
- The exact `meta` shape varies by endpoint and pagination mode.
```ts
const result = await paystack.customer_list({ query: { perPage: 20 } });
const customers = assertOk(result);
const total = result.response.headers.get("x-total-count");
```
## Error Handling
```ts
import { toPaystackApiError } from "@alexasomba/paystack-node";
const result = await paystack.transaction_initialize({
/* ... */
});
const error = toPaystackApiError(result);
if (error) {
console.error(`Status ${error.status}: ${error.message}`);
console.error(`Paystack Request ID: ${error.requestId}`);
}
```
The `requestId` is useful when correlating logs or escalating an issue with Paystack support.
## Errors
- Paystack uses conventional HTTP status codes such as `200`, `201`, `400`, `401`, `404`, and `5xx`.
- Error responses typically include `status`, `message`, `type`, `code`, and optional diagnostic `meta` information.
- Error types described in `Paystack-API/0d-Errors.md` include `api_error`, `validation_error`, and `processor_error`.
- For charge and verify flows, always inspect the returned response body and status fields, not just the HTTP code.
## Coverage
This SDK is generated from the SDK spec in this monorepo and currently tracks the full set of generated typed operations for the Paystack-API-aligned contract.
## Modules
For this SDK, these schema families are exposed through generated TypeScript types in `src/openapi-types.ts` and operation helpers in `src/operations.ts`.
| Module | Schema / model family |
| -------------------------------------------------------------------- | -------------------------------------------------------- |
| Transactions | `Transaction*` |
| Verify Payments (Transaction verification) | `VerifyResponse / TransactionFetchResponse` |
| Charges | `Charge*` |
| Bulk Charges | `BulkCharge*` |
| Subaccounts | `Subaccount*` |
| Transaction Splits | `Split*` |
| Terminal | `Terminal*` |
| Virtual Terminal | `VirtualTerminal*` |
| Customers | `Customer*` |
| Direct Debit | `DirectDebit*` |
| Dedicated Virtual Accounts | `DedicatedNuban* / DedicatedVirtualAccount*` |
| Apple Pay | `ApplePay*` |
| Plans | `Plan*` |
| Subscriptions | `Subscription*` |
| Transfer Recipients | `TransferRecipient*` |
| Transfers | `Transfer*` |
| Transfers Control (OTP settings; under Transfers) | `TransferEnable* / TransferDisable* / TransferFinalize*` |
| Balance | `Balance*` |
| Payment Requests (Invoices) | `PaymentRequest*` |
| Verification (Resolve Account / Validate Account / Resolve Card BIN) | `Verification*` |
| Products | `Product*` |
| Storefronts | `Storefront*` |
| Orders | `Order*` |
| Payment Pages | `Page*` |
| Settlements | `Settlement*` |
| Integration | `Integration*` |
| Control Panel (Payment session timeout; under Integration) | `ControlPanel*` |
| Refunds | `Refund*` |
| Disputes | `Dispute*` |
| Banks | `Bank*` |
| Miscellaneous | `Miscellaneous* / Currency` |
## Module Examples
These are intentionally short examples. Use them as entry points, then expand the request bodies with the typed fields exposed by your editor and `src/openapi-types.ts`.
### Transactions
```ts
const tx = await paystack.transaction_initialize({
body: { email: "customer@example.com", amount: 5000 },
});
```
### Verify Payments (Transaction verification)
```ts
const verified = await paystack.transaction_verify({
params: { path: { reference: "ref_123" } },
});
```
### Charges
```ts
await paystack.charge_create({
body: {
email: "customer@example.com",
amount: 5000,
bank: { code: "057", account_number: "0001234567" },
},
});
```
### Bulk Charges
```ts
await paystack.bulkCharge_initiate({
body: [{ authorization: "AUTH_xxx", amount: 5000, reference: "bulk-ref-1" }],
});
```
### Subaccounts
```ts
await paystack.subaccount_create({
body: {
business_name: "Acme Stores",
settlement_bank: "057",
account_number: "0001234567",
percentage_charge: 10,
},
});
```
### Transaction Splits
```ts
await paystack.split_create({
body: { name: "Main split", type: "percentage", currency: "NGN", subaccounts: [] },
});
```
### Terminal
```ts
const terminals = await paystack.terminal_list();
```
### Virtual Terminal
```ts
await paystack.virtualTerminal_create({
body: { name: "Web checkout terminal" },
});
```
### Customers
```ts
await paystack.customer_create({
body: { email: "customer@example.com", first_name: "Ada", last_name: "Lovelace" },
});
```
### Direct Debit
```ts
await paystack.directdebit_initialize({
body: { email: "customer@example.com", amount: 5000, bank_code: "057" },
});
```
### Dedicated Virtual Accounts
```ts
await paystack.dedicatedAccount_assign({
body: { customer: 12345, preferred_bank: "wema-bank" },
});
```
### Apple Pay
```ts
await paystack.applePay_registerDomain({
body: { domainName: "example.com" },
});
```
### Plans
```ts
await paystack.plan_create({
body: { name: "Starter", amount: 500000, interval: "monthly" },
});
```
### Subscriptions
```ts
await paystack.subscription_create({
body: { customer: "CUS_xxx", plan: "PLN_xxx" },
});
```
### Transfer Recipients
```ts
await paystack.transferrecipient_create({
body: {
type: "nuban",
name: "Ada Lovelace",
account_number: "0001234567",
bank_code: "057",
currency: "NGN",
},
});
```
### Transfers
```ts
await paystack.transfer_create({
body: { source: "balance", amount: 5000, recipient: "RCP_xxx", reason: "Vendor payout" },
});
```
### Transfers Control (OTP settings; under Transfers)
```ts
await paystack.transfer_enableOtp();
```
### Balance
```ts
const balance = await paystack.balance_fetch();
```
### Payment Requests (Invoices)
```ts
await paystack.paymentRequest_create({
body: { customer: "CUS_xxx", amount: 5000, description: "Consulting invoice" },
});
```
### Verification (Resolve Account / Validate Account / Resolve Card BIN)
```ts
await paystack.bank_resolveAccountNumber({
params: { query: { account_number: "0001234567", bank_code: "057" } },
});
```
### Products
```ts
await paystack.product_create({
body: { name: "T-shirt", description: "Cotton tee", price: 5000, currency: "NGN" },
});
```
### Storefronts
```ts
const storefronts = await paystack.storefront_list();
```
### Orders
```ts
await paystack.order_create({
body: { customer: "CUS_xxx", items: [] },
});
```
### Payment Pages
```ts
await paystack.page_create({
body: { name: "Event Ticket", amount: 5000, description: "Landing page for ticket sales" },
});
```
### Settlements
```ts
const settlements = await paystack.settlement_list();
```
### Integration
```ts
const timeout = await paystack.integration_fetchPaymentSessionTimeout();
```
### Control Panel (Payment session timeout; under Integration)
```ts
await paystack.integration_updatePaymentSessionTimeout({
body: { timeout: 20 },
});
```
### Refunds
```ts
await paystack.refund_create({
body: { transaction: 123456789, amount: 5000 },
});
```
### Disputes
```ts
const disputes = await paystack.dispute_list();
```
### Banks
```ts
const banks = await paystack.bank_list({ params: { query: { country: "nigeria" } } });
```
### Miscellaneous
```ts
const countries = await paystack.miscellaneous_listCountries();
```
## Related SDKs
- [@alexasomba/paystack-browser](https://github.com/alexasomba/paystack-browser) - Optimized for browser fetches.
- [@alexasomba/paystack-axios](https://github.com/alexasomba/paystack-axios) - For projects using Axios.
## Used By
- **[Better Auth Paystack Plugin](https://github.com/alexasomba/better-auth-paystack)**: A comprehensive Paystack plugin for Better Auth.
## Source
- Monorepo source: [alexasomba/paystack-openapi](https://github.com/alexasomba/paystack-openapi)
- Standalone SDK repo: [https://github.com/alexasomba/paystack-node](https://github.com/alexasomba/paystack-node)
## License
MIT