🌉 核心定位

🔗 支付网关 = 商户系统 ↔ 银行系统 的翻译官

负责交易路由、协议转换、数据加密、结果通知

🏢 主流网关对比

网关 用户量 覆盖 特点
💙 支付宝 10亿+ 中国 功能最全、AI风控、刷脸支付
💚 微信支付 13亿+ 中国 小程序生态、私域流量
💜 Stripe 全球 135+国家 开发者友好、多币种
💙 PayPal 4亿+ 190+国家 跨境支付、买家保护

🔧 集成四步走

📝
1. 注册商户
  • 营业执照
  • 法人身份证
  • 银行账户
🔑
2. 获取密钥
  • merchant_id
  • API Key
  • 应用AppID
📦
3. 接入SDK
  • 服务端SDK
  • 客户端SDK
  • 配置密钥
🧪
4. 沙箱测试
  • 下单接口
  • 回调通知
  • 退款流程

🔥🔥🔥 核心难点(必看)

🔐 1. 签名机制

🔍 签名机制原理

所有请求必须带签名,防止数据被篡改

1
参数排序
按字典序排列参数
2
字符串拼接
添加密钥拼接
3
加密生成
HMAC-SHA256
🔐 签名算法实现

下面是完整的签名生成和验证过程:


# 签名算法实现详解
import hmac
import hashlib

# 步骤1: 参数预处理
def prepare_params(raw_params):
    # 移除签名字段并按字典序排序
    clean_params = {k: v for k, v in raw_params.items() if k != 'sign'}
    return sorted(clean_params.items())

# 步骤2: 生成签名
def generate_signature(params, secret_key):
    # 按参数名排序
    sorted_params = prepare_params(params)
    
    # 拼接参数字符串
    param_str = "&".join([f"{k}={v}" for k, v in sorted_params])
    
    # 添加密钥并生成签名
    sign_str = f"{param_str}&key={secret_key}"
    
    # 使用HMAC-SHA256生成签名
    sign = hmac.new(
        secret_key.encode('utf-8'),
        sign_str.encode('utf-8'),
        hashlib.sha256
    ).hexdigest().lower()  # 转换为小写
    
    return sign

# 步骤3: 验证签名
def verify_signature(received_params, received_sign, secret_key):
    # 重新计算签名
    expected_sign = generate_signature(received_params, secret_key)
    
    # 安全比较(防止时序攻击)
    return hmac.compare_digest(expected_sign, received_sign.lower())

# 使用示例
sample_params = {
    "amount": "100.00",
    "currency": "CNY",
    "merchant_id": "M123456",
    "order_id": "ORD20230101001",
    "timestamp": "1672531200"
}
api_secret = "your_super_secret_api_key_here"

calculated_signature = generate_signature(sample_params, api_secret)
print(f"计算得到的签名: {calculated_signature}")

# 验证签名
is_valid = verify_signature(sample_params, calculated_signature, api_secret)
print(f"签名是否有效: {is_valid}")
                    
⚠️ 难点:3秒内必须返回"success",否则平台会重试

🔄 3. 幂等性设计

✅ 幂等性

同一个请求重复执行,结果一致

👤
用户
🖱️
重复点击
📦
幂等处理
结果一致
💡 为什么要幂等?
  • • 用户重复点击支付按钮
  • • 网络超时导致重试
  • • 回调重复通知

# 使用唯一订单号作为幂等键
def create_order(out_trade_no, amount):
    # 检查订单是否已存在
    order = db.get_order(out_trade_no)
    if order:
        return order  # 已存在,直接返回

    # 不存在,创建新订单
    order = db.create_order(...)
    return order
                    
💡 核心:用 out_trade_no(商户订单号)作为唯一约束

4. 超时与状态查询

⏱️ 超时处理

支付超时了怎么办?

🕐
超时发生
🔍
主动查询
📊
确认状态
🔄 解决方案:主动查询

支付成功后,页面卡住了 → 调用查询接口确认状态


# 超时后的处理流程
def pay_with_timeout(order_id):
    try:
        result = request_payment(order_id, timeout="30s")
    except Timeout:
        # 超时了?立即查询状态
        status = query_order_status(order_id)
        if status == "SUCCESS":
            return "已支付"
        else:
            return "支付中,请稍后查询"
                    
⚠️ 难点:订单状态以查询结果为准,别信前端

📋 订单状态流转

CREATED
订单创建
WAIT_PAY
等待支付
SUCCESS
支付成功
REFUND
已退款
WAIT_PAY
等待支付
CLOSED
超时关闭

⚠️ 常见错误码

错误码 含义 解决方案
1001参数错误检查必填参数是否完整
1002签名失败检查签名算法和密钥
1003订单不存在检查订单号是否正确
1004订单状态异常别重复操作,换查询接口
1005余额不足提示用户充值
1006系统繁忙稍后重试

📡 四个核心接口

📝 接口清单

1. 统一下单 /api/payment/create - 创建支付订单
2. 支付查询 /api/payment/query - 查询订单状态
3. 申请退款 /api/payment/refund - 退款操作
4. 异步回调 商户提供notify_url - 接收支付结果