"""{{APP_NAME}} webhook receiver: Python 3.10+ with Flask (pip install flask). Run: GATEWAY_WEBHOOK_SECRET=whsec_... flask --app webhook_server run --port 3000 """ import hashlib import hmac import os import re import time from decimal import Decimal from flask import Flask, abort, request app = Flask(__name__) SECRET = os.environ["GATEWAY_WEBHOOK_SECRET"].encode() processed: set[int] = set() # replace with a UNIQUE column in your database @app.post("/webhooks/usdt") def gateway_webhook(): raw = request.get_data() # raw bytes: required for the signature m = re.match(r"t=(\d+),v1=([0-9a-f]{64})", request.headers.get("X-Gateway-Signature", "")) if not m: abort(400) if abs(time.time() - int(m[1])) > 300: abort(400) expected = hmac.new(SECRET, m[1].encode() + b"." + raw, hashlib.sha256).hexdigest() if not hmac.compare_digest(expected, m[2]): abort(401) event = request.get_json(force=True) d = event.get("data", {}) if event.get("type") == "deposit.confirmed" and d.get("credited") and d["id"] not in processed: processed.add(d["id"]) amount = Decimal(d["amount"]) # exact # In one DB transaction: insert (gateway_deposit_id UNIQUE) and, if inserted, credit the customer. app.logger.info("credit %s USDT to customer %s (deposit %s)", amount, d["external_id"], d["id"]) return "ok", 200 # answer within 10 seconds