Overview
The Webhook class provides a secure, type-safe way to handle webhook events from Paystack. It automatically verifies webhook signatures, parses event payloads, and routes events to registered handlers.Key Features
- Automatic signature verification using HMAC SHA-512
- Type-safe event handlers with full TypeScript support
- Event-driven architecture with chainable
.on()method - Platform-agnostic works with Express, Next.js, Hono, and more
- Zod validation for runtime type safety
Methods
on
Registers a handler function for a specific webhook event. This method is chainable, allowing you to register multiple handlers at once.Parameters
The event type to listen for. See Supported Events below
The function to execute when the event is received. The function receives the event data as its parameter and can be async
Returns
Returns the Webhook instance for chaining.process
Processes an incoming webhook request by verifying the signature, parsing the payload, and dispatching it to the appropriate handler.Parameters
The raw, unparsed request body as a string. Important: Do not parse the JSON before passing it to this method, as the signature verification requires the raw body
The value of the
x-paystack-signature header from the webhook requestReturns
Returns a Promise that resolves to the parsed webhook payload if successful.Throws
Error("Missing 'x-paystack-signature' header")- If the signature header is missingError("Invalid webhook signature")- If the signature verification failsError("Failed to parse webhook payload")- If the payload doesn’t match the expected schema
Supported Events
The SDK supports all Paystack webhook events with full TypeScript types:Charge Events
charge.success
charge.success
Triggered when a charge is successful.Handler data includes:
reference- Transaction referenceamount- Amount in kobocustomer- Customer details (email, name, etc.)authorization- Card/payment authorization detailsmetadata- Custom metadata
charge.dispute.create
charge.dispute.create
Triggered when a dispute is created on a charge.Handler data includes:
id- Dispute IDtransaction- Full transaction detailscustomer- Customer detailsstatus- Dispute status
charge.dispute.remind
charge.dispute.remind
Triggered to remind you of a pending dispute.
charge.dispute.resolve
charge.dispute.resolve
Triggered when a dispute is resolved.
Transfer Events
transfer.success
transfer.success
Triggered when a transfer is successful.Handler data includes:
reference- Transfer referenceamount- Transfer amountrecipient- Recipient detailsstatus- Transfer status
transfer.failed
transfer.failed
Triggered when a transfer fails.
transfer.reversed
transfer.reversed
Triggered when a transfer is reversed.
Subscription Events
subscription.create
subscription.create
Triggered when a subscription is created.Handler data includes:
subscription_code- Unique subscription codeplan- Plan detailscustomer- Customer detailsauthorization- Payment authorization
subscription.disable
subscription.disable
Triggered when a subscription is disabled.
subscription.not_renew
subscription.not_renew
Triggered when a subscription will not renew.
subscription.expiring_cards
subscription.expiring_cards
Triggered to alert about expiring cards on subscriptions. Returns an array of subscriptions with expiring cards.
Invoice Events
invoice.create
invoice.create
Triggered when an invoice is created.
invoice.update
invoice.update
Triggered when an invoice is updated.
invoice.payment_failed
invoice.payment_failed
Triggered when an invoice payment fails.
Refund Events
refund.pending
refund.pending
Triggered when a refund is pending.
refund.processing
refund.processing
Triggered when a refund is being processed.
refund.processed
refund.processed
Triggered when a refund has been processed.
refund.failed
refund.failed
Triggered when a refund fails.
Other Events
dedicatedaccount.assign.success
dedicatedaccount.assign.success
Triggered when a dedicated virtual account is successfully assigned to a customer.
dedicatedaccount.assign.failed
dedicatedaccount.assign.failed
Triggered when dedicated virtual account assignment fails.
customeridentification.success
customeridentification.success
Triggered when customer identification is successful.
customeridentification.failed
customeridentification.failed
Triggered when customer identification fails.
paymentrequest.pending
paymentrequest.pending
Triggered when a payment request is pending.
paymentrequest.success
paymentrequest.success
Triggered when a payment request is successful.
Security
Signature Verification
The SDK automatically verifies webhook signatures using HMAC SHA-512. This ensures that webhooks are genuinely from Paystack and haven’t been tampered with.Best Practices
Always use the raw request body
Always use the raw request body
The signature is computed against the raw request body. Parse the body to JSON only after verification fails.
Use environment variables for secrets
Use environment variables for secrets
Never hardcode your Paystack secret key.
Implement idempotency
Implement idempotency
Paystack may send the same webhook multiple times. Use the event’s reference/ID to prevent duplicate processing.
Return 200 quickly
Return 200 quickly
Process webhooks quickly or queue them for background processing. Paystack expects a 200 response within a reasonable time.
Error Handling
Handle webhook processing errors gracefully:Testing Webhooks
Using Paystack Test Mode
- Use your test secret key to initialize the SDK
- Make a test transaction on your staging/test environment
- Paystack will send webhooks to your configured endpoint

