RazCrypto RazCrypto Docs
Dashboard Get API Keys
Docs Handler Examples

Webhook Handler Examples

Complete webhook handler implementations for popular languages and frameworks.

<?php
header('Content-Type: application/json');

$rawPayload = file_get_contents('php://input');
$signature  = $_SERVER['HTTP_X_RAZCRYPTO_SIGNATURE'] ?? '';
$secret     = getenv('RAZ_WEBHOOK_SECRET');
$expected   = hash_hmac('sha256', $rawPayload, $secret);

if (!hash_equals($expected, $signature)) {
    http_response_code(401);
    exit(json_encode(['error' => 'Invalid signature']));
}

$data  = json_decode($rawPayload, true);
$event = $data['event'] ?? '';

if ($event === 'payment.completed') {
    $paymentId  = $data['payment_id'];
    $amount     = $data['amount'];
    $txHash     = $data['tx_hash'];
    $orderId    = $data['custom_data']['order_id'] ?? $paymentId;

    // Update your database
    $pdo->prepare("UPDATE orders SET status='paid', tx_hash=? WHERE order_id=?")
        ->execute([$txHash, $orderId]);
}

http_response_code(200);
echo json_encode(['status' => 'success']);
?>
<?php
// app/Http/Controllers/WebhookController.php
public function handle(Request $request)
{
    $rawPayload = $request->getContent();
    $signature  = $request->header('x-razcrypto-signature', '');
    $secret     = config('services.razcrypto.webhook_secret');
    $expected   = hash_hmac('sha256', $rawPayload, $secret);

    if (!hash_equals($expected, $signature)) {
        return response()->json(['error' => 'Invalid signature'], 401);
    }

    $data  = $request->json()->all();
    $event = $data['event'] ?? '';

    if ($event === 'payment.completed') {
        $orderId = $data['custom_data']['order_id'] ?? null;
        if ($orderId) {
            Order::where('id', $orderId)->update([
                'status'     => 'paid',
                'payment_id' => $data['payment_id'],
                'tx_hash'    => $data['tx_hash'],
                'paid_at'    => now(),
            ]);
        }
    }

    return response()->json(['status' => 'success']);
}
?>
const express = require('express');
const crypto  = require('crypto');
const app     = express();

app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
    const payload   = req.body.toString('utf8');
    const signature = req.headers['x-razcrypto-signature'] || '';
    const secret    = process.env.RAZ_WEBHOOK_SECRET;
    const expected  = crypto.createHmac('sha256', secret).update(payload).digest('hex');

    if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) {
        return res.status(401).json({ error: 'Invalid signature' });
    }

    const data  = JSON.parse(payload);
    const event = data.event;

    if (event === 'payment.completed') {
        const orderId = data.custom_data?.order_id;
        // db.query('UPDATE orders SET status=paid WHERE id=?', [orderId])
        console.log('Paid:', orderId, 'tx:', data.tx_hash);
    }

    res.status(200).json({ status: 'ok' });
});
import hmac, hashlib, json, os
from flask import Flask, request, jsonify

app    = Flask(__name__)
SECRET = os.getenv('RAZ_WEBHOOK_SECRET', '')

@app.route('/webhook', methods=['POST'])
def webhook():
    payload   = request.get_data(as_text=True)
    signature = request.headers.get('X-Razcrypto-Signature', '')
    expected  = hmac.new(SECRET.encode(), payload.encode(), hashlib.sha256).hexdigest()

    if not hmac.compare_digest(expected, signature):
        return jsonify({'error': 'Invalid signature'}), 401

    data  = json.loads(payload)
    event = data.get('event')

    if event == 'payment.completed':
        order_id = data.get('custom_data', {}).get('order_id')
        tx_hash  = data.get('tx_hash')
        print(f'Order {order_id} paid — tx: {tx_hash}')
        # Update your database here

    return jsonify({'status': 'success'})