Files
soul/addons/Universal_Payment_Module copy/1_核心设计_通用协议/安全与合规.md
卡若 b60edb3d47 feat: 完整重构小程序匹配功能 + 修复UI对齐 + 文章数据API
主要更新:
1. 按H5网页端完全重构匹配功能(match页面)
   - 4种匹配类型: 创业合伙/资源对接/导师顾问/团队招募
   - 资源对接等类型弹出手机号/微信号输入框
   - 去掉重新匹配按钮,改为返回按钮

2. 修复所有卡片对齐和宽度问题
   - 目录页附录卡片居中
   - 首页阅读进度卡片满宽度
   - 我的页面菜单卡片对齐
   - 推广中心分享卡片统一宽度

3. 修复目录页图标和文字对齐
   - section-icon固定40rpx宽高
   - section-title与图标垂直居中

4. 更新真实完整文章标题(62篇)
   - 从book目录读取真实markdown文件名
   - 替换之前的简化标题

5. 新增文章数据API
   - /api/db/chapters - 获取完整书籍结构
   - 支持按ID获取单篇文章内容
2026-01-21 15:49:12 +08:00

8.1 KiB

支付安全与合规指南 (Security & Compliance) v4.0

支付系统安全最佳实践,保护你的资金和用户数据

🔐 密钥安全

1. 密钥存储原则

❌ 错误做法:
- 将密钥硬编码在代码中
- 将密钥提交到 Git 仓库
- 通过即时通讯工具传输密钥
- 使用弱密码作为 API Key

✅ 正确做法:
- 使用环境变量存储密钥
- 使用专业密钥管理服务 (AWS KMS, HashiCorp Vault)
- 定期轮换密钥
- 最小权限原则

2. .gitignore 必须包含

# 支付密钥相关
.env
.env.local
.env.*.local
*.pem
*.key
cert/
config/payment.yml
secrets/

3. 密钥轮换

  • 定期更换 API 密钥 (建议每 90 天)
  • 发现泄露立即作废并重新生成
  • 保留旧密钥短暂过渡期

🔒 通信安全

1. HTTPS 强制

# Nginx 配置示例
server {
    listen 80;
    server_name your-domain.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name your-domain.com;
    
    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    
    # HSTS
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}

2. 证书管理

  • 使用受信任的 CA 签发证书
  • 定期检查证书有效期
  • 推荐 Let's Encrypt 自动续期

签名验证

1. 支付宝签名验证

from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
import base64

def verify_alipay_sign(params: dict, sign: str, public_key: str) -> bool:
    """验证支付宝签名"""
    # 1. 参数排序
    sorted_params = sorted([(k, v) for k, v in params.items() if k != 'sign' and v])
    
    # 2. 拼接待签名字符串
    sign_str = '&'.join([f'{k}={v}' for k, v in sorted_params])
    
    # 3. RSA2 验签
    key = RSA.import_key(f"-----BEGIN PUBLIC KEY-----\n{public_key}\n-----END PUBLIC KEY-----")
    verifier = PKCS1_v1_5.new(key)
    hash_obj = SHA256.new(sign_str.encode('utf-8'))
    
    try:
        verifier.verify(hash_obj, base64.b64decode(sign))
        return True
    except (ValueError, TypeError):
        return False

2. 微信签名验证

import hashlib

def verify_wechat_sign(params: dict, sign: str, api_key: str) -> bool:
    """验证微信支付签名"""
    # 1. 参数排序
    sorted_params = sorted([(k, v) for k, v in params.items() if k != 'sign' and v])
    
    # 2. 拼接待签名字符串
    sign_str = '&'.join([f'{k}={v}' for k, v in sorted_params])
    sign_str += f'&key={api_key}'
    
    # 3. MD5 签名
    calculated_sign = hashlib.md5(sign_str.encode('utf-8')).hexdigest().upper()
    
    return calculated_sign == sign

💰 金额校验

1. 回调金额必须验证

def handle_payment_notify(trade_sn: str, paid_amount: int):
    """处理支付回调时必须验证金额"""
    trade = get_trade_by_sn(trade_sn)
    
    # 金额必须严格匹配
    if paid_amount != trade.cash_amount:
        log.error(f"金额不匹配! 订单:{trade.cash_amount}, 回调:{paid_amount}")
        raise AmountMismatchError()
    
    # 继续处理...

2. 防止金额篡改

# 前端传入的金额仅用于展示,实际金额从后端订单读取
def checkout(order_sn: str, gateway: str):
    order = get_order(order_sn)
    
    # 金额从数据库读取,不信任前端
    amount = order.pay_amount
    
    return create_trade(order_sn, amount, gateway)

🛡️ 回调安全

1. IP 白名单

# 支付平台回调 IP 白名单
PAYMENT_IP_WHITELIST = {
    'alipay': [
        '110.75.0.0/16',
        '203.209.0.0/16'
    ],
    'wechat': [
        '101.226.0.0/16',
        '140.207.0.0/16'
    ]
}

def verify_callback_ip(gateway: str, client_ip: str) -> bool:
    """验证回调来源 IP"""
    import ipaddress
    
    whitelist = PAYMENT_IP_WHITELIST.get(gateway, [])
    client = ipaddress.ip_address(client_ip)
    
    for cidr in whitelist:
        if client in ipaddress.ip_network(cidr):
            return True
    
    return False

2. 防重放攻击

import time

def check_notify_timestamp(timestamp: int) -> bool:
    """检查回调时间戳,防止重放攻击"""
    now = int(time.time())
    
    # 允许 5 分钟的时间差
    if abs(now - timestamp) > 300:
        log.warning(f"回调时间戳异常: {timestamp}")
        return False
    
    return True

3. 幂等性处理

def process_notify_idempotent(trade_sn: str, notify_data: dict):
    """幂等性处理回调"""
    
    # 使用分布式锁
    lock_key = f"payment_notify:{trade_sn}"
    
    with redis_lock(lock_key, timeout=10):
        trade = get_trade_by_sn(trade_sn)
        
        # 已处理过,直接返回成功
        if trade.status == 'paid':
            return success_response()
        
        # 处理支付成功逻辑
        update_trade_to_paid(trade, notify_data)
        
    return success_response()

📝 日志审计

1. 必须记录的日志

import logging

payment_logger = logging.getLogger('payment')

# 创建交易日志
payment_logger.info(f"创建交易 | trade_sn={trade_sn} | order_sn={order_sn} | amount={amount} | gateway={gateway}")

# 回调日志
payment_logger.info(f"收到回调 | gateway={gateway} | trade_sn={trade_sn} | raw_data={raw_data[:500]}")

# 签名验证日志
payment_logger.info(f"签名验证 | trade_sn={trade_sn} | result={verify_result}")

# 状态变更日志
payment_logger.info(f"状态变更 | trade_sn={trade_sn} | from={old_status} | to={new_status}")

# 退款日志
payment_logger.info(f"发起退款 | refund_sn={refund_sn} | trade_sn={trade_sn} | amount={amount}")

2. 敏感信息脱敏

def mask_sensitive(data: dict) -> dict:
    """敏感信息脱敏"""
    sensitive_keys = ['card_no', 'id_card', 'phone', 'bank_account']
    
    masked = data.copy()
    for key in sensitive_keys:
        if key in masked:
            value = str(masked[key])
            if len(value) > 4:
                masked[key] = value[:2] + '*' * (len(value) - 4) + value[-2:]
    
    return masked

🚨 异常处理

1. 支付异常分类

class PaymentError(Exception):
    """支付基础异常"""
    pass

class SignatureError(PaymentError):
    """签名验证失败"""
    pass

class AmountMismatchError(PaymentError):
    """金额不匹配"""
    pass

class OrderExpiredError(PaymentError):
    """订单已过期"""
    pass

class DuplicatePaymentError(PaymentError):
    """重复支付"""
    pass

class RefundError(PaymentError):
    """退款失败"""
    pass

2. 统一异常处理

@app.exception_handler(PaymentError)
async def payment_exception_handler(request, exc):
    return JSONResponse(
        status_code=400,
        content={
            "code": 400,
            "message": str(exc),
            "data": None
        }
    )

合规要求

1. PCI DSS 合规 (信用卡)

  • 不存储完整卡号、CVV、PIN
  • 使用 Stripe/PayPal 等符合 PCI DSS 的支付网关
  • 定期安全评估

2. GDPR 合规 (欧盟用户)

  • 明确告知用户数据用途
  • 提供数据删除功能
  • 用户同意授权

3. 中国支付合规

  • 接入持牌支付机构
  • 实名认证
  • 交易限额管理

📋 安全检查清单

## 上线前安全检查

### 密钥管理
- [ ] 所有密钥通过环境变量配置
- [ ] 密钥未提交到代码仓库
- [ ] 生产环境密钥与测试环境隔离

### 通信安全
- [ ] 启用 HTTPS
- [ ] 证书有效且受信任
- [ ] 启用 HSTS

### 签名验证
- [ ] 所有回调验签
- [ ] 验签失败拒绝处理

### 金额校验
- [ ] 回调金额与订单金额比对
- [ ] 金额从后端读取

### 日志审计
- [ ] 关键操作有日志
- [ ] 敏感信息脱敏

### 异常处理
- [ ] 异常不泄露敏感信息
- [ ] 有统一异常处理

### 回调安全
- [ ] IP 白名单验证 (可选)
- [ ] 幂等性处理
- [ ] 防重放攻击