{"id":44833008,"url":"https://github.com/alexasomba/paystack-node","last_synced_at":"2026-04-16T09:05:43.615Z","repository":{"id":336076589,"uuid":"1148087422","full_name":"alexasomba/paystack-node","owner":"alexasomba","description":"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.","archived":false,"fork":false,"pushed_at":"2026-04-16T07:45:47.000Z","size":6407,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-16T08:38:58.971Z","etag":null,"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"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexasomba.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-02T15:06:21.000Z","updated_at":"2026-04-16T07:29:21.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/alexasomba/paystack-node","commit_stats":null,"previous_names":["alexasomba/paystack-node"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/alexasomba/paystack-node","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexasomba%2Fpaystack-node","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexasomba%2Fpaystack-node/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexasomba%2Fpaystack-node/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexasomba%2Fpaystack-node/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexasomba","download_url":"https://codeload.github.com/alexasomba/paystack-node/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexasomba%2Fpaystack-node/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31878856,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-16T07:36:03.521Z","status":"ssl_error","status_checked_at":"2026-04-16T07:35:53.576Z","response_time":69,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["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"],"created_at":"2026-02-17T00:35:26.072Z","updated_at":"2026-04-16T09:05:43.607Z","avatar_url":"https://github.com/alexasomba.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @alexasomba/paystack-node\n\n[![npm version](https://img.shields.io/npm/v/@alexasomba/paystack-node.svg)](https://www.npmjs.com/package/@alexasomba/paystack-node)\n[![license](https://img.shields.io/npm/l/@alexasomba/paystack-node.svg)](https://github.com/alexasomba/paystack-node/blob/main/LICENSE)\n[![bundle size](https://img.shields.io/bundlephobia/minzip/@alexasomba/paystack-node)](https://bundlephobia.com/package/@alexasomba/paystack-node)\n\nTypeScript-first Paystack API client for Node.js, generated from the official Paystack OpenAPI spec.\n\n## Features\n\n- **Spec-driven Accuracy**: Generated directly from the Paystack OpenAPI specification.\n- **100% Type-safe**: Full TypeScript support with generated types for every endpoint, request, and response.\n- **Smart Retries**: Automatic retries for transient failures with exponential backoff and jitter.\n- **Retry-After Compliance**: Automatically respects Paystack `Retry-After` headers on rate limit responses.\n- **Sophisticated Idempotency**: Built-in support for manual, static, or automatic UUID-based idempotency keys on POST requests.\n- **Detailed Error Handling**: `PaystackApiError` includes `status`, `url`, and Paystack `requestId`.\n- **Webhook Verification**: Timing-safe webhook signature verification helper included.\n\n## Install\n\n```bash\npnpm add @alexasomba/paystack-node\n```\n\nAuthenticate requests with your Paystack secret key:\n\n```ts\nprocess.env.PAYSTACK_SECRET_KEY = \"sk_test_...\";\n```\n\n## Quick Start\n\n```ts\nimport { createPaystack, assertOk } from \"@alexasomba/paystack-node\";\n\nconst paystack = createPaystack({\n  secretKey: process.env.PAYSTACK_SECRET_KEY!,\n  idempotencyKey: \"auto\",\n});\n\nconst result = await paystack.transaction_initialize({\n  body: {\n    email: \"customer@example.com\",\n    amount: 5000,\n  },\n});\n\nconst data = assertOk(result);\nconsole.log(data.authorization_url);\n```\n\n`assertOk` returns the successful Paystack payload and throws a structured `PaystackApiError` for non-2xx responses.\n\n## API Basics\n\n- Base URL: `https://api.paystack.co`\n- HTTPS is required for all requests.\n- Requests and responses are JSON-based.\n- Most successful responses follow the `status`, `message`, `data`, and optional `meta` envelope described in `Paystack-API/0a-Introduction.md`.\n- Amounts are usually sent in currency subunits such as kobo, pesewas, or cents. Check the module docs for currency-specific rules.\n\n## Authentication \u0026 Environments\n\n- Server-side SDKs should use your secret key (`sk_test_*` or `sk_live_*`).\n- Browser SDKs should use only your public key (`pk_test_*` or `pk_live_*`).\n- Send server-side API credentials as `Authorization: Bearer YOUR_SECRET_KEY`.\n- Test and live modes use different keys and isolated environments.\n- Rotate keys if they are exposed, and never commit secret keys to source control.\n- If you enable IP whitelisting in Paystack, requests from non-whitelisted IPs will be blocked.\n\n## Advanced Configuration\n\nThe `createPaystack` helper accepts `PaystackClientOptions`:\n\n```ts\nconst paystack = createPaystack({\n  secretKey: \"sk_...\",\n  timeoutMs: 30_000,\n  retry: {\n    retries: 3,\n    minDelayMs: 500,\n    retryOnStatuses: [429, 500, 503],\n  },\n  idempotencyKey: \"auto\",\n  headers: {\n    \"X-My-App\": \"v1.0.0\",\n  },\n});\n```\n\n### Webhooks\n\nUse the webhook helper when validating server-to-server events from Paystack. Pass the raw request body, not a parsed JSON object.\n\n```ts\nimport { verifyPaystackWebhookSignature } from \"@alexasomba/paystack-node/webhooks\";\n\nconst isValid = verifyPaystackWebhookSignature({\n  rawBody: req.body,\n  signature: req.headers[\"x-paystack-signature\"],\n  secret: process.env.PAYSTACK_SECRET_KEY!,\n});\n```\n\n### Handling Pagination\n\nList endpoints expose pagination controls through query params like `perPage`, `page`, `next`, and `previous`. Response headers are still available when you need manual pagination control.\n\n## Pagination\n\n- Paystack supports both offset pagination and cursor pagination.\n- Offset pagination uses `page` and `perPage`.\n- Cursor pagination uses `use_cursor=true` plus `next` or `previous` cursors returned in `meta`.\n- Cursor pagination is especially useful for large or frequently changing datasets.\n- The exact `meta` shape varies by endpoint and pagination mode.\n\n```ts\nconst result = await paystack.customer_list({ query: { perPage: 20 } });\nconst customers = assertOk(result);\nconst total = result.response.headers.get(\"x-total-count\");\n```\n\n## Error Handling\n\n```ts\nimport { toPaystackApiError } from \"@alexasomba/paystack-node\";\n\nconst result = await paystack.transaction_initialize({\n  /* ... */\n});\nconst error = toPaystackApiError(result);\n\nif (error) {\n  console.error(`Status ${error.status}: ${error.message}`);\n  console.error(`Paystack Request ID: ${error.requestId}`);\n}\n```\n\nThe `requestId` is useful when correlating logs or escalating an issue with Paystack support.\n\n## Errors\n\n- Paystack uses conventional HTTP status codes such as `200`, `201`, `400`, `401`, `404`, and `5xx`.\n- Error responses typically include `status`, `message`, `type`, `code`, and optional diagnostic `meta` information.\n- Error types described in `Paystack-API/0d-Errors.md` include `api_error`, `validation_error`, and `processor_error`.\n- For charge and verify flows, always inspect the returned response body and status fields, not just the HTTP code.\n\n## Coverage\n\nThis 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.\n\n## Modules\n\nFor this SDK, these schema families are exposed through generated TypeScript types in `src/openapi-types.ts` and operation helpers in `src/operations.ts`.\n\n| Module                                                               | Schema / model family                                    |\n| -------------------------------------------------------------------- | -------------------------------------------------------- |\n| Transactions                                                         | `Transaction*`                                           |\n| Verify Payments (Transaction verification)                           | `VerifyResponse / TransactionFetchResponse`              |\n| Charges                                                              | `Charge*`                                                |\n| Bulk Charges                                                         | `BulkCharge*`                                            |\n| Subaccounts                                                          | `Subaccount*`                                            |\n| Transaction Splits                                                   | `Split*`                                                 |\n| Terminal                                                             | `Terminal*`                                              |\n| Virtual Terminal                                                     | `VirtualTerminal*`                                       |\n| Customers                                                            | `Customer*`                                              |\n| Direct Debit                                                         | `DirectDebit*`                                           |\n| Dedicated Virtual Accounts                                           | `DedicatedNuban* / DedicatedVirtualAccount*`             |\n| Apple Pay                                                            | `ApplePay*`                                              |\n| Plans                                                                | `Plan*`                                                  |\n| Subscriptions                                                        | `Subscription*`                                          |\n| Transfer Recipients                                                  | `TransferRecipient*`                                     |\n| Transfers                                                            | `Transfer*`                                              |\n| Transfers Control (OTP settings; under Transfers)                    | `TransferEnable* / TransferDisable* / TransferFinalize*` |\n| Balance                                                              | `Balance*`                                               |\n| Payment Requests (Invoices)                                          | `PaymentRequest*`                                        |\n| Verification (Resolve Account / Validate Account / Resolve Card BIN) | `Verification*`                                          |\n| Products                                                             | `Product*`                                               |\n| Storefronts                                                          | `Storefront*`                                            |\n| Orders                                                               | `Order*`                                                 |\n| Payment Pages                                                        | `Page*`                                                  |\n| Settlements                                                          | `Settlement*`                                            |\n| Integration                                                          | `Integration*`                                           |\n| Control Panel (Payment session timeout; under Integration)           | `ControlPanel*`                                          |\n| Refunds                                                              | `Refund*`                                                |\n| Disputes                                                             | `Dispute*`                                               |\n| Banks                                                                | `Bank*`                                                  |\n| Miscellaneous                                                        | `Miscellaneous* / Currency`                              |\n\n## Module Examples\n\nThese 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`.\n\n### Transactions\n\n```ts\nconst tx = await paystack.transaction_initialize({\n  body: { email: \"customer@example.com\", amount: 5000 },\n});\n```\n\n### Verify Payments (Transaction verification)\n\n```ts\nconst verified = await paystack.transaction_verify({\n  params: { path: { reference: \"ref_123\" } },\n});\n```\n\n### Charges\n\n```ts\nawait paystack.charge_create({\n  body: {\n    email: \"customer@example.com\",\n    amount: 5000,\n    bank: { code: \"057\", account_number: \"0001234567\" },\n  },\n});\n```\n\n### Bulk Charges\n\n```ts\nawait paystack.bulkCharge_initiate({\n  body: [{ authorization: \"AUTH_xxx\", amount: 5000, reference: \"bulk-ref-1\" }],\n});\n```\n\n### Subaccounts\n\n```ts\nawait paystack.subaccount_create({\n  body: {\n    business_name: \"Acme Stores\",\n    settlement_bank: \"057\",\n    account_number: \"0001234567\",\n    percentage_charge: 10,\n  },\n});\n```\n\n### Transaction Splits\n\n```ts\nawait paystack.split_create({\n  body: { name: \"Main split\", type: \"percentage\", currency: \"NGN\", subaccounts: [] },\n});\n```\n\n### Terminal\n\n```ts\nconst terminals = await paystack.terminal_list();\n```\n\n### Virtual Terminal\n\n```ts\nawait paystack.virtualTerminal_create({\n  body: { name: \"Web checkout terminal\" },\n});\n```\n\n### Customers\n\n```ts\nawait paystack.customer_create({\n  body: { email: \"customer@example.com\", first_name: \"Ada\", last_name: \"Lovelace\" },\n});\n```\n\n### Direct Debit\n\n```ts\nawait paystack.directdebit_initialize({\n  body: { email: \"customer@example.com\", amount: 5000, bank_code: \"057\" },\n});\n```\n\n### Dedicated Virtual Accounts\n\n```ts\nawait paystack.dedicatedAccount_assign({\n  body: { customer: 12345, preferred_bank: \"wema-bank\" },\n});\n```\n\n### Apple Pay\n\n```ts\nawait paystack.applePay_registerDomain({\n  body: { domainName: \"example.com\" },\n});\n```\n\n### Plans\n\n```ts\nawait paystack.plan_create({\n  body: { name: \"Starter\", amount: 500000, interval: \"monthly\" },\n});\n```\n\n### Subscriptions\n\n```ts\nawait paystack.subscription_create({\n  body: { customer: \"CUS_xxx\", plan: \"PLN_xxx\" },\n});\n```\n\n### Transfer Recipients\n\n```ts\nawait paystack.transferrecipient_create({\n  body: {\n    type: \"nuban\",\n    name: \"Ada Lovelace\",\n    account_number: \"0001234567\",\n    bank_code: \"057\",\n    currency: \"NGN\",\n  },\n});\n```\n\n### Transfers\n\n```ts\nawait paystack.transfer_create({\n  body: { source: \"balance\", amount: 5000, recipient: \"RCP_xxx\", reason: \"Vendor payout\" },\n});\n```\n\n### Transfers Control (OTP settings; under Transfers)\n\n```ts\nawait paystack.transfer_enableOtp();\n```\n\n### Balance\n\n```ts\nconst balance = await paystack.balance_fetch();\n```\n\n### Payment Requests (Invoices)\n\n```ts\nawait paystack.paymentRequest_create({\n  body: { customer: \"CUS_xxx\", amount: 5000, description: \"Consulting invoice\" },\n});\n```\n\n### Verification (Resolve Account / Validate Account / Resolve Card BIN)\n\n```ts\nawait paystack.bank_resolveAccountNumber({\n  params: { query: { account_number: \"0001234567\", bank_code: \"057\" } },\n});\n```\n\n### Products\n\n```ts\nawait paystack.product_create({\n  body: { name: \"T-shirt\", description: \"Cotton tee\", price: 5000, currency: \"NGN\" },\n});\n```\n\n### Storefronts\n\n```ts\nconst storefronts = await paystack.storefront_list();\n```\n\n### Orders\n\n```ts\nawait paystack.order_create({\n  body: { customer: \"CUS_xxx\", items: [] },\n});\n```\n\n### Payment Pages\n\n```ts\nawait paystack.page_create({\n  body: { name: \"Event Ticket\", amount: 5000, description: \"Landing page for ticket sales\" },\n});\n```\n\n### Settlements\n\n```ts\nconst settlements = await paystack.settlement_list();\n```\n\n### Integration\n\n```ts\nconst timeout = await paystack.integration_fetchPaymentSessionTimeout();\n```\n\n### Control Panel (Payment session timeout; under Integration)\n\n```ts\nawait paystack.integration_updatePaymentSessionTimeout({\n  body: { timeout: 20 },\n});\n```\n\n### Refunds\n\n```ts\nawait paystack.refund_create({\n  body: { transaction: 123456789, amount: 5000 },\n});\n```\n\n### Disputes\n\n```ts\nconst disputes = await paystack.dispute_list();\n```\n\n### Banks\n\n```ts\nconst banks = await paystack.bank_list({ params: { query: { country: \"nigeria\" } } });\n```\n\n### Miscellaneous\n\n```ts\nconst countries = await paystack.miscellaneous_listCountries();\n```\n\n## Related SDKs\n\n- [@alexasomba/paystack-browser](https://github.com/alexasomba/paystack-browser) - Optimized for browser fetches.\n- [@alexasomba/paystack-axios](https://github.com/alexasomba/paystack-axios) - For projects using Axios.\n\n## Used By\n\n- **[Better Auth Paystack Plugin](https://github.com/alexasomba/better-auth-paystack)**: A comprehensive Paystack plugin for Better Auth.\n\n## Source\n\n- Monorepo source: [alexasomba/paystack-openapi](https://github.com/alexasomba/paystack-openapi)\n- Standalone SDK repo: [https://github.com/alexasomba/paystack-node](https://github.com/alexasomba/paystack-node)\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexasomba%2Fpaystack-node","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexasomba%2Fpaystack-node","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexasomba%2Fpaystack-node/lists"}