const express = require('express');
const app = express();
app.use(express.json());
app.post('/webhook/payin', (req, res) => {
const { id, invoice, status, status_detail, updated_at, metadata } = req.body;
console.log(`Received payin webhook for ID: ${id}`);
console.log(`Invoice: ${invoice}`);
console.log(`Status: ${status.name} (${status.id})`);
console.log(`Updated at: ${updated_at}`);
// Handle different statuses
switch (status.id) {
case 5: // Credited
console.log('✓ Payment successful and credited');
handleSuccessfulPayment(id, invoice, metadata);
break;
case 3: // Rejected
console.log('✗ Payment rejected');
if (status_detail) {
console.log(`Reason: ${status_detail.code} - ${status_detail.detail}`);
}
handleRejectedPayment(id, invoice, status_detail);
break;
case 2: // Canceled
console.log('⊘ Payment canceled or expired');
handleCanceledPayment(id, invoice);
break;
default:
console.log(`Status: ${status.name}`);
}
// Always respond 200 OK
res.status(200).json({ received: true });
});
function handleSuccessfulPayment(id, invoice, metadata) {
// Verify webhook signature before using paid_amount
const paidAmount = metadata?.paid_amount;
// Update order status
updateOrderStatus(invoice, 'paid', paidAmount);
// Send confirmation email
sendConfirmationEmail(invoice);
// Trigger fulfillment
triggerFulfillment(invoice);
}
function handleRejectedPayment(id, invoice, statusDetail) {
// Log rejection reason
console.error(`Rejection: ${statusDetail?.code} - ${statusDetail?.detail}`);
// Notify customer
notifyCustomer(invoice, 'rejected', statusDetail);
// Update order status
updateOrderStatus(invoice, 'payment_failed');
}
function handleCanceledPayment(id, invoice) {
// Update order status
updateOrderStatus(invoice, 'canceled');
// Notify customer
notifyCustomer(invoice, 'canceled');
}
app.listen(3000, () => {
console.log('Webhook server listening on port 3000');
});