Skip to content

支付开发指南

概述

DSMall Pro 支付系统基于 Yansongda Pay v3 构建,支持微信支付、支付宝等多种支付方式。系统采用驱动模式设计,支持多种支付场景和渠道。

环境要求

1. 依赖安装

系统使用以下Composer包:

bash
# 安装Yansongda Pay v3支付SDK
composer require yansongda/pay:~3.7.0 -vvv

# 安装依赖注入容器
composer require hyperf/pimple:~2.2.0

2. 系统要求

  • PHP >= 7.4
  • ThinkPHP 8.0+
  • Composer 2.0+

3. 官方文档

支付架构

1. 架构图

前端应用 → API接口 → 支付服务 → 第三方支付驱动 → 支付平台
    ↓         ↓         ↓           ↓            ↓
  Vue3    TradePay   TradePayService  Wechat/Alipay  微信/支付宝

2. 核心组件

  • ThirdPartyLoader: 第三方服务加载器
  • TradeManager: 支付驱动管理器
  • BaseTrade: 支付驱动基类
  • Wechat: 微信支付驱动
  • Alipay: 支付宝支付驱动
  • TradePayService: 支付业务服务
  • TradeNotifyService: 支付回调服务
  • TradePaymentConfigEnum: 支付配置枚举

数据库设计

1. 支付相关数据表

系统涉及以下支付相关的数据表:

表名说明主要用途
ds_trade_pay_log用户支付记录记录所有支付交易
ds_trade_refund_log交易退款记录记录退款操作
ds_trade_transfer_log交易转账表记录转账操作
ds_trade_payment_config支付配置表存储支付渠道配置
ds_user_recharge_log用户充值记录记录用户充值
ds_user_withdrawal_log用户提现记录记录用户提现
ds_user_withdrawal_account用户提现账户表存储用户提现账户

2. 核心数据表结构

2.1 支付记录表 (ds_trade_pay_log)

sql
CREATE TABLE `ds_trade_pay_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL COMMENT '支付用户ID',
  `source_type` varchar(20) NOT NULL COMMENT '来源类型 比如订单,充值',
  `source_id` int(11) NOT NULL COMMENT '来源ID',
  `out_trade_no` varchar(32) DEFAULT NULL COMMENT '商户订单号',
  `trade_no` varchar(32) DEFAULT NULL COMMENT '支付订单号 微信中参数是 transaction_id',
  `pay_merchant_id` int(11) NOT NULL COMMENT '收款商户ID  0为后台收款',
  `pay_channel` varchar(20) DEFAULT NULL COMMENT '支付渠道 alipay wechat',
  `pay_scene` varchar(20) DEFAULT NULL COMMENT '支付场景 H5 APP支付等',
  `pay_amount` decimal(20,4) NOT NULL COMMENT '支付金额',
  `pay_status` int(11) NOT NULL COMMENT '支付状态 0 未支付 1已支付 2已关闭',
  `buyer_id` varchar(128) DEFAULT NULL COMMENT '付款号 支付宝 buyer_id 微信  openid',
  `seller_id` varchar(32) DEFAULT NULL COMMENT '收款号 支付宝 seller_id 微信 mchid',
  `pay_time` int(11) DEFAULT NULL COMMENT '支付时间',
  `close_time` int(11) DEFAULT NULL COMMENT '关闭时间',
  `create_at` int(11) NOT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `udx_out_trade_no` (`out_trade_no`),
  UNIQUE KEY `udx_trade_no` (`trade_no`),
  KEY `idx_user_id` (`user_id`),
  KEY `idx_source_type` (`source_type`),
  KEY `idx_source_id` (`source_id`),
  KEY `idx_pay_merchant_id` (`pay_merchant_id`),
  KEY `idx_pay_channel` (`pay_channel`),
  KEY `idx_pay_scene` (`pay_scene`),
  KEY `idx_pay_status` (`pay_status`),
  KEY `idx_pay_time` (`pay_time`),
  KEY `idx_create_at` (`create_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户支付记录';

2.2 退款记录表 (ds_trade_refund_log)

sql
CREATE TABLE `ds_trade_refund_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL COMMENT '退款用户ID',
  `source_type` varchar(20) NOT NULL COMMENT '来源 退款',
  `source_id` int(11) NOT NULL COMMENT '来源ID',
  `out_trade_no` varchar(32) DEFAULT NULL COMMENT '商户订单号',
  `trade_no` varchar(32) DEFAULT NULL COMMENT '支付订单号',
  `out_refund_no` varchar(32) NOT NULL COMMENT '商户退款单号',
  `pay_amount` decimal(20,4) NOT NULL COMMENT '支付金额',
  `refund_merchant_id` int(11) NOT NULL COMMENT '退款商户ID',
  `refund_amount` decimal(20,4) NOT NULL COMMENT '退款金额',
  `refund_channel` varchar(20) NOT NULL COMMENT '支付渠道',
  `refund_scene` varchar(20) DEFAULT NULL COMMENT '支付场景 H5 APP',
  `refund_status` tinyint(4) NOT NULL COMMENT '退款状态 0待退款 1退款完成 2退款关闭',
  `refund_time` int(11) NOT NULL COMMENT '退款时间',
  `close_time` int(11) DEFAULT NULL COMMENT '关闭时间',
  `create_at` int(11) DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `udx_out_refund_no` (`out_refund_no`),
  KEY `idx_user_id` (`user_id`),
  KEY `idx_source_type` (`source_type`),
  KEY `idx_source_id` (`source_id`),
  KEY `idx_out_trade_no` (`out_trade_no`),
  KEY `idx_trade_no` (`trade_no`),
  KEY `idx_refund_merchant_id` (`refund_merchant_id`),
  KEY `idx_refund_channel` (`refund_channel`),
  KEY `idx_refund_status` (`refund_status`),
  KEY `idx_refund_time` (`refund_time`),
  KEY `idx_create_at` (`create_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='交易退款记录';

2.3 转账记录表 (ds_trade_transfer_log)

sql
CREATE TABLE `ds_trade_transfer_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL COMMENT '用户ID',
  `source_type` varchar(20) NOT NULL COMMENT '关联类型 提现',
  `source_id` int(11) NOT NULL COMMENT '关联ID',
  `out_transfer_no` varchar(32) NOT NULL COMMENT '微信out_bill_no 支付宝out_biz_no',
  `transfer_no` varchar(32) DEFAULT NULL COMMENT '转账单号',
  `transfer_type` varchar(20) NOT NULL COMMENT '转账类型 支付宝、微信',
  `transfer_amount` decimal(20,4) NOT NULL COMMENT '转账金额',
  `transfer_status` tinyint(4) NOT NULL COMMENT '状态 0 失败 1成功',
  `transfer_response` text COMMENT '返回结果',
  `account_type` varchar(20) NOT NULL COMMENT '提现账户类型',
  `account_name` varchar(20) NOT NULL COMMENT '账户名称 支付宝、微信、银行卡',
  `account_number` varchar(32) NOT NULL COMMENT '卡号',
  `account_holder` varchar(10) NOT NULL COMMENT '持有人',
  `create_at` int(11) DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `udx_out_transfer_no` (`out_transfer_no`),
  KEY `idx_user_id` (`user_id`),
  KEY `idx_source_type` (`source_type`),
  KEY `idx_source_id` (`source_id`),
  KEY `idx_transfer_no` (`transfer_no`),
  KEY `idx_transfer_type` (`transfer_type`),
  KEY `idx_transfer_status` (`transfer_status`),
  KEY `idx_account_type` (`account_type`),
  KEY `idx_create_at` (`create_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='交易转账表';

2.4 支付配置表 (ds_trade_payment_config)

sql
CREATE TABLE `ds_trade_payment_config` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `merchant_id` int(11) NOT NULL COMMENT '商户ID  0为系统',
  `payment_channel` varchar(20) NOT NULL COMMENT '支付渠道 WECHAT ALIPAY',
  `payment_scene` varchar(20) NOT NULL COMMENT '支付场景 H5  PC 小程序 等支付方式',
  `config_data` text COMMENT '支付配置',
  `is_enabled` tinyint(4) DEFAULT NULL COMMENT '是否启用 0未启用 1启用',
  `sort` int(11) NOT NULL DEFAULT '0' COMMENT '排序',
  `create_at` int(11) NOT NULL COMMENT '创建时间',
  `update_at` int(11) DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `udx_merchant_channel_scene` (`merchant_id`, `payment_channel`, `payment_scene`),
  KEY `idx_payment_channel` (`payment_channel`),
  KEY `idx_payment_scene` (`payment_scene`),
  KEY `idx_is_enabled` (`is_enabled`),
  KEY `idx_sort` (`sort`),
  KEY `idx_create_at` (`create_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='支付配置表';

2.5 用户充值记录表 (ds_user_recharge_log)

sql
CREATE TABLE `ds_user_recharge_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `out_trade_no` varchar(32) DEFAULT NULL COMMENT '支付单号',
  `trade_no` varchar(32) DEFAULT NULL COMMENT '第三方平台交易号',
  `pay_merchant_id` int(11) NOT NULL COMMENT '支付商户ID 0为系统收款',
  `pay_channel` varchar(20) DEFAULT NULL COMMENT '支付渠道 alipay wechat',
  `pay_scene` varchar(20) DEFAULT NULL COMMENT '支付场景 H5 PC 等',
  `recharge_amount` decimal(20,4) DEFAULT NULL COMMENT '充值金额',
  `recharge_status` tinyint(4) DEFAULT NULL COMMENT '充值状态 0未支付 1完成',
  `pay_time` int(11) DEFAULT NULL COMMENT '支付完成时间',
  `create_at` int(11) DEFAULT NULL COMMENT '创建时间',
  `update_at` int(11) DEFAULT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户充值记录';

2.6 用户提现记录表 (ds_user_withdrawal_log)

sql
CREATE TABLE `ds_user_withdrawal_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `out_transfer_no` varchar(32) DEFAULT NULL COMMENT '微信out_bill_no 支付宝out_biz_no',
  `transfer_type` varchar(10) DEFAULT NULL COMMENT '转账类型 微信 支付宝 手工转',
  `transfer_remark` varchar(255) DEFAULT NULL COMMENT '转账备注,针对手工转账',
  `account_type` varchar(10) DEFAULT NULL COMMENT '提现账户类型',
  `account_name` varchar(20) DEFAULT NULL COMMENT '名称',
  `account_number` varchar(32) DEFAULT NULL COMMENT '卡号',
  `account_holder` varchar(10) DEFAULT NULL COMMENT '持有人',
  `apply_amount` decimal(20,4) DEFAULT NULL COMMENT '申请提现金额',
  `fee_amount` decimal(20,4) DEFAULT NULL COMMENT '手续费',
  `withdrawal_amount` decimal(20,4) DEFAULT NULL COMMENT '提现金额',
  `operation_time` int(11) DEFAULT NULL COMMENT '处理时间',
  `operation_remark` varchar(255) DEFAULT NULL COMMENT '处理备注',
  `status` tinyint(4) DEFAULT '0' COMMENT '状态 待审核 通过  拒绝',
  `create_at` int(11) DEFAULT NULL,
  `update_at` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户提现记录';

3. 字段说明

3.1 支付状态枚举

状态值说明适用表
0未支付/待处理pay_status, refund_status, transfer_status
1已支付/成功pay_status, refund_status, transfer_status
2已关闭/失败pay_status, refund_status

3.2 来源类型枚举

类型说明适用场景
order订单支付商品订单支付
recharge充值用户余额充值
refund退款订单退款
withdrawal提现用户余额提现

3.3 支付渠道枚举

渠道说明支持场景
wechat_pay微信支付公众号、小程序、H5、APP、扫码
ali_pay支付宝网页、H5、APP
balance_pay余额支付所有场景
offline_pay线下付款所有场景

3.4 支付场景枚举

场景说明适用渠道
h5H5支付微信、支付宝
pcPC支付微信、支付宝
appAPP支付微信、支付宝
wechat_official微信公众号支付微信
wechat_mini微信小程序支付微信
douyin_mini抖音小程序支付抖音

支付配置

1. 支付渠道配置

系统支持以下支付渠道:

渠道标识说明
微信支付wechat_pay微信支付
支付宝ali_pay支付宝支付
余额支付balance_pay系统余额支付
线下付款offline_pay线下付款

2. 支付场景配置

系统支持以下支付场景:

场景标识说明
APP支付app移动应用支付
H5支付h5手机网页支付
公众号支付wechat_official微信公众号支付
小程序支付wechat_mini微信小程序支付
PC支付pc电脑网页支付
抖音小程序douyin_mini抖音小程序支付

API接口开发

1. 发起支付接口

接口地址: POST /api/trade/pay

请求参数:

json
{
    "source_type": "order",           // 来源类型: recharge充值, order订单, order_merge合并订单
    "source_id": 1,                  // 来源ID
    "pay_merchant_id": 1,            // 商户ID
    "pay_channel": "wechat_pay",     // 支付渠道: wechat_pay微信, ali_pay支付宝, balance_pay余额
    "pay_scene": "wechat_official",  // 支付场景: app应用, h5网页, wechat_official公众号, wechat_mini小程序
    "pay_amount": 100.00             // 支付金额
}

响应示例:

json
{
    "code": 10000,
    "msg": "操作成功",
    "data": {
        "out_trade_no": "wec202501151234567890",
        "pay_url": "https://pay.weixin.qq.com/...",
        "qr_code": "weixin://wxpay/..."
    }
}

2. 获取支付方式接口

接口地址: GET /api/trade/payment/list

请求参数:

json
{
    "pay_merchant_id": 1,            // 商户ID
    "pay_scene": "wechat_official", // 支付场景
    "pay_type": "wechat_pay"         // 支付类型
}

3. 支付回调接口

接口地址: POST /api/trade/notify/{merchant_id}/{trade_channel}/{trade_scene}/{trade_type}/

说明: 第三方支付平台回调接口,用于处理支付结果通知。注意URL末尾有斜杠。

支付驱动开发

1. 第三方服务加载器

系统使用 ThirdPartyLoader 来加载和管理第三方支付服务:

php
<?php

namespace app\deshang\core;

class ThirdPartyLoader
{
    /**
     * 交易相关
     * @param int $merchant_id 商户id
     * @param string $trade_channel 交易渠道
     * @param string $trade_scene 交易场景
     * @param string $trade_type 交易类型
     * @param string $return_url 返回地址
     * @param string $quit_url 退出地址
     * @return TradeManager
     */
    public static function trade($merchant_id, $trade_channel, $trade_scene, $trade_type, $return_url = '', $quit_url = '')
    {
        // 获取支付配置
        $data = [
            'merchant_id' => $merchant_id,
            'payment_channel' => $trade_channel,
            'payment_scene' => $trade_scene,
            'is_enabled' => 1,
        ];

        $result = (new DeshangTradePaymentConfigService())->getPaymentConfigInfo($data);

        if (empty($result)) {
            throw new CommonException('支付配置未开启');
        }

        // 设置回调地址和返回地址
        $result['config_data']['notify_url'] = url('/api/trade/notify/' . $merchant_id . '/' . $trade_channel . '/' . $trade_scene . '/' . $trade_type . '/', [], false, true);
        $result['config_data']['return_url'] = $return_url;
        $result['config_data']['quit_url'] = $quit_url;

        // 根据支付渠道返回对应的驱动管理器
        if ($result['payment_channel'] == TradePaymentConfigEnum::CHANNEL_ALIPAY) {
            return new TradeManager('Alipay', $result['config_data']);
        } else if ($result['payment_channel'] == TradePaymentConfigEnum::CHANNEL_WECHAT) {
            return new TradeManager('Wechat', $result['config_data']);
        } else {
            throw new CommonException('支付渠道错误,请检查配置');
        }
    }
}

2. 驱动基类

所有支付驱动都继承自 BaseTrade 基类:

php
<?php

namespace app\deshang\third_party\trade\providers;

abstract class BaseTrade
{
    // 网页支付
    abstract public function web(array $data);
    
    // 公众号支付
    abstract public function mp(array $data);
    
    // H5支付
    abstract public function h5(array $data);
    
    // APP支付
    abstract public function app(array $data);
    
    // 小程序支付
    abstract public function mini(array $data);
    
    // 扫码支付
    abstract public function scan(array $data);
    
    // 查询订单
    abstract public function query(array $data);
    
    // 退款
    abstract public function refund(array $data);
    
    // 关闭订单
    abstract public function close(array $data);
    
    // 取消订单
    abstract public function cancel(array $data);
    
    // 接收回调
    abstract public function callback();
    
    // 确认回调
    abstract public function confirm();
}

2. 微信支付驱动

2.1 配置初始化

php
public function __construct(array $config)
{
    $wechat_config = [
        'wechat' => [
            'default' => [
                'mch_id' => $config['mch_id'],                    // 商户号
                'mch_secret_key' => $config['mch_secret_key'],   // v3商户密钥
                'mch_secret_cert' => $config['mch_secret_cert_path'], // 商户私钥
                'mch_public_cert_path' => $config['mch_public_cert_path'], // 商户公钥
                'notify_url' => $config['notify_url'],           // 回调地址
                'wechat_public_cert_path' => [                   // 微信公钥
                    $config['wechat_public_cert_id'] => $config['wechat_public_cert_path']
                ],
                'mode' => Pay::MODE_NORMAL,
            ]
        ],
    ];
    
    Pay::config($wechat_config);
}

2.2 公众号支付 (wechat_official)

php
public function mp(array $data)
{
    $order = [
        'out_trade_no' => $data['out_trade_no'],
        'description' => $data['subject'],
        'amount' => [
            'total' => intval($data['total_amount'] * 100),
        ],
        'payer' => [
            'openid' => $data['openid'],
        ],
    ];
    
    $result = Pay::wechat()->mp($order);
    return $this->parseResponse($result);
}

2.3 小程序支付 (wechat_mini)

php
public function mini(array $data)
{
    $order = [
        'out_trade_no' => $data['out_trade_no'],
        'description' => $data['subject'],
        'amount' => [
            'total' => intval($data['total_amount'] * 100),
            'currency' => 'CNY',
        ],
        'payer' => [
            'openid' => $data['openid'],
        ],
    ];
    
    $result = Pay::wechat()->mini($order);
    return $this->parseResponse($result);
}

2.4 PC扫码支付 (pc)

php
public function scan(array $data)
{
    $order = [
        'out_trade_no' => $data['out_trade_no'],
        'description' => $data['subject'],
        'amount' => [
            'total' => intval($data['total_amount'] * 100),
        ],
    ];
    
    $result = Pay::wechat()->scan($order);
    return $this->parseResponse($result);
}

2.5 退款处理

php
public function refund(array $data): bool
{
    $order = [
        'out_trade_no' => $data['out_trade_no'],
        'out_refund_no' => $data['out_refund_no'],
        'amount' => [
            'refund' => intval($data['refund_amount'] * 100),
            'total' => intval($data['total_amount'] * 100),
            'currency' => 'CNY',
        ],
    ];
    
    $result = $this->parseResponse(Pay::wechat()->refund($order));
    
    // 退款成功或处理中
    return $result['status'] == 'SUCCESS' || $result['status'] == 'PROCESSING';
}

2.6 支付回调处理

php
public function callback()
{
    $result = Pay::wechat()->callback();
    $result = $this->parseResponse($result);
    
    $ciphertext = $result['resource']['ciphertext'];
    
    return [
        'status' => 'success',
        'buyer_id' => $ciphertext['payer']['openid'],
        'seller_id' => $ciphertext['mchid'],
        'trade_no' => $ciphertext['transaction_id'],
        'out_trade_no' => $ciphertext['out_trade_no'],
        'total_amount' => $ciphertext['amount']['total'] / 100,
    ];
}

3. 支付宝支付驱动

3.1 配置初始化

php
public function __construct(array $config)
{
    $alipay_config = [
        'alipay' => [
            'default' => [
                'app_id' => $config['app_id'],                           // 应用ID
                'app_secret_cert' => $config['app_secret_cert'],         // 应用私钥
                'app_public_cert_path' => $config['app_public_cert_path'], // 应用公钥
                'alipay_public_cert_path' => $config['alipay_public_cert_path'], // 支付宝公钥
                'alipay_root_cert_path' => $config['alipay_root_cert_path'],     // 支付宝根证书
                'return_url' => $config['return_url'],                   // 返回地址
                'notify_url' => $config['notify_url'],                   // 回调地址
                'mode' => Pay::MODE_NORMAL,
            ]
        ],
    ];
    
    Pay::config($alipay_config);
}

3.2 PC网页支付 (pc)

php
public function web(array $data)
{
    $order = [
        'out_trade_no' => $data['out_trade_no'],
        'total_amount' => $data['total_amount'],
        'subject' => $data['subject'],
    ];
    
    $result = Pay::alipay()->web($order);
    return $this->parseResponse($result);
}

3.3 H5支付 (h5)

php
public function h5(array $data)
{
    $order = [
        'out_trade_no' => $data['out_trade_no'],
        'total_amount' => $data['total_amount'],
        'subject' => $data['subject'],
    ];
    
    $result = Pay::alipay()->h5($order);
    return $this->parseResponse($result);
}

3.4 APP支付 (app)

php
public function app(array $data)
{
    $order = [
        'out_trade_no' => $data['out_trade_no'],
        'total_amount' => $data['total_amount'],
        'subject' => $data['subject'],
    ];
    
    $result = Pay::alipay()->app($order);
    return $this->parseResponse($result);
}

3.5 退款处理

php
public function refund(array $data): bool
{
    $order = [
        'out_trade_no' => $data['out_trade_no'],
        'refund_amount' => $data['refund_amount'],
    ];
    
    $result = $this->parseResponse(Pay::alipay()->refund($order));
    
    return $result['code'] == '10000';
}

3.6 支付回调处理

php
public function callback()
{
    $result = Pay::alipay()->callback();
    $result = $this->parseResponse($result);
    
    return [
        'status' => 'success',
        'buyer_id' => $result['buyer_id'],
        'seller_id' => $result['seller_id'],
        'trade_no' => $result['trade_no'],
        'out_trade_no' => $result['out_trade_no'],
        'total_amount' => $result['total_amount'],
    ];
}

支付流程

1. 支付创建流程

mermaid
sequenceDiagram
    participant C as 客户端
    participant A as API接口
    participant S as 支付服务
    participant D as 支付驱动
    participant P as 支付平台
    
    C->>A: 发起支付请求
    A->>S: 调用支付服务
    S->>D: 选择支付驱动
    D->>P: 调用支付平台API
    P-->>D: 返回支付参数
    D-->>S: 返回支付结果
    S-->>A: 返回支付信息
    A-->>C: 返回支付数据

2. 支付回调流程

mermaid
sequenceDiagram
    participant P as 支付平台
    participant A as API接口
    participant S as 回调服务
    participant D as 支付驱动
    participant B as 业务系统
    
    P->>A: 发送支付回调
    A->>S: 调用回调服务
    S->>D: 验证回调数据
    D->>D: 解析回调信息
    D-->>S: 返回解析结果
    S->>B: 更新订单状态
    B-->>S: 返回处理结果
    S-->>A: 返回确认响应
    A-->>P: 返回SUCCESS

参数验证

1. 支付参数验证

php
class TradePayValidate extends BaseValidate
{
    protected $rule = [
        'source_type' => 'require|checkSourceType',
        'source_id' => 'integer',
        'pay_merchant_id' => 'require|integer',
        'pay_channel' => 'require|checkPayChannel',
        'pay_scene' => 'require|checkPayScene',
        'pay_amount' => 'require|float|gt:0|max:999999.99',
    ];
    
    protected $message = [
        'source_type.require' => '来源类型不能为空',
        'pay_channel.require' => '支付渠道不能为空',
        'pay_scene.require' => '支付场景不能为空',
        'pay_amount.require' => '支付金额不能为空',
        'pay_amount.gt' => '支付金额必须大于0',
        'pay_amount.max' => '支付金额不能超过999999.99',
    ];
}

2. 验证规则说明

字段规则说明
source_typerequire|checkSourceType来源类型必填,值必须有效 (order, recharge, order_merge)
source_idinteger来源ID必须为整数
pay_merchant_idrequire|integer商户ID必填且为整数
pay_channelrequire|checkPayChannel支付渠道必填且有效 (wechat_pay, ali_pay, balance_pay)
pay_scenerequire|checkPayScene支付场景必填且有效 (h5, pc, app, wechat_official, wechat_mini)
pay_amountrequire|float|gt:0|max:999999.99支付金额必填,浮点数,大于0,最大999999.99

错误处理

1. 常见错误码

错误码说明解决方案
40001参数错误检查请求参数格式
40002商户不存在检查商户ID是否正确
40003支付渠道不支持检查支付渠道配置
40004支付场景不支持检查支付场景配置
50001支付平台错误检查第三方支付平台状态
50002网络超时重试或检查网络连接

2. 异常处理

php
try {
    $result = $this->pay($data);
} catch (CommonException $e) {
    // 业务异常
    return ds_json_error($e->getMessage());
} catch (\Exception $e) {
    // 系统异常
    return ds_json_error('支付失败,请稍后重试');
}

安全考虑

1. 签名验证

  • 所有支付回调都经过签名验证
  • 使用Yansongda Pay内置的签名验证机制
  • 确保回调数据的完整性和真实性

2. 数据加密

  • 敏感数据使用HTTPS传输
  • 支付参数进行适当的数据脱敏
  • 日志记录不包含敏感信息

3. 防重放攻击

  • 使用订单号防重复提交
  • 回调处理使用幂等性设计
  • 设置合理的超时时间

测试指南

1. 微信支付测试

php
// 测试数据
$test_data = [
    'out_trade_no' => 'test_' . time(),
    'subject' => '测试订单',
    'total_amount' => 0.01,
    'openid' => 'test_openid',
];

// 调用支付
$result = $wechat_driver->mini($test_data);

2. 支付宝测试

php
// 测试数据
$test_data = [
    'out_trade_no' => 'test_' . time(),
    'subject' => '测试订单',
    'total_amount' => 0.01,
];

// 调用支付
$result = $alipay_driver->web($test_data);

部署检查清单

环境检查

  • [ ] PHP版本 >= 7.4
  • [ ] Yansongda Pay v3 已安装
  • [ ] 支付证书文件已配置
  • [ ] 回调地址可访问

配置检查

  • [ ] 支付渠道配置正确
  • [ ] 支付场景配置正确
  • [ ] 商户信息配置正确
  • [ ] 证书路径配置正确

功能检查

  • [ ] 支付创建功能正常
  • [ ] 支付回调功能正常
  • [ ] 退款功能正常
  • [ ] 查询功能正常

安全检查

  • [ ] HTTPS配置正确
  • [ ] 签名验证正常
  • [ ] 敏感信息保护
  • [ ] 日志记录安全

最后更新:2024-01-20
维护者:DSPlatform技术团队