Paystack Integration
import { Aside, Tabs, TabItem, Steps } from ‘@astrojs/starlight/components’;
Paystack is one of Africa’s leading payment processors, supporting businesses in Nigeria, Ghana, South Africa, and Kenya. This guide covers how to integrate Paystack payments using Voltax.
Prerequisites
Section titled “Prerequisites”Before you begin, you’ll need:
- A Paystack account (sign up at paystack.com)
- Your Paystack secret key (found in Settings → API Keys & Webhooks)
Configuration
Section titled “Configuration”Initialize Voltax with your Paystack credentials:
import Voltax from '@noelzappy/voltax';
const voltax = new Voltax({ paystack: { secretKey: process.env.PAYSTACK_SECRET_KEY!, },});Initialize a Payment
Section titled “Initialize a Payment”Basic Payment
Section titled “Basic Payment”import { Currency } from '@noelzappy/voltax';
const payment = await voltax.paystack.initializePayment({ amount: 5000, // 5,000 NGN (Voltax handles kobo conversion) email: 'customer@example.com', currency: Currency.NGN, reference: `txn-${Date.now()}`, callbackUrl: 'https://yoursite.com/payment/callback',});
// Redirect customer to complete paymentconsole.log(payment.authorizationUrl);// "https://checkout.paystack.com/xxxxxxxxxx"With Metadata
Section titled “With Metadata”Attach custom data to track orders and customers:
const payment = await voltax.paystack.initializePayment({ amount: 15000, email: 'customer@example.com', currency: Currency.NGN, description: 'Order #12345', metadata: { orderId: 'ORD-12345', customerId: 'CUST-67890', items: ['Product A', 'Product B'], cart_id: 398, },});Paystack-Specific Options
Section titled “Paystack-Specific Options”Paystack supports several advanced options through the options.paystack field:
Payment Channels
Section titled “Payment Channels”Limit which payment methods customers can use:
import { PaystackChannel } from '@noelzappy/voltax';
const payment = await voltax.paystack.initializePayment({ amount: 5000, email: 'customer@example.com', currency: Currency.NGN, options: { paystack: { channels: [ PaystackChannel.CARD, PaystackChannel.BANK_TRANSFER, PaystackChannel.USSD, ], }, },});Available Channels:
| Channel | Value | Description |
|---|---|---|
CARD | "card" | Debit/Credit cards |
BANK | "bank" | Pay with bank account |
BANK_TRANSFER | "bank_transfer" | Bank transfer |
USSD | "ussd" | USSD payment |
QR | "qr" | QR code payment |
MOBILE_MONEY | "mobile_money" | Mobile money (Ghana) |
EFT | "eft" | Electronic Funds Transfer (South Africa) |
APPLE_PAY | "apple_pay" | Apple Pay |
PAYATTITUDE | "payattitude" | PayAttitude |
Split Payments
Section titled “Split Payments”Split payments between accounts using subaccounts or split codes:
const payment = await voltax.paystack.initializePayment({ amount: 10000, email: 'customer@example.com', currency: Currency.NGN, options: { paystack: { // Use a subaccount subaccount: 'ACCT_xxxxxxxxxx',
// Or use a split code for multi-party splits splitCode: 'SPL_xxxxxxxxxx',
// Who bears the transaction charge bearer: 'subaccount', // or 'account'
// Additional charge to add (in kobo) transactionCharge: 10000, // ₦100 extra }, },});Subscription Payments
Section titled “Subscription Payments”For recurring payments with Paystack Plans:
const payment = await voltax.paystack.initializePayment({ amount: 5000, email: 'customer@example.com', currency: Currency.NGN, options: { paystack: { plan: 'PLN_xxxxxxxxxx', // Limit number of subscription invoices invoiceLimit: 12, // 12 months }, },});Complete Options Reference
Section titled “Complete Options Reference”interface PaystackOptions { // Limit payment channels channels?: PaystackChannel[];
// Subaccount for split payments subaccount?: string;
// Split code for multi-party splits splitCode?: string;
// Who bears Paystack fees: 'account' (you) or 'subaccount' bearer?: 'account' | 'subaccount';
// Flat fee to charge on transaction (in kobo) transactionCharge?: number;
// Subscription plan code plan?: string;
// Max number of subscription charges invoiceLimit?: number;}Verify a Transaction
Section titled “Verify a Transaction”After the customer completes payment, verify the transaction:
import { PaymentStatus } from '@noelzappy/voltax';
const result = await voltax.paystack.verifyTransaction('txn-123456');
console.log(result);// {// status: 'SUCCESS',// reference: 'txn-123456',// externalReference: '1234567890',// raw: { ... }// }
if (result.status === PaymentStatus.SUCCESS) { // Payment successful - fulfill order const amount = result.raw.data.amount / 100; // Convert from kobo console.log(`Received ₦${amount}`);}Status Mapping
Section titled “Status Mapping”Voltax maps Paystack statuses to standardized values:
| Paystack Status | Voltax Status |
|---|---|
success | SUCCESS |
failed | FAILED |
reversed | FAILED |
abandoned | FAILED |
| Other | PENDING |
Get Payment Status
Section titled “Get Payment Status”For a quick status check:
const status = await voltax.paystack.getPaymentStatus('txn-123456');
if (status === PaymentStatus.SUCCESS) { console.log('Payment successful!');}Complete Example
Section titled “Complete Example”Here’s a full Express.js integration example:
import express from 'express';import Voltax, { Currency, PaymentStatus, PaystackChannel } from '@noelzappy/voltax';
const app = express();app.use(express.json());
const voltax = new Voltax({ paystack: { secretKey: process.env.PAYSTACK_SECRET_KEY! },});
// Initialize paymentapp.post('/api/payments/initialize', async (req, res) => { try { const { amount, email, orderId } = req.body;
const payment = await voltax.paystack.initializePayment({ amount, email, currency: Currency.NGN, reference: `order-${orderId}-${Date.now()}`, callbackUrl: `${process.env.BASE_URL}/payment/callback`, description: `Payment for Order #${orderId}`, metadata: { orderId }, options: { paystack: { channels: [ PaystackChannel.CARD, PaystackChannel.BANK_TRANSFER, ], }, }, });
res.json({ success: true, checkoutUrl: payment.authorizationUrl, reference: payment.reference, }); } catch (error) { res.status(400).json({ success: false, error: error.message }); }});
// Payment callbackapp.get('/payment/callback', async (req, res) => { const { reference } = req.query;
try { const result = await voltax.paystack.verifyTransaction(reference as string);
if (result.status === PaymentStatus.SUCCESS) { // Mark order as paid in your database res.redirect('/order/success'); } else { res.redirect('/order/failed'); } } catch (error) { res.redirect('/order/error'); }});
app.listen(3000);Supported Currencies
Section titled “Supported Currencies”| Currency | Code | Country |
|---|---|---|
| Nigerian Naira | NGN | Nigeria |
| Ghanaian Cedi | GHS | Ghana |
| South African Rand | ZAR | South Africa |
| Kenyan Shilling | KES | Kenya |
| US Dollar | USD | International |
Next Steps
Section titled “Next Steps”- Learn about Error Handling for Paystack errors
- Explore the API Reference for PaystackAdapter
- Set up Webhook handling for real-time notifications