Developer Documentation

Welcome to the DunadPay Developer Documentation. Whether you are building a custom checkout flow, integrating with an e-commerce platform, or automating payouts, our APIs and SDKs provide the tools you need to accept and manage payments globally.

What's New DunadPay API v2 is now generally available, featuring improved latency, enhanced webhook reliability, and new subscription billing endpoints. Read the changelog →

Core Concepts

Before making your first API call, familiarize yourself with these fundamental DunadPay concepts:

  • Environments: Use Test Mode to simulate transactions with mock data. Use Live Mode for real money movement (requires KYC).
  • API Keys: Use pk_test_... / pk_live_... for frontend initialization. Use sk_test_... / sk_live_... for secure server-to-server calls.
  • Idempotency: Include an Idempotency-Key header in POST requests to prevent duplicate charges or payouts.

Authentication

DunadPay uses standard HTTP Bearer authentication. Include your Secret Key in the Authorization header of your requests.

curl -X GET https://api.dunadpay.com/v2/balance \
  -H "Authorization: Bearer sk_test_your_secret_key_here" \
  -H "Content-Type: application/json"
const axios = require('axios');

axios.get('https://api.dunadpay.com/v2/balance', {
  headers: { 'Authorization': 'Bearer sk_test_your_secret_key_here' }
}).then(res => console.log(res.data));
import requests

headers = {"Authorization": "Bearer sk_test_your_secret_key_here"}
response = requests.get("https://api.dunadpay.com/v2/balance", headers=headers)
print(response.json())
using System.Net.Http;
using System.Threading.Tasks;

var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer sk_test_your_secret_key_here");
var response = await client.GetAsync("https://api.dunadpay.com/v2/balance");
var content = await response.Content.ReadAsStringAsync();

Pay-ins (Collections)

Accept card and bank transfer pay-ins directly into your merchant wallet. DunadPay handles real-time transaction status and automated reconciliation.

Initialize a Payment

Create a payment session to redirect your customer to a secure checkout page or trigger an inline modal.

curl -X POST https://api.dunadpay.com/v2/payments \
  -H "Authorization: Bearer sk_test_your_secret_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 5000,
    "currency": "NGN",
    "payment_method": "card",
    "customer": { "email": "customer@example.com", "name": "Jane Doe" },
    "redirect_url": "https://yourwebsite.com/callback",
    "description": "Order #12345"
  }'
const DunadPay = require('dunadpay-node');
const dunadpay = new DunadPay('sk_test_your_secret_key_here');

const payment = await dunadpay.payments.create({
  amount: 5000, currency: 'NGN', payment_method: 'card',
  customer: { email: 'customer@example.com', name: 'Jane Doe' },
  redirect_url: 'https://yourwebsite.com/callback', description: 'Order #12345'
});
console.log(payment.data.payment_url);
import dunadpay
dunadpay.api_key = "sk_test_your_secret_key_here"

payment = dunadpay.Payment.create(
    amount=5000, currency="NGN", payment_method="card",
    customer={"email": "customer@example.com", "name": "Jane Doe"},
    redirect_url="https://yourwebsite.com/callback", description="Order #12345"
)
print(payment.payment_url)
var request = new PaymentRequest {
    Amount = 5000, Currency = "NGN", PaymentMethod = "card",
    Customer = new Customer { Email = "customer@example.com", Name = "Jane Doe" },
    RedirectUrl = "https://yourwebsite.com/callback", Description = "Order #12345"
};
var response = await dunadpay.Payments.CreateAsync(request);

Payouts (Disbursements)

Send single or bulk payouts against your Available Balance. DunadPay includes built-in validation checks to stop failures before funds move.

Initiate a Single Payout

curl -X POST https://api.dunadpay.com/v2/payouts \
  -H "Authorization: Bearer sk_test_your_secret_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 15000,
    "currency": "NGN",
    "reference": "PAYOUT-12345",
    "beneficiary": {
      "account_number": "0123456789",
      "bank_code": "058",
      "account_name": "John Doe"
    },
    "reason": "Vendor payment"
  }'
const payout = await dunadpay.payouts.create({
  amount: 15000, currency: 'NGN', reference: 'PAYOUT-12345',
  beneficiary: { account_number: '0123456789', bank_code: '058', account_name: 'John Doe' },
  reason: 'Vendor payment'
});
console.log(payout.data.status);
payout = dunadpay.Payout.create(
    amount=15000, currency="NGN", reference="PAYOUT-12345",
    beneficiary={"account_number": "0123456789", "bank_code": "058", "account_name": "John Doe"},
    reason="Vendor payment"
)
print(payout.status)
var request = new PayoutRequest {
    Amount = 15000, Currency = "NGN", Reference = "PAYOUT-12345",
    Beneficiary = new Beneficiary { AccountNumber = "0123456789", BankCode = "058", AccountName = "John Doe" },
    Reason = "Vendor payment"
};
var response = await dunadpay.Payouts.CreateAsync(request);

Bill Payments

Integrate electricity, airtime, data, cable TV, and water payments directly into your platform. Users get instant tokens, automatic receipts, and zero hidden fees.

Supported Billers

⚡ Electricity

📞 Airtime

📶 Data

📺 Cable TV

💧 Water

Process a Bill Payment

curl -X POST https://api.dunadpay.com/v2/bills/pay \
  -H "Authorization: Bearer sk_test_your_secret_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "biller_code": "EKEDC",
    "customer_id": "04123456789",
    "amount": 5000,
    "currency": "NGN",
    "reference": "BILL-12345"
  }'
const billPayment = await dunadpay.bills.pay({
  biller_code: 'EKEDC', customer_id: '04123456789',
  amount: 5000, currency: 'NGN', reference: 'BILL-12345'
});
console.log(billPayment.data.token);
bill = dunadpay.Bill.pay(
    biller_code="EKEDC", customer_id="04123456789",
    amount=5000, currency="NGN", reference="BILL-12345"
)
print(bill.token)
var request = new BillPaymentRequest {
    BillerCode = "EKEDC", CustomerId = "04123456789",
    Amount = 5000, Currency = "NGN", Reference = "BILL-12345"
};
var response = await dunadpay.Bills.PayAsync(request);

Webhooks

Don't rely solely on client-side redirects. Use Webhooks to receive secure, server-to-server notifications about payment status changes (e.g., payment.success, payout.completed).

Security Best Practice Always verify the HMAC webhook signature using your Webhook Secret to ensure the request genuinely came from DunadPay.

Testing Your Integration

Use the following mock data to test your integration in Test Mode:

Card TypeCard NumberExpiryCVVResult
Success4111 1111 1111 1111Any futureAny 3 digitsPayment succeeds
Insufficient Funds4000 0000 0000 9995Any futureAny 3 digitsPayment declines
Requires 3D Secure4000 0025 0000 3155Any futureAny 3 digitsTriggers OTP modal

Need Help?

We are here to support your development journey.