Authentication & Security
API key authentication, webhook HMAC verification, rate limits, and security best practices.
Authentication & Security
API Key Authentication
All API calls require the apikey header.
| Header | Required | Description |
|---|---|---|
apikey | Yes | Your merchant API key |
x-api-secret | No (most endpoints) | Validated if sent, ignored if omitted |
const client = axios.create({
baseURL: 'https://pay.3pa-y.com/api/v1',
headers: {
'apikey': process.env.THREEPAY_API_KEY,
'x-api-secret': process.env.THREEPAY_API_SECRET, // optional but recommended
},
});x-api-secret is required for:
| Endpoint |
|---|
POST /api/v1/public/withdrawal-requests/{id}/approve |
POST /api/v1/public/withdrawal-requests/{id}/reject |
Error responses: 401 for missing/invalid API key or invalid API secret.
Dashboard Authentication
- JWT in
httpOnlycookies (secure: true,sameSite: strictin production) - OTP required for payouts and password changes
- Optional TOTP 2FA in Dashboard > Settings > Security
Webhook HMAC Verification
Every webhook includes X-Webhook-Signature: sha256=<hex-digest> computed from the raw body using your webhookSecret.
const expected = crypto.createHmac('sha256', webhookSecret).update(rawBody).digest('hex');
const received = signatureHeader?.replace('sha256=', '') || '';
const valid = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received));| Endpoint | Description |
|---|---|
GET /api/v1/webhook/secret | View masked secret |
POST /api/v1/webhook/secret/rotate | Generate new secret (shown once) |
Full verification examples (Node.js, Python, PHP): Webhook Handling
Rate Limits
All endpoints are rate-limited per IP (sliding window).
| Tier | Limit | Window | Applies To |
|---|---|---|---|
| Auth | 15 | 15 min | Login, register, password reset |
| Financial | 30 | 15 min | Withdrawals, balance updates, approve/reject |
| Wallet Generation | 20 | 15 min | POST /wallet/generate |
| Standard API | 100 | 15 min | Other public API endpoints |
| Dashboard | 200 | 15 min | Dashboard browsing |
| Public Page | 60 | 15 min | Customer-facing payment pages |
Exceeding returns 429 with RateLimit-* headers. Implement exponential backoff.
Pagination
limitcapped at 100 server-side on all list endpointssortByvalidated against allowlist:createdAt,updatedAt,amount,status,confirmedAt- Invalid
sortByvalues fall back tocreatedAt
SSRF Protection
Webhook URLs and callback URLs are validated — private IPs, localhost, and cloud metadata endpoints are rejected. Use public, internet-routable HTTPS URLs only.
Best Practices
- HTTPS webhook URLs — HTTP works but exposes payload data
- Rotate webhook secrets periodically —
POST /webhook/secret/rotate - Send
x-api-secreton every call — adds a second credential layer - IP whitelisting — Dashboard > Settings
- API keys server-side only — never in client code
- Enable 2FA — Dashboard > Settings > Security
- Verify webhook signatures — never skip HMAC verification
- Idempotency — webhooks may arrive more than once (5 auto-retries)
Updated about 2 months ago
