Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.usepaykit.dev/llms.txt

Use this file to discover all available pages before exploring further.

npm install @paykit-sdk/paystack

Setup

import { PayKit } from '@paykit-sdk/core';
import { paystack } from '@paykit-sdk/paystack';

export const paykit = new PayKit(paystack());
Required env vars:
PAYSTACK_SECRET_KEY=sk_test_...
PAYSTACK_WEBHOOK_SECRET=your-webhook-secret

How it works

Paystack uses an initialize-then-verify flow. createCheckout calls POST /transaction/initialize and returns an authorization_url. After payment, retrieve the transaction with retrievePayment(reference). Amounts are in the smallest currency unit (kobo for NGN).

Webhooks

Enable these events in your Paystack dashboard:
  • charge.success
  • charge.failed
  • customer.create
  • customeridentification.success
  • customeridentification.failed
  • subscription.create
  • subscription.not_renew
  • subscription.disable
  • invoice.create
  • invoice.update
  • invoice.payment_failed
  • refund.pending
  • refund.processed
  • refund.failed
Paystack signs webhooks with HMAC-SHA512 via the x-paystack-signature header.
const webhook = paykit.webhooks
  .setup({ webhookSecret: process.env.PAYSTACK_WEBHOOK_SECRET! })
  .on('payment.created', async event => { /* ... */ })
  .on('subscription.created', async event => { /* ... */ })
  .on('customer.created', async event => { /* ... */ })
  .on('invoice.generated', async event => { /* ... */ });

await webhook.handle({
  body: rawBody,
  headersAsObject: Object.fromEntries(request.headers),
  fullUrl: request.url,
});

Raw Paystack events

Opt into any native Paystack event — fully typed against Paystack’s API types:
paykit.webhooks
  .setup({ webhookSecret: process.env.PAYSTACK_WEBHOOK_SECRET! })
  .on('paystack.charge.success', async event => {
    // event.data is typed as PaystackTransaction
  })
  .on('paystack.subscription.create', async event => {
    // event.data is typed as PaystackSubscription
  })
  .on('paystack.refund.processed', async event => {
    // event.data is typed as PaystackRefund
  });
All available raw events:
EventData type
paystack.charge.successPaystackTransaction
paystack.charge.dispute.create/remind/resolvePaystackDispute
paystack.customeridentification.success/failedPaystackCustomerIdentification
paystack.dedicatedaccount.assign.success/failedPaystackDVAAssignment
paystack.invoice.create/update/payment_failedPaystackInvoice
paystack.paymentrequest.pending/successPaystackPaymentRequest
paystack.refund.failed/pending/processed/processingPaystackRefund
paystack.subscription.create/enable/disable/not_renewPaystackSubscription
paystack.transfer.success/failed/reversedPaystackTransfer

provider_metadata

// checkout.provider_metadata is typed as { amount?: number; currency?: string }
await paykit.checkouts.create({
  customer: { email: 'user@example.com' },
  item_id: 'PLN_abc123',
  session_type: 'one_time',
  quantity: 1,
  success_url: '...',
  cancel_url: '...',
  provider_metadata: {
    amount: 500000, // override amount in kobo
    currency: 'NGN',
  },
});

// refund.provider_metadata is typed as { merchant_note: string; customer_note: string }
await paykit.refunds.create({
  payment_id: 'ref_abc123',
  amount: 5000,
  provider_metadata: {
    merchant_note: 'Duplicate charge',
    customer_note: 'Sorry for the inconvenience',
  },
});