logo NodeSeekbeta

HashPay | 一站式加密货币支付网关

  • 不错

  • 支持

  • @NSjj #10
    这是一个加密货币的支付网关。
    @布莱恩 #11
    是的!!当时第一眼看到就觉得很对味
    @coolpool #12
    理论上有,因为你不能阻拦任何人给你付款,系统也没办法在付款完成前得知谁要给你付款,因此这个风控是没有的。
    @koudai #13
    收到,会开始逐步做插件
    @verse4 #21
    参与了,做了一遍白盒测试
    @ddkiss #23
    已严肃支持
    @0x20x2 #22
    会的,做这个是我自己有需求,所以会持续更新
    @bluecode #27
    是的,大部分转账添加备注时都需要额外的手续费,并且也增加了付款难度

  • 有能力支付加密货币的用户也越来越多,真的吗 ac01

  • @pursuer #34 xhj027 目前u卡普及率我是感觉越来越高了,用u卡就非常有机会接触到交易所。虽然大陆监管上越来越严,但是私下交易越来越方便

  • 太牛了

  • @outtime #35 发布于2026/7/6 12:23:39
    @pursuer #34 xhj027 目前u卡普及率我是感觉越来越高了,用u卡就非常有机会接触到交易所。虽然大陆监管上越来越严,但是私下交易越来越方便

    @outtime #35 私下交易越来越方便 ac01
    老哥有空研究研究国内蓝绿怎么安全收款呗 ac08

  • 佬,怎么蓝绿呀

  • 不错,偷懒让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是不是没有功能啊?连订单推送都没

你好啊,陌生人!

我的朋友,看起来你是新来的,如果想参与到讨论中,点击下面的按钮!

📈用户数目📈

目前论坛共有72280位seeker

🎉欢迎新用户🎉