Skip to content

Paystack Integration with EasySwitch

Overview

Paystack is a leading African payment gateway powered by Stripe, serving businesses in Nigeria, Ghana, and across the continent. It supports card payments, mobile money, USSD, bank transfer, and more. EasySwitch wraps Paystack's transaction initialization and verification APIs behind a unified interface.

Prerequisites

  • EasySwitch installed (see Installation)
  • A Paystack account with your secret key (from the Paystack dashboard)
  • Your secret key (starts with sk_) for API authentication

Supported Features

Feature Paystack Support
Payment Initialization ✅ via send_payment()
Status Verification ✅ via check_status()
Transaction Details ✅ via get_transaction_detail()
Refunds ✅ Full & partial via refund()
Cancellation ❌ Not supported (use refund for reversals)
Webhook Validation ✅ HMAC-SHA512 signature
Webhook Parsing ✅ Standardized WebhookEvent

Supported Currencies

Currency Code Min Max
Nigerian Naira NGN 50.00 10,000,000
Ghanaian Cedi GHS 0.10 10,000,000
US Dollar USD 2.00 10,000,000

Setup & Configuration

Minimal Configuration

from easyswitch import EasySwitch, Provider

config = {
    "providers": {
        Provider.PAYSTACK: {
            "api_key": "sk_live_your_paystack_secret_key",
            "callback_url": "https://your-site.com/webhook/paystack",
            "environment": "sandbox",  # or "production"
        }
    },
    "default_provider": Provider.PAYSTACK,
}

client = EasySwitch.from_dict(config)

Environment Variables (.env)

EASYSWITCH_ENABLED_PROVIDERS=paystack
EASYSWITCH_DEFAULT_PROVIDER=paystack
EASYSWITCH_PAYSTACK_API_KEY=sk_live_your_paystack_secret_key
EASYSWITCH_PAYSTACK_CALLBACK_URL=https://your-site.com/webhook/paystack
EASYSWITCH_PAYSTACK_ENVIRONMENT=sandbox
client = EasySwitch.from_env()

JSON Configuration

{
    "default_provider": "PAYSTACK",
    "providers": {
        "PAYSTACK": {
            "api_key": "sk_live_your_paystack_secret_key",
            "callback_url": "https://your-site.com/webhook/paystack",
            "environment": "sandbox"
        }
    }
}
client = EasySwitch.from_json("config.json")

API Methods

1. Initialize a Payment

Paystack payments are two-step: you first initialize a transaction (getting a payment link), then the customer completes payment on Paystack's checkout page.

from easyswitch import (
    TransactionDetail, Currency, TransactionStatus,
    TransactionType, CustomerInfo, Provider
)

transaction = TransactionDetail(
    transaction_id="order-20240704-001",
    provider=Provider.PAYSTACK,
    amount=5000.00,        # Amount in major units (NGN)
    currency=Currency.NGN,
    customer=CustomerInfo(
        email="customer@example.com",   # Required by Paystack
        phone_number="+2348012345678",
        first_name="John",
        last_name="Doe",
    ),
    reason="Premium Plan Purchase",
    callback_url="https://your-site.com/webhook/paystack",
    metadata={"order_id": "ORD-12345"},
)

response = client.send_payment(transaction)

print(f"Paystack Transaction ID: {response.transaction_id}")
print(f"Payment Link (send to customer): {response.payment_link}")
print(f"Access Code: {response.transaction_token}")
print(f"Status: {response.status}")

Response highlights: - response.payment_link: Redirect the customer to this URL - response.transaction_token: Access code for the transaction - response.reference: Paystack transaction reference (used for verification)

2. Verify Transaction Status

After the customer completes (or abandons) payment, verify the status:

reference = "paystack_ref_123"  # From the payment response
status_response = client.check_status(reference)

print(f"Status: {status_response.status}")
print(f"Amount: {status_response.amount}")

if status_response.status == TransactionStatus.SUCCESSFUL:
    print("Payment completed — fulfill the order!")
elif status_response.status == TransactionStatus.FAILED:
    print("Payment failed")
elif status_response.status == TransactionStatus.PENDING:
    print("Payment still pending")

3. Get Transaction Details

Retrieve full transaction details from Paystack by transaction ID:

detail = client.get_transaction_detail("paystack_tx_id")
print(f"Customer: {detail.customer.email}")
print(f"Reference: {detail.reference}")
print(f"Paid at: {detail.completed_at}")

4. Refund a Transaction

Paystack supports both full and partial refunds:

# Full refund
refund_response = client.refund(transaction_id="paystack_ref_123")
print(f"Refund status: {refund_response.status}")

# Partial refund
partial_refund = client.refund(
    transaction_id="paystack_ref_123",
    amount=2500.00,  # Partial amount
    reason="Customer requested partial refund",
)

5. Cancellation

# Paystack does not support API cancellation
try:
    client.cancel_transaction("tx_ref")
except UnsupportedOperationError as e:
    print(f"Cancellation not supported: {e}")
    # Use refund instead

Webhook Management

Paystack sends webhooks for transaction events. EasySwitch validates them using HMAC-SHA512.

Webhook Endpoint

from flask import Flask, request, jsonify

app = Flask(__name__)
client = EasySwitch.from_env()

@app.route("/webhook/paystack", methods=["POST"])
def paystack_webhook():
    payload = request.get_json()
    headers = dict(request.headers)

    # Parse & validate in one call (signature checked automatically)
    event = client.parse_webhook(
        payload=payload,
        headers=headers,
        provider=Provider.PAYSTACK,
    )

    # Handle event
    if event.event_type == "charge.success":
        print(f"Payment {event.transaction_id} succeeded: {event.amount} {event.currency}")
        # Fulfill order…

    return jsonify({"status": "ok"}), 200

Status Mapping

Paystack Status EasySwitch Status Meaning
success SUCCESSFUL Payment completed
failed FAILED Payment failed
abandoned CANCELLED Customer abandoned
pending PENDING Awaiting confirmation
refund REFUNDED Transaction refunded

Complete Example

from easyswitch import (
    EasySwitch, Provider, TransactionDetail,
    Currency, TransactionStatus, CustomerInfo,
)
from easyswitch.exceptions import PaymentError

# 1. Initialize
client = EasySwitch.from_env()

# 2. Create transaction
tx = TransactionDetail(
    transaction_id="order-001",
    provider=Provider.PAYSTACK,
    amount=1500.00,
    currency=Currency.NGN,
    customer=CustomerInfo(
        email="buyer@example.com",
        phone_number="+2348012345678",
    ),
    reason="Digital Download",
)

try:
    # 3. Initialize payment
    response = client.send_payment(tx)
    print(f"Redirect customer to: {response.payment_link}")

    # 4. Later — verify
    status_response = client.check_status(response.reference)
    if status_response.status == TransactionStatus.SUCCESSFUL:
        print("Deliver product to customer")
    elif status_response.status == TransactionStatus.FAILED:
        print("Payment failed — notify customer")

except PaymentError as e:
    print(f"Payment error: {e}")

Limitations

  • No cancellation: Paystack does not allow cancelling a transaction via API. Use refund for post-payment reversals.
  • Requires checkout page: Payments must be completed on Paystack's hosted page (not inline/headless).
  • Initialization-only: send_payment() only initialises; actual payment happens on Paystack's side.