This document describes the Card Transaction Webhook used to notify your system about card activities such as debits, refunds, failed transactions, and card termination events.
Webhook Notification Format
The webhook will send a JSON payload to your endpoint, with the following structure:
To ensure the authenticity and integrity of the webhook data, Xixapay includes a signature in the request header for every webhook notification sent. This signature is generated by Xixapay using your secret security key and the webhook payload.
1. Verifying the Webhook Signature
When you receive a webhook, you need to:
Retrieve the payload sent by Xixapay in the request body.
Retrieve the xixapay header, which contains the expected signature for the webhook.
Hash the payload with your secret security key using the same hashing algorithm Xixapay uses (usually HMAC-SHA256).
Compare the computed signature with the one sent in the xixapay header.
If the signatures match, you can be confident that the webhook is authentic and hasn't been tampered with
2. Signature Verification in Different Languages
Hereβs how to implement the signature verification in PHP, Python, and Node.js.
<?php
// Retrieve the raw POST body and headers
$payload = file_get_contents('php://input');
$signatureHeader = $_SERVER['HTTP_XIXAPAY']; // xixapay signature header
// Your Xixapay secret security key
$secretKey = 'your-secret-key'; // Replace with your actual secret key
// Calculate the expected signature using HMAC-SHA256
$calculatedSignature = hash_hmac('sha256', $payload, $secretKey);
// Compare the calculated signature with the one from the xixapay header
if (hash_equals($calculatedSignature, $signatureHeader)) {
// Signature is valid, proceed with handling the webhook
echo "Webhook signature is valid!";
// Process the payload (decode JSON, handle business logic)
$data = json_decode($payload, true);
// Example: Process the data (e.g., update database)
} else {
// Signature is invalid, reject the request
header('HTTP/1.1 400 Bad Request');
echo "Invalid signature!";
}
?>
import hmac
import hashlib
import json
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
# Your Xixapay secret security key (set this in your settings)
SECRET_KEY = "" # Add your secret key in xixapay
@csrf_exempt
def webhook(request):
if request.method == 'POST':
# Get the payload (raw body)
payload = request.body
# Get the signature from the header (xixapay)
signature_header = request.headers.get('xixapay')
if not signature_header:
return JsonResponse({'error': 'No signature header'}, status=400)
# Calculate the HMAC signature using SHA-256
calculated_signature = hmac.new(
SECRET_KEY.encode(), payload, hashlib.sha256
).hexdigest()
# Compare the calculated signature with the one from the xixapay header
if hmac.compare_digest(calculated_signature, signature_header):
# Signature is valid, process the webhook data
data = json.loads(payload)
print("Webhook received:", data)
# Do your processing here (e.g., update database, send email, etc.)
return JsonResponse({'status': 'success'}, status=200)
else:
# Signature mismatch
return JsonResponse({'error': 'Invalid signature'}, status=400)
else:
return JsonResponse({'error': 'Invalid HTTP method'}, status=405)
// Some code
const express = require('express');
const crypto = require('crypto');
const bodyParser = require('body-parser');
const app = express();
const secretKey = 'your-secret-key'; // Replace with your actual secret key
// Middleware to parse incoming JSON payload
app.use(bodyParser.json());
app.post('/webhook', (req, res) => {
// Retrieve the raw POST body and signature header
const payload = JSON.stringify(req.body); // Ensure the body is a JSON string
const signatureHeader = req.headers['xixapay']; // xixapay signature header
// Calculate the HMAC signature using SHA-256
const calculatedSignature = crypto.createHmac('sha256', secretKey).update(payload).digest('hex');
// Compare the calculated signature with the one from the xixapay header
if (calculatedSignature === signatureHeader) {
// Signature is valid, process the webhook
console.log("Webhook signature is valid!");
// Example: Process the data (e.g., update database)
res.status(200).send('Webhook received');
} else {
// Signature is invalid, reject the request
res.status(400).send('Invalid signature');
}
});
// Start the server
app.listen(3000, () => {
console.log('Server listening on port 3000');
});