Before you start
Accepting payments in Nigeria means supporting multiple payment methods. Your customers will want to pay with bank transfers (the most popular method), debit cards (Verve, Mastercard, Visa), USSD, and increasingly mobile wallets. Crezaro handles all of these through a single API endpoint.
To follow this guide, you will need a Crezaro account (free to create) and your API keys from the dashboard. We will start in sandbox mode, where all transactions are simulated, then switch to live when you are ready.
Step 1: Get your API keys
After creating your account at app.crezaro.com, navigate to Settings > API Keys. You will see two sets of keys: one for sandbox (prefixed with sk_sandbox_) and one for live (prefixed with sk_live_). Keep your secret key secure and never expose it in client-side code.
Step 2: Initialize a payment
The core flow is straightforward: your server creates a payment intent, your frontend redirects the customer to complete payment, and Crezaro notifies your server via webhook when the payment succeeds or fails.
Here is how to create a payment intent using cURL:
curl -X POST https://api.crezaro.com/v1/payments/initialize \
-H "Authorization: Bearer sk_sandbox_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"amount": 500000,
"currency": "NGN",
"email": "customer@example.com",
"reference": "order_12345",
"callback_url": "https://yoursite.com/payment/callback",
"metadata": {
"order_id": "12345",
"product": "Premium Plan"
}
}'
The amount is in the smallest currency unit (kobo for NGN), so 500000 equals 5,000 NGN. The response includes an authorization_url that you redirect the customer to:
{
"status": true,
"data": {
"reference": "order_12345",
"authorization_url": "https://checkout.crezaro.com/pay/cz_txn_abc123",
"access_code": "cz_txn_abc123"
}
}
Step 3: Handle the webhook
After the customer completes (or abandons) the payment, Crezaro sends a webhook to the URL you configured in your dashboard. Here is how to handle it in Node.js with Express:
const crypto = require('crypto');
const express = require('express');
const app = express();
app.post('/webhooks/crezaro', express.json(), (req, res) => {
// Verify the webhook signature
const hash = crypto
.createHmac('sha512', process.env.CREZARO_SECRET_KEY)
.update(JSON.stringify(req.body))
.digest('hex');
if (hash !== req.headers['x-crezaro-signature']) {
return res.status(401).send('Invalid signature');
}
const event = req.body;
switch (event.event) {
case 'payment.success':
// Fulfill the order
console.log('Payment successful:', event.data.reference);
break;
case 'payment.failed':
// Handle failure
console.log('Payment failed:', event.data.reference);
break;
}
// Always respond with 200 to acknowledge receipt
res.status(200).send('OK');
});
Step 4: Verify the payment server-side
Never rely solely on the callback URL redirect to confirm payment. Always verify the transaction status from your server before fulfilling the order:
curl -X GET https://api.crezaro.com/v1/payments/verify/order_12345 \
-H "Authorization: Bearer sk_sandbox_your_key_here"
Check that the status is "success" and that the amount and currency match what you expected. This protects against tampering and replay attacks.
Step 5: Go live
When you are ready to accept real payments, complete the following:
- Submit your KYB (Know Your Business) verification in the dashboard
- Configure your settlement bank account
- Set up your live webhook URL
- Replace your sandbox API key with your live key
- Run a small test transaction with a real card or bank transfer
Settlement for NGN transactions happens within 24 hours (T+1) for card payments and next-day for bank transfers. You can track all settlements in your dashboard under Finance > Settlements.
Common pitfalls to avoid
- Hardcoding amounts on the frontend. Always set the amount on your server. A determined user can modify client-side code to change the price.
- Skipping webhook signature verification. Without it, anyone can send fake webhook events to your endpoint.
- Not handling idempotency. Webhooks can be delivered more than once. Use the transaction reference to ensure you do not process the same payment twice.
- Ignoring the sandbox. Our sandbox simulates real-world scenarios including failures, timeouts, and partial payments. Test thoroughly before going live.
For the complete API reference, visit our developer documentation. If you run into any issues, our engineering team responds to support tickets within 4 hours during business hours.