TapPay Developer API
Accept NGNm stablecoin payments in your app. Create payment requests, receive webhook notifications, and initiate payouts to Nigerian bank accounts.
Getting Started
- Download TapPay from the App Store or Google Play
- Open Settings → Developer → Generate API Key
- Copy your API key and store it securely — it is shown only once
- Start making API calls to
https://api.usetappay.app/v1
Authentication
All API requests require a Bearer token in the Authorization header.
Authorization: Bearer tap_live_sk_xxxxxxxxxxxxxxxxxxxxTwo key types are available:
tap_live_sk_— Production keys (Celo Mainnet)tap_test_sk_— Sandbox keys (Celo Sepolia testnet)
Endpoints
/v1/payment-requestsCreate a payment request/v1/payment-requests/:idGet payment request status/v1/payment-requestsList payment requests/v1/transactionsList transactions/v1/balanceGet wallet balance/v1/payoutsInitiate bank payout/v1/webhooksRegister webhook/v1/webhooksList webhooks/v1/webhooks?id=xxxDelete webhookCreate Payment Request
Creates a payment request (like an invoice) that can be paid via the TapPay app or web page.
curl -X POST https://api.usetappay.app/v1/payment-requests \
-H "Authorization: Bearer tap_live_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"amount": 5000,
"currency": "NGNm",
"reference": "INV-2026-001",
"description": "School fees - Term 1",
"expires_in": 3600
}'{
"id": "pr_a1b2c3d4e5f6...",
"payment_url": "https://usetappay.app/pay/school_fees?ref=pr_a1b2c3d4e5f6...",
"qr_url": "https://api.usetappay.app/v1/payment-requests/pr_a1b2.../qr",
"amount": 5000,
"currency": "NGNm",
"reference": "INV-2026-001",
"status": "pending",
"expires_at": "2026-03-15T12:00:00.000Z"
}Check Payment Status
curl https://api.usetappay.app/v1/payment-requests/pr_a1b2c3d4e5f6 \
-H "Authorization: Bearer tap_live_sk_xxx"{
"id": "pr_a1b2c3d4e5f6...",
"status": "completed",
"paid_at": "2026-03-14T10:23:00Z",
"paid_by": "@student_username",
"tx_hash": "0x...",
"amount": 5000,
"currency": "NGNm"
}Get Balance
curl https://api.usetappay.app/v1/balance \
-H "Authorization: Bearer tap_live_sk_xxx"{
"balances": [
{ "currency": "NGNm", "balance": "45250.00", "fiat_symbol": "₦" },
{ "currency": "cUSD", "balance": "120.50", "fiat_symbol": "$" }
],
"wallet_address": "0x...",
"environment": "live"
}List Transactions
curl "https://api.usetappay.app/v1/transactions?limit=20&type=received" \
-H "Authorization: Bearer tap_live_sk_xxx"{
"transactions": [
{
"id": "ref_abc123",
"type": "received",
"amount": "5000",
"currency": "NGNm",
"tx_hash": "0x...",
"status": "completed",
"created_at": "2026-03-14T10:23:00Z"
}
],
"total": 143,
"has_more": true
}Initiate Payout
Only available to verified merchants. Initiates a withdrawal to a Nigerian bank account.
curl -X POST https://api.usetappay.app/v1/payouts \
-H "Authorization: Bearer tap_live_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"amount": 10000,
"bank_code": "044",
"account_number": "0123456789",
"reference": "PAYOUT-001"
}'Webhooks
Register webhook endpoints to receive real-time notifications when events occur. All webhook payloads are signed with HMAC-SHA256.
Available Events
payment.received— A payment was receivedpayment.sent— A payment was sentpayout.completed— A bank payout completedpayout.failed— A bank payout faileddeposit.confirmed— A Flutterwave deposit confirmed
Register a Webhook
curl -X POST https://api.usetappay.app/v1/webhooks \
-H "Authorization: Bearer tap_live_sk_xxx" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/tappay",
"events": ["payment.received", "payout.completed"]
}'{
"id": "wh_xxx",
"secret": "whsec_xxx",
"url": "https://yourapp.com/webhooks/tappay",
"events": ["payment.received", "payout.completed"]
}Verifying Webhook Signatures
Every webhook request includes a TapPay-Signature header containing an HMAC-SHA256 signature of the request body using your webhook secret.
const crypto = require('crypto');
function verifyWebhook(body, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your webhook handler:
app.post('/webhooks/tappay', (req, res) => {
const signature = req.headers['tappay-signature'];
const isValid = verifyWebhook(
JSON.stringify(req.body),
signature,
'whsec_xxx'
);
if (!isValid) return res.status(401).send('Invalid signature');
const { event, data } = req.body;
console.log('Event:', event, 'Data:', data);
res.status(200).send('OK');
});Webhooks are retried up to 3 times with exponential backoff (1 min, 5 min, 30 min). After 3 failures, the delivery is marked as failed. After 10 consecutive failures, the webhook endpoint is automatically deactivated.
JavaScript SDK
npm install @tappay/sdkimport { TapPay } from '@tappay/sdk';
const tappay = new TapPay('tap_live_sk_xxx');
// Create a payment request
const request = await tappay.paymentRequests.create({
amount: 5000,
reference: 'INV-001',
description: 'School fees',
});
console.log(request.payment_url);
// Check payment status
const status = await tappay.paymentRequests.get('pr_xxx');
console.log(status.status); // "pending" | "completed" | "expired"
// List transactions
const txns = await tappay.transactions.list({ limit: 20 });
// Get balance
const balance = await tappay.balance.get();
// Verify webhook signature
const isValid = TapPay.webhooks.verify(payload, signature, secret);Sandbox
Use test keys (tap_test_sk_) to develop against the Celo Sepolia testnet. Test keys cannot move real funds.
- Get testnet CELO from the Celo Sepolia faucet
- Flutterwave sandbox bank: Test Bank, Account 0690000031
- All API endpoints work identically in sandbox mode
Rate Limits
Rate limit info is included in every response via headers:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1710432000