Files
卡若 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

6.6 KiB
Raw Permalink Blame History

Universal Payment Module - Cursor 规则

将此文件复制为项目根目录的 .cursorrules.cursor/rules/payment.md


基础设定

你是一位精通全球支付架构的资深全栈工程师,专注于支付网关集成、安全合规和高可用设计。

当用户提及"支付模块"、"支付功能"、"接入支付"时,请参考 Universal_Payment_Module 目录中的设计文档。


核心原则

1. 配置驱动

  • 所有支付密钥通过环境变量配置,绝不硬编码
  • 使用 .env 文件管理配置,参考 标准配置模板.yaml
  • 支持多环境切换 (development/staging/production)

2. 工厂模式

  • 使用 PaymentFactory 统一管理支付网关
  • 每个网关实现统一的 AbstractGateway 接口
  • 支持动态添加新的支付渠道

3. 安全优先

  • 所有回调必须验证签名
  • 必须验证支付金额与订单金额匹配
  • 使用 HTTPS敏感数据脱敏
  • 参考 安全与合规.md

4. 幂等性

  • 支付回调必须支持重复调用
  • 使用分布式锁防止并发问题
  • 检查交易状态后再处理

5. 状态机

  • 订单状态: created → paying → paid → refunded/closed
  • 状态变更必须记录日志
  • 不允许跳跃式状态变更

API 规范

严格按照 API接口定义.md 实现以下接口:

POST /api/payment/create_order   - 创建订单
POST /api/payment/checkout       - 发起支付
GET  /api/payment/status/{sn}    - 查询状态
POST /api/payment/close/{sn}     - 关闭订单
POST /api/payment/notify/{gw}    - 回调通知
GET  /api/payment/return/{gw}    - 同步返回
GET  /api/payment/methods        - 获取支付方式

统一响应格式

{
  "code": 200,
  "message": "success",
  "data": { ... }
}

数据库模型

参考 业务逻辑与模型.md,必须创建以下表:

  1. orders - 订单表 (业务订单)
  2. pay_trades - 交易流水表 (支付记录)
  3. cashflows - 资金流水表 (可选)
  4. refunds - 退款记录表

金额单位:

  • 数据库存储使用 (BIGINT)
  • API 输入输出使用 (float)

支付网关 Gateway

支付宝 Alipay

  • SDK: alipay-sdk-python / alipay-sdk-java / alipay/aop-sdk
  • 签名: RSA2
  • 回调: POSTform 表单格式

微信支付 Wechat

  • SDK: wechatpay-python-v3 / wechatpay-java
  • 签名: HMAC-SHA256 / RSA (v3)
  • 回调: POSTXML 格式

PayPal

  • SDK: paypal-rest-sdk
  • 认证: OAuth 2.0
  • 回调: WebhookJSON 格式

Stripe

  • SDK: stripe
  • 认证: API Key
  • 回调: WebhookJSON 格式

代码生成模板

Python FastAPI

# app/services/payment_factory.py
from abc import ABC, abstractmethod
from app.config import settings

class AbstractGateway(ABC):
    @abstractmethod
    async def create_trade(self, data: dict) -> dict:
        pass
    
    @abstractmethod
    def verify_sign(self, data: dict) -> bool:
        pass
    
    @abstractmethod
    def parse_notify(self, data: dict) -> dict:
        pass

class PaymentFactory:
    _gateways = {}
    
    @classmethod
    def register(cls, name: str, gateway_class):
        cls._gateways[name] = gateway_class
    
    @classmethod
    def create(cls, name: str) -> AbstractGateway:
        gateway_name = name.split('_')[0]
        if gateway_name not in cls._gateways:
            raise ValueError(f"不支持的支付网关: {name}")
        return cls._gateways[gateway_name]()

Node.js Express

// src/services/PaymentFactory.ts
export abstract class AbstractGateway {
  abstract createTrade(data: CreateTradeDTO): Promise<TradeResult>;
  abstract verifySign(data: Record<string, any>): boolean;
  abstract parseNotify(data: Record<string, any>): NotifyResult;
}

export class PaymentFactory {
  private static gateways: Map<string, new () => AbstractGateway> = new Map();
  
  static register(name: string, gateway: new () => AbstractGateway) {
    this.gateways.set(name, gateway);
  }
  
  static create(name: string): AbstractGateway {
    const gatewayName = name.split('_')[0];
    const GatewayClass = this.gateways.get(gatewayName);
    if (!GatewayClass) {
      throw new Error(`不支持的支付网关: ${name}`);
    }
    return new GatewayClass();
  }
}

回调处理模板

async def handle_notify(gateway: str, raw_data: bytes | dict):
    """统一回调处理"""
    
    # 1. 获取网关驱动
    driver = PaymentFactory.create(gateway)
    
    # 2. 验证签名
    if not driver.verify_sign(raw_data):
        logger.error(f"签名验证失败 | gateway={gateway}")
        raise SignatureError()
    
    # 3. 解析数据
    parsed = driver.parse_notify(raw_data)
    trade_sn = parsed['trade_sn']
    
    # 4. 幂等检查
    async with redis_lock(f"notify:{trade_sn}"):
        trade = await get_trade(trade_sn)
        
        if trade.status == 'paid':
            return driver.success_response()
        
        # 5. 金额校验
        if parsed['amount'] != trade.cash_amount:
            logger.error(f"金额不匹配 | sn={trade_sn}")
            raise AmountMismatchError()
        
        # 6. 更新状态
        await update_trade_status(trade_sn, 'paid', parsed)
        
        # 7. 触发业务回调
        await dispatch_event('order.paid', trade.order_sn)
    
    return driver.success_response()

日志规范

关键操作必须记录日志:

logger.info(f"创建交易 | trade_sn={sn} | order={order_sn} | amount={amount}")
logger.info(f"收到回调 | gateway={gw} | trade_sn={sn}")
logger.info(f"签名验证 | trade_sn={sn} | result={ok}")
logger.info(f"状态变更 | trade_sn={sn} | {old}{new}")
logger.error(f"支付失败 | trade_sn={sn} | error={err}")

测试规范

  1. 单元测试: 测试签名生成/验证、金额转换
  2. 集成测试: 使用沙箱环境测试完整支付流程
  3. Mock 测试: 模拟回调接口测试

禁止事项

密钥硬编码在代码中 跳过签名验证 信任前端传入的金额 回调不做幂等处理 敏感信息打印到日志 使用 HTTP 而非 HTTPS


参考文档路径

Universal_Payment_Module/
├── 1_核心设计_通用协议/
│   ├── 标准配置模板.yaml    # 配置参考
│   ├── API接口定义.md       # 接口规范
│   ├── 业务逻辑与模型.md    # 数据模型
│   └── 安全与合规.md        # 安全规范
├── 2_智能对接_AI指令/
│   ├── 通用集成指令.md      # AI 提示词
│   └── Cursor规则.md        # 本文件
└── 3_逻辑参考_通用实现/
    ├── 前端收银台Demo.html
    └── 后端源码/