Appearance
支付开发指南
概述
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 支付场景枚举
场景 | 说明 | 适用渠道 |
---|---|---|
h5 | H5支付 | 微信、支付宝 |
pc | PC支付 | 微信、支付宝 |
app | APP支付 | 微信、支付宝 |
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_type | require|checkSourceType | 来源类型必填,值必须有效 (order, recharge, order_merge) |
source_id | integer | 来源ID必须为整数 |
pay_merchant_id | require|integer | 商户ID必填且为整数 |
pay_channel | require|checkPayChannel | 支付渠道必填且有效 (wechat_pay, ali_pay, balance_pay) |
pay_scene | require|checkPayScene | 支付场景必填且有效 (h5, pc, app, wechat_official, wechat_mini) |
pay_amount | require|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技术团队