Skip to content

Latest commit

 

History

History
476 lines (357 loc) · 15.8 KB

File metadata and controls

476 lines (357 loc) · 15.8 KB

@alexasomba/paystack-browser

npm version license bundle size

Paystack API client optimized for browser environments, providing a lightweight, fully typed, and spec-compliant way to interact with the Paystack API via native fetch.

Features

  • Lightweight & Tree-shakeable: Only import what you use, optimized for modern frontend bundles.
  • Native Fetch: Uses standard browser fetch and AbortController.
  • 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.
  • Secure Idempotency: Automatically handles Idempotency-Key headers using browser-safe random generation.
  • Detailed Error Handling: PaystackApiError includes status, url, and Paystack requestId.

Install

pnpm add @alexasomba/paystack-browser

Use your Paystack public key in browser environments. Do not expose a secret key in frontend code.

const publicKey = "pk_test_...";

Quick Start

import { createPaystack, assertOk } from "@alexasomba/paystack-browser";

const paystack = createPaystack({
  secretKey: "pk_test_...",
  idempotencyKey: "auto",
});

const result = await paystack.transaction_initialize({
  body: {
    email: "customer@example.com",
    amount: 5000,
  },
});

const data = assertOk(result);
window.location.href = 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

Custom Fetch Implementation

Provide a custom fetch implementation when you need framework-specific instrumentation, tracing, or polyfills.

const paystack = createPaystack({
  secretKey: "pk_...",
  fetch: customFetchWrapper,
  timeoutMs: 15_000,
});

Handling Rate Limits

The SDK respects Paystack Retry-After headers automatically. Override retry statuses only when you want tighter browser-side behavior.

Stable Type Exports

This SDK exports stable grouped client slices and curated request/query/response aliases so downstream integrations do not need to reconstruct types from ReturnType<typeof createPaystack>, paths, or operations.

import {
  createPaystack,
  type Paystack,
  type PaystackTransactionClient,
  type PaystackSubscriptionClient,
  type TransactionInitializePayload,
  type TransactionChargeAuthorizationPayload,
  type SubscriptionCreatePayload,
  type SubscriptionListQueryParams,
  type RefundCreatePayload,
} from "@alexasomba/paystack-browser";

const paystack: Paystack = createPaystack({
  secretKey: "pk_test_...",
});

const transactionClient: PaystackTransactionClient = paystack.transaction;
const subscriptionClient: PaystackSubscriptionClient = paystack.subscription;

const tx: TransactionInitializePayload = {
  email: "customer@example.com",
  amount: 5000,
};

const chargeAuthorization: TransactionChargeAuthorizationPayload = {
  email: "customer@example.com",
  amount: 2500,
  authorization_code: "AUTH_123",
};

const subscriptionCreate: SubscriptionCreatePayload = {
  customer: "CUS_123",
  plan: "PLN_123",
};

const subscriptionList: SubscriptionListQueryParams = {
  customer: 123,
};

const refundCreate: RefundCreatePayload = {
  transaction: "TRX_123",
  amount: 1000,
};

Notable aliases include transaction initialize / charge authorization / verify; subscription create / list / disable / enable / fetch / manage link / manage email; customer fetch / create / update; plan list / create / update / fetch; product list / create / update / fetch; dispute list / fetch; refund create / fetch; payment request create / fetch; terminal send-event; and verification helpers for account resolution, account validation, and card BIN lookup.

Client slices include PaystackTransactionClient, PaystackCustomerClient, PaystackSubscriptionClient, PaystackPlanClient, PaystackProductClient, PaystackDisputeClient, and PaystackRefundClient.

Grouped methods reflect supported generated OpenAPI operations. Unsupported helpers such as subscription.update are intentionally not part of the public SDK surface.

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.
const paystack = createPaystack({
  secretKey: "pk_...",
  retry: {
    retries: 2,
    retryOnStatuses: [429],
  },
});

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

const tx = await paystack.transaction_initialize({
  body: { email: "customer@example.com", amount: 5000 },
});

Verify Payments (Transaction verification)

const verified = await paystack.transaction_verify({
  params: { path: { reference: "ref_123" } },
});

Charges

await paystack.charge_create({
  body: {
    email: "customer@example.com",
    amount: 5000,
    bank: { code: "057", account_number: "0001234567" },
  },
});

Bulk Charges

await paystack.bulkCharge_initiate({
  body: [{ authorization: "AUTH_xxx", amount: 5000, reference: "bulk-ref-1" }],
});

Subaccounts

await paystack.subaccount_create({
  body: {
    business_name: "Acme Stores",
    settlement_bank: "057",
    account_number: "0001234567",
    percentage_charge: 10,
  },
});

Transaction Splits

await paystack.split_create({
  body: { name: "Main split", type: "percentage", currency: "NGN", subaccounts: [] },
});

Terminal

const terminals = await paystack.terminal_list();

Virtual Terminal

await paystack.virtualTerminal_create({
  body: { name: "Web checkout terminal" },
});

Customers

await paystack.customer_create({
  body: { email: "customer@example.com", first_name: "Ada", last_name: "Lovelace" },
});

Direct Debit

await paystack.directdebit_initialize({
  body: { email: "customer@example.com", amount: 5000, bank_code: "057" },
});

Dedicated Virtual Accounts

await paystack.dedicatedAccount_assign({
  body: { customer: 12345, preferred_bank: "wema-bank" },
});

Apple Pay

await paystack.applePay_registerDomain({
  body: { domainName: "example.com" },
});

Plans

await paystack.plan_create({
  body: { name: "Starter", amount: 500000, interval: "monthly" },
});

Subscriptions

await paystack.subscription_create({
  body: { customer: "CUS_xxx", plan: "PLN_xxx" },
});

Transfer Recipients

await paystack.transferrecipient_create({
  body: {
    type: "nuban",
    name: "Ada Lovelace",
    account_number: "0001234567",
    bank_code: "057",
    currency: "NGN",
  },
});

Transfers

await paystack.transfer_create({
  body: { source: "balance", amount: 5000, recipient: "RCP_xxx", reason: "Vendor payout" },
});

Transfers Control (OTP settings; under Transfers)

await paystack.transfer_enableOtp();

Balance

const balance = await paystack.balance_fetch();

Payment Requests (Invoices)

await paystack.paymentRequest_create({
  body: { customer: "CUS_xxx", amount: 5000, description: "Consulting invoice" },
});

Verification (Resolve Account / Validate Account / Resolve Card BIN)

await paystack.bank_resolveAccountNumber({
  params: { query: { account_number: "0001234567", bank_code: "057" } },
});

Products

await paystack.product_create({
  body: { name: "T-shirt", description: "Cotton tee", price: 5000, currency: "NGN" },
});

Storefronts

const storefronts = await paystack.storefront_list();

Orders

await paystack.order_create({
  body: { customer: "CUS_xxx", items: [] },
});

Payment Pages

await paystack.page_create({
  body: { name: "Event Ticket", amount: 5000, description: "Landing page for ticket sales" },
});

Settlements

const settlements = await paystack.settlement_list();

Integration

const timeout = await paystack.integration_fetchPaymentSessionTimeout();

Control Panel (Payment session timeout; under Integration)

await paystack.integration_updatePaymentSessionTimeout({
  body: { timeout: 20 },
});

Refunds

await paystack.refund_create({
  body: { transaction: 123456789, amount: 5000 },
});

Disputes

const disputes = await paystack.dispute_list();

Banks

const banks = await paystack.bank_list({ params: { query: { country: "nigeria" } } });

Miscellaneous

const countries = await paystack.miscellaneous_listCountries();

Related SDKs

Used By

Source

License

MIT