@NSjj #10 这是一个加密货币的支付网关。 @布莱恩 #11 是的!!当时第一眼看到就觉得很对味 @coolpool #12 理论上有,因为你不能阻拦任何人给你付款,系统也没办法在付款完成前得知谁要给你付款,因此这个风控是没有的。 @koudai #13 收到,会开始逐步做插件 @verse4 #21 参与了,做了一遍白盒测试 @ddkiss #23 已严肃支持 @0x20x2 #22 会的,做这个是我自己有需求,所以会持续更新 @bluecode #27 是的,大部分转账添加备注时都需要额外的手续费,并且也增加了付款难度
@outtime #35 发布于2026/7/6 12:23:39 @pursuer #34 目前u卡普及率我是感觉越来越高了,用u卡就非常有机会接触到交易所。虽然大陆监管上越来越严,但是私下交易越来越方便 @outtime #35 私下交易越来越方便 老哥有空研究研究国内蓝绿怎么安全收款呗
不错,偷懒让AI也给我写了一个套娃变易支付 import hashlib import time import json import base64 import logging import sqlite3 import requests from flask import Flask, request, jsonify, redirect from Crypto.PublicKey import RSA from Crypto.Signature import pkcs1_15 from Crypto.Hash import SHA256 from Crypto.Cipher import AES, PKCS1_OAEP logging.basicConfig(level=logging.INFO) logger = logging.getLogger("EpayBridge") app = Flask(__name__) # ==================== 配置区 ==================== # 1. 你为这个“虚拟易支付”自定义的商户配置(填入你的独角数卡等插件中) BRIDGE_EPAY_PID = "8888" # 自定义商户ID BRIDGE_EPAY_KEY = "23fsdsdvv3" # 自定义商户MD5密钥 # 2. 真实的 HashPay 配置 HASHPAY_CONFIG = { "base_url": "https://hashpay.xxxxx.xxxx", "merchant_id": "xxxx-xxxx-xxxx-xxxx-xxxx", "private_key": """-----BEGIN PRIVATE KEY----- xxxx -----END PRIVATE KEY-----""" } # 独角数卡传过来的 type 映射到 HashPay 的币种结算 TYPE_TO_CURRENCY = { "usdt": "CNY", } # ================================================ def init_db(): conn = sqlite3.connect('orders.db') c = conn.cursor() # 扩展数据库字段,把原始的商品名称(goods_name)和支付类型(pay_type)也存下来用于完美对齐回调 c.execute('''CREATE TABLE IF NOT EXISTS orders (out_trade_no TEXT PRIMARY KEY, hp_order_id TEXT, notify_url TEXT, amount TEXT, pay_type TEXT, goods_name TEXT)''') conn.commit() conn.close() init_db() def _hashpay_sign(method, path, timestamp, body_str): try: sign_str = f"{method}\n{path}\n{timestamp}\n{body_str}" key = RSA.import_key(HASHPAY_CONFIG["private_key"]) h = SHA256.new(sign_str.encode("utf-8")) signature = pkcs1_15.new(key).sign(h) return base64.b64encode(signature).decode("utf-8") except Exception as e: logger.error(f"HashPay 签名失败: {e}") return "" def _decrypt_hashpay_callback(encrypted_envelope): try: private_key = RSA.import_key(HASHPAY_CONFIG["private_key"]) encrypted_key = base64.b64decode(encrypted_envelope["key"]) cipher_rsa = PKCS1_OAEP.new(private_key, hashAlgo=SHA256) aes_key = cipher_rsa.decrypt(encrypted_key) iv = base64.b64decode(encrypted_envelope["iv"]) encrypted_data = base64.b64decode(encrypted_envelope["data"]) ciphertext = encrypted_data[:-16] tag = encrypted_data[-16:] cipher_aes = AES.new(aes_key, AES.MODE_GCM, nonce=iv) decrypted_bytes = cipher_aes.decrypt_and_verify(ciphertext, tag) return json.loads(decrypted_bytes.decode("utf-8")) except Exception as e: logger.error(f"解密 HashPay 回调信封失败: {e}") return None def verify_epay_md5(params): sign = params.get("sign") if not sign: return False keys = sorted([k for k in params.keys() if params[k] and k not in ["sign", "sign_type"]]) sign_str = "&".join([f"{k}={params[k]}" for k in keys]) + BRIDGE_EPAY_KEY local_sign = hashlib.md5(sign_str.encode("utf-8")).hexdigest() return local_sign == sign # --- 1. 易支付下单一式 (submit.php) --- @app.route("/submit.php", methods=["GET", "POST"]) @app.route("/mapi.php", methods=["GET", "POST"]) def epay_submit(): req_params = request.args.to_dict() if request.method == "GET" else request.form.to_dict() if not verify_epay_md5(req_params): return "易支付签名验证失败", 400 out_trade_no = req_params.get("out_trade_no") money = req_params.get("money") pay_type = req_params.get("type", "usdt") goods_name = req_params.get("name", "product") # 抓取发卡网传过来的 name 参数 notify_url = req_params.get("notify_url") currency = TYPE_TO_CURRENCY.get(pay_type, "USDT") path = "/api/merchant/new" timestamp = str(int(time.time())) body_data = { "merchantNo": out_trade_no, "amount": float(money), "currency": currency, "description": f"Epay {out_trade_no}", "return_url": req_params.get("return_url") } body_str = json.dumps(body_data, separators=(',', ':')) signature = _hashpay_sign("POST", path, timestamp, body_str) headers = { "X-Merchant-Id": HASHPAY_CONFIG["merchant_id"], "X-Timestamp": timestamp, "X-Signature": signature, "Content-Type": "application/json" } try: url = f"{HASHPAY_CONFIG['base_url']}{path}" res = requests.post(url, data=body_str, headers=headers, timeout=15).json() if "checkoutUrl" in res: checkout_url = res.get("checkoutUrl") hp_order_id = res.get("order", {}).get("id") # 【完美对齐修改】存入数据库时,连同原始的 pay_type 和 goods_name 一起保存 conn = sqlite3.connect('orders.db') c = conn.cursor() c.execute("INSERT OR REPLACE INTO orders VALUES (?, ?, ?, ?, ?, ?)", (out_trade_no, hp_order_id, notify_url, str(money), str(pay_type), str(goods_name))) conn.commit() conn.close() if checkout_url.startswith("http://hashpay.xxxx.xx"): checkout_url = checkout_url.replace("http://", "https://") return redirect(checkout_url) else: return f"HashPay 生单失败: {res}", 500 except Exception as e: return f"网关桥接异常: {e}", 500 # --- 2. 精确转换查单 (api.php) --- @app.route("/api.php", methods=["GET"]) def epay_api(): act = request.args.get("act") if act != "order": return jsonify({"code": -1, "msg": "只支持 act=order"}) out_trade_no = request.args.get("out_trade_no") conn = sqlite3.connect('orders.db') c = conn.cursor() c.execute("SELECT hp_order_id, amount FROM orders WHERE out_trade_no=?", (out_trade_no,)) row = c.fetchone() conn.close() if not row: return jsonify({"code": -1, "msg": "未找到对应的本地订单记录"}) hp_order_id, amount = row path = f"/api/order/{hp_order_id}" timestamp = str(int(time.time())) signature = _hashpay_sign("GET", path, timestamp, "") headers = { "X-Merchant-Id": HASHPAY_CONFIG["merchant_id"], "X-Timestamp": timestamp, "X-Signature": signature } try: url = f"{HASHPAY_CONFIG['base_url']}{path}" res = requests.get(url, headers=headers, timeout=10).json() if res.get("status") in ["success", "paid"]: return jsonify({ "code": 1, "status": 1, "msg": "success", "out_trade_no": out_trade_no, "amount": amount }) else: return jsonify({"code": 1, "status": 0, "msg": "pending"}) except Exception as e: return jsonify({"code": -1, "msg": f"请求真实网关失败: {e}"}) # --- 3. 精准对齐独角数卡金额、名称与签名的回调函数 --- @app.route("/hashpay/callback", methods=["POST"]) def hashpay_callback(): envelope = request.json logger.info("📡 收到来自 HashPay 的原始回调请求...") if not envelope or "data" not in envelope: return "Invalid payload", 400 decrypted_json = _decrypt_hashpay_callback(envelope) if not decrypted_json: return "Decryption failed", 400 payload = decrypted_json.get("payload", {}) merchant_no = payload.get("merchantNo") status = payload.get("status") hp_order_id = payload.get("orderId") logger.debug(f"🔓 信封解密成功! 内部单号(trade_no): {hp_order_id}, 商户单号(out_trade_no): {merchant_no}, 状态: {status}") if status in ["success", "paid"]: # 从本地数据库取出下单时存留的所有发卡网原始参数 conn = sqlite3.connect('orders.db') c = conn.cursor() c.execute("SELECT notify_url, amount, pay_type, goods_name FROM orders WHERE out_trade_no=?", (merchant_no,)) row = c.fetchone() conn.close() if row: notify_url, amount, pay_type, goods_name = row # 【终极对齐】完美复原独角数卡生单时传过来的每一个核心参数 epay_notify_data = { "pid": str(BRIDGE_EPAY_PID), "trade_no": str(hp_order_id), "out_trade_no": str(merchant_no), "type": str(pay_type), # 动态还原原始支付类型,如 usdt "name": str(goods_name), # 动态还原原始商品名,如 EW1YQJ2QGVRTUDWM "money": str(amount), # 动态还原原始金额格式,如 10 "trade_status": "TRADE_SUCCESS" } # 对参数名进行升序排序 (A-Z) keys = sorted([k for k in epay_notify_data.keys() if epay_notify_data[k]]) # 拼接签名串 sign_str = "&".join([f"{k}={epay_notify_data[k]}" for k in keys]) full_sign_str = sign_str + BRIDGE_EPAY_KEY # 计算 MD5 signature = hashlib.md5(full_sign_str.encode("utf-8")).hexdigest() epay_notify_data["sign"] = signature epay_notify_data["sign_type"] = "MD5" logger.debug("================== 易支付回调参数对账 ==================") logger.debug(f"待签名原文: {full_sign_str}") logger.debug(f"生成的MD5签名: {signature}") try: logger.debug(f"🚀 正在向发卡网发起标准 GET 回调...") rep = requests.get(notify_url, params=epay_notify_data, timeout=15) logger.debug(f"最终请求发卡网的完整URL: {rep.url}") logger.info(f"📥 发卡网响应状态码: {rep.status_code}") logger.debug(f"📥 发卡网返回正文内容: {rep.text.strip()}") logger.debug("======================================================") if "success" in rep.text.lower(): logger.info("✅ 发卡网已成功识别并处理订单,完成发货!") return "success" else: logger.warning("⏳ 发卡网依然返回 fail。请检查前后台密钥配置。") return rep.text, 200 except Exception as e: logger.error(f"❌ 向发卡网投递易支付回调时发生异常: {e}") return "bridge_delivery_error", 200 else: logger.error(f"❌ 本地数据库找不到商户单号 {merchant_no} 的记录") return "fail", 200 if __name__ == "__main__": app.run(host="0.0.0.0", port=8000) epay.xxxx.xx反代ip:8000 后台商户回调URL写 https://epay.xxxx.xx/hashpay/callback 另外现在Tgbot是不是没有功能啊?连订单推送都没
不错
支持
@NSjj #10
这是一个加密货币的支付网关。
@布莱恩 #11
是的!!当时第一眼看到就觉得很对味
@coolpool #12
理论上有,因为你不能阻拦任何人给你付款,系统也没办法在付款完成前得知谁要给你付款,因此这个风控是没有的。
@koudai #13
收到,会开始逐步做插件
@verse4 #21
参与了,做了一遍白盒测试
@ddkiss #23
已严肃支持
@0x20x2 #22
会的,做这个是我自己有需求,所以会持续更新
@bluecode #27
是的,大部分转账添加备注时都需要额外的手续费,并且也增加了付款难度
有能力支付加密货币的用户也越来越多,真的吗
@pursuer #34
目前u卡普及率我是感觉越来越高了,用u卡就非常有机会接触到交易所。虽然大陆监管上越来越严,但是私下交易越来越方便
@SolitudeAlma #29
太牛了
@outtime #35 私下交易越来越方便

老哥有空研究研究国内蓝绿怎么安全收款呗
佬,怎么蓝绿呀
不错,偷懒让AI也给我写了一个套娃变易支付
epay.xxxx.xx反代ip:8000
后台商户回调URL写 https://epay.xxxx.xx/hashpay/callback
另外现在Tgbot是不是没有功能啊?连订单推送都没