Webhooks — Python SDK

Flask example

from flask import Flask, request, jsonify
import simiz

app = Flask(__name__)
client = simiz.Client(api_key="sk_test_xxxxxxxxxxxx")

@app.route('/webhooks/simiz', methods=['POST'])
def handle_webhook():
    payload = request.get_data()
    signature = request.headers.get('X-Simiz-Signature')

    try:
        event = client.webhooks.construct_event(
            payload=payload,
            signature=signature,
            secret="whsec_xxxxxxxxxxxx"
        )

        if event.type == "payment.succeeded":
            print(f"Payment received: {event.data.id}")
        elif event.type == "payment.failed":
            print(f"Payment failed: {event.data.id}")
        elif event.type == "refund.succeeded":
            print(f"Refund completed: {event.data.id}")

        return jsonify(received=True), 200

    except simiz.errors.SignatureVerificationError as e:
        return f"Invalid signature: {e}", 401

Django example

from django.http import JsonResponse, HttpResponse
from django.views.decorators.csrf import csrf_exempt
import simiz

client = simiz.Client(api_key="sk_test_xxxxxxxxxxxx")

@csrf_exempt
def webhook_handler(request):
    if request.method != 'POST':
        return HttpResponse(status=405)

    payload = request.body
    signature = request.META.get('HTTP_X_SIMIZ_SIGNATURE')

    try:
        event = client.webhooks.construct_event(
            payload=payload,
            signature=signature,
            secret="whsec_xxxxxxxxxxxx"
        )

        # Process event...
        return JsonResponse({"received": True})

    except simiz.errors.SignatureVerificationError:
        return HttpResponse("Invalid signature", status=401)

Manual verification

Signature format: X-Simiz-Signature: t=<timestamp>,v1=<hmac_sha256_hex>The timestamp protects against replay attacks. Signatures older than 5 minutes are rejected.
import hmac
import hashlib

def verify_signature(payload: bytes, signature_header: str, secret: str, tolerance_seconds: int = 300) -> bool:
    """Verify Simiz webhook signature with replay protection."""

    # Parse signature header: t=<timestamp>,v1=<hash>
    parts = signature_header.split(',')
    timestamp = None
    hash_value = None

    for part in parts:
        if part.startswith('t='):
            timestamp = int(part[2:])
        elif part.startswith('v1='):
            hash_value = part[3:]

    if timestamp is None or hash_value is None:
        return False

    # Check timestamp is within tolerance (default: 5 minutes)
    import time
    now = int(time.time())
    if abs(now - timestamp) > tolerance_seconds:
        return False

    # Calculate expected signature
    signature_payload = f"{timestamp}.{payload.decode()}"
    expected_signature = hmac.new(
        secret.encode(),
        signature_payload.encode(),
        hashlib.sha256
    ).hexdigest()

    # Timing-safe comparison
    return hmac.compare_digest(
        hash_value.encode(),
        expected_signature.encode()
    )