Payin Webhooks
The Payin webhook allows you to receive real-time notifications about the status of your payin transactions. You can configure your webhook URL in the dashboard under Dev Settings.
Webhook Configuration
- Go to your dashboard
- Click on "Dev Settings" tab
- Find the "Webhook Configuration" section
- Enter your webhook URL
- Save the configuration
Webhook Payload
When a payin transaction status changes, you'll receive a POST request to your configured webhook URL with the following payload:
{
"type": "payin",
"payload": {
"order_id": "123456789012345",
"amount": 10,
"status": "SUCCESS",
"utr": "UTR24031545789",
"upi": "user@okaxis",
"code": "PAYMENT_SUCCESS"
}
}Payload Fields
| Field | Type | Description |
|---|---|---|
| type | string | Always "payin" for payin webhooks |
| payload.order_id | string | Your merchant order ID for reference |
| payload.amount | number | Amount of the transaction |
| payload.status | string | Transaction status (SUCCESS, FAILED, PENDING) |
| payload.utr | string | UTR number for successful transactions |
| payload.upi | string | UPI ID used for payment |
| payload.code | string | Transaction response code |
Headers
Each webhook request includes the following headers:
| Header | Value |
|---|---|
| Content-Type | application/json |
| X-Webhook-Source | PayVanta |
Response
Your webhook endpoint should return a 2xx status code to acknowledge receipt of the webhook. Any other status code will be considered a failure, and we may retry the webhook delivery.
Security
To ensure the webhook is coming from PayVanta:
- Verify the
X-Webhook-Sourceheader is set to "PayVanta" - Implement IP whitelisting for PayVanta's webhook servers
- Use HTTPS for your webhook endpoint
Example Implementation
const express = require('express');
const app = express();
app.post('/webhook', (req, res) => {
// Verify webhook source
if (req.headers['x-webhook-source'] !== 'PayVanta') {
return res.status(401).json({ error: 'Invalid webhook source' });
}
const { type, payload } = req.body;
// Handle payin webhook
if (type === 'payin') {
console.log('Received payin webhook:', {
orderId: payload.order_id,
amount: payload.amount,
status: payload.status,
utr: payload.utr,
upi: payload.upi,
code: payload.code
});
// Process the webhook data
// Update your database, notify users, etc.
}
// Always return 200 to acknowledge receipt
res.status(200).send('Webhook received');
});
app.listen(3000, () => {
console.log('Webhook server listening on port 3000');
});Best Practices
- Always respond quickly to webhook requests (within 5 seconds)
- Implement idempotency to handle duplicate webhooks
- Log all webhook requests for debugging
- Use HTTPS for your webhook endpoint
- Implement proper error handling
- Store webhook data in your database for record-keeping