PIK Webhooks let your application receive real-time notifications when payment events occur. Instead of polling the API to check payment status, you register an endpoint on your server and PIK sends an HTTP POST request to it whenever a payment event happens.
How webhooks work
When a customer completes a payment:
- PIK confirms the transaction on-chain
- PIK sends an HTTP
POST request to your registered webhook URL
- Your server processes the event and responds with
HTTP 200
- PIK marks the event as delivered
If your server does not respond with 200, PIK retries the delivery.
Register a webhook endpoint
You can register a webhook endpoint from the Dashboard or via the API.
Via Dashboard
- Go to Account Settings → Webhooks
- Click Add Webhook
- Enter the URL of your server endpoint (must be publicly accessible over HTTPS)
- Select the events you want to receive
- Click Save
Via API
curl -X POST https://api.pik.global/v1/webhooks \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/pik",
"events": ["payment.confirmed", "payment.settled"]
}'
Webhook events
| Event | Triggered when |
|---|
payment.confirmed | A payment is confirmed on-chain |
payment.settled | Funds are credited to your PIK balance |
payment.failed | A payment attempt fails or times out |
Webhook payload
PIK sends a JSON payload in the body of each webhook request. Here is an example payment.confirmed event:
{
"event": "payment.confirmed",
"id": "evt_xyz789",
"created_at": "2024-01-15T10:45:00Z",
"data": {
"transaction_id": "txn_def456",
"payment_link_id": "pl_abc123xyz",
"amount": "75.00",
"currency": "USDT",
"status": "confirmed",
"confirmed_at": "2024-01-15T10:45:00Z"
}
}
Verify webhook authenticity
PIK signs each webhook request so you can verify it came from PIK and not from a third party. Each request includes a PIK-Signature header.
To verify the signature:
- Retrieve the raw request body (do not parse JSON before verifying)
- Compute an HMAC-SHA256 hash of the raw body using your webhook secret as the key
- Compare the result to the value in the
PIK-Signature header
const crypto = require('crypto');
function verifyWebhook(rawBody, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
);
}
Your webhook secret is shown when you create the webhook endpoint. Store it securely alongside your API key.
Always verify the webhook signature before processing event data. Never trust webhook payloads without verification.
Respond to webhooks
Your endpoint must return HTTP 200 within 10 seconds. If PIK does not receive a 200 response, it retries the request with exponential backoff.
app.post('/webhooks/pik', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['pik-signature'];
const isValid = verifyWebhook(req.body, signature, process.env.PIK_WEBHOOK_SECRET);
if (!isValid) {
return res.status(400).send('Invalid signature');
}
const event = JSON.parse(req.body);
if (event.event === 'payment.confirmed') {
// Mark order as paid in your database
console.log('Payment confirmed:', event.data.transaction_id);
}
res.status(200).send('OK');
});
Retry behavior
| Attempt | Delay |
|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 30 minutes |
| 4th retry | 2 hours |
After 4 failed retries, the event is marked as failed. You can view failed events and manually retry them from Account Settings → Webhooks in the Dashboard.