Quickstart
From a new account to your first signed webhook, using the sandbox.
1. Create a developer account
Go to Create account. You can also sign in with your existing Payder email and password, which starts an application from that account. Every developer account is reviewed by a Payder admin, and you get an email when it is approved. This portal is separate from the customer app.
2. Create your sandbox merchant and key
- Open the console and stay on the Sandbox tab.
- Click Create merchant, enter your business name, and copy the Merchant ID (
mch_test_…). - Click Create key. The key (
pdr_test_sk_…) is shown once. Store it in your secret manager now. - Under Webhooks, enter your endpoint URL and click Generate secret. The secret is also shown once.
export BASE=https://sandbox-api.payder.ng
export KEY=pdr_test_sk_xxxxxxxx
export MID=mch_test_xxxxxxxx3. Create a checkout
curl -s $BASE/v1/checkouts \
-H "Authorization: Bearer $KEY" \
-H "X-Merchant-Id: $MID" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"reference": "ORD-1001",
"amount": 1250000,
"currency": "NGN",
"description": "Order Q-1001",
"customer": { "email": "buyer@example.com" },
"returnUrl": "https://yourshop.example/return",
"metadata": { "orderCode": "Q-1001" }
}'The response:
{
"id": "chk_9f2c...",
"reference": "ORD-1001",
"checkoutUrl": "https://www.payder.ng/pay/chk_9f2c...",
"status": "pending"
}4. Pay it with a test card
Open checkoutUrl. In the sandbox the page shows a test form. Use card 4242 4242 4242 4242 with any future expiry and any CVV. You are sent back to your returnUrl.
5. Receive the webhook
Your endpoint receives a payment.succeeded event with an x-payder-signature header. Verify it against the raw body:
import crypto from 'crypto';
import express from 'express';
const app = express();
app.post('/api/webhooks/payder', express.raw({ type: 'application/json' }), (req, res) => {
const expected = crypto
.createHmac('sha256', process.env.PAYDER_WEBHOOK_SECRET)
.update(req.body) // the raw Buffer, not parsed JSON
.digest('hex');
const given = String(req.headers['x-payder-signature'] || '');
const ok = given.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected));
if (!ok) return res.sendStatus(401);
const event = JSON.parse(req.body.toString());
// event = { event: 'payment.succeeded', reference: 'ORD-1001', amountMinor: 1250000, ... }
// mark the order paid, idempotently, then:
res.sendStatus(200);
});That is the whole integration loop. Read Webhooks for retries and the other languages, and Going live when you are ready for real money.