Skip to content

支付管理

1. 功能概述

支付管理模块是系统的重要组成部分,负责处理支付相关的所有功能,包含以下主要模块:

  • 支付渠道管理:配置和管理各种支付渠道
  • 支付审核:审核支付单据
  • 账单管理:查询和统计支付账单
  • 退款管理:处理退款申请和操作
  • 支付操作:发起支付和查询支付状态
  • 转账管理:配置和管理转账场景

1.1 支付管理功能流程

mermaid
flowchart TD
    A[支付管理] --> B[支付渠道管理]
    A --> C[支付审核]
    A --> D[账单管理]
    A --> E[退款管理]
    A --> F[支付操作]
    A --> G[转账管理]

    subgraph 支付渠道
        B --> B1[渠道列表]
        B --> B2[渠道设置]
        B --> B3[转账设置]
        B1 --> B11[获取渠道]
        B1 --> B12[筛选渠道]
        B2 --> B21[配置参数]
        B2 --> B22[启用禁用]
        B3 --> B31[配置转账参数]
        B3 --> B32[设置默认渠道]
    end

    subgraph 支付流程
        F --> F1[发起支付]
        F --> F2[支付信息查询]
        F --> F3[支付方式列表]
        F1 --> F11[生成订单]
        F1 --> F12[调用渠道接口]
        F1 --> F13[返回支付参数]
        F2 --> F21[查询订单状态]
        F2 --> F22[获取详细信息]
        F2 --> F23[处理回调]
    end

    subgraph 审核与管理
        C --> C1[审核列表]
        C --> C2[审核操作]
        C --> C3[单据详情]
        D --> D1[账单列表]
        D --> D2[账单详情]
        D --> D3[账单统计]
        E --> E1[退款列表]
        E --> E2[退款详情]
        E --> E3[退款操作]
        G --> G1[转账场景管理]
        G --> G2[业务场景配置]
    end

2. 路由配置

支付管理相关的路由配置位于 backend/app/adminapi/route/pay.php 文件中,主要包含以下路由组:

2.1 支付渠道管理

  • GET /pay/channel/lists:渠道列表
  • POST /pay/channel/set/:channel/:type:渠道设置
  • GET /pay/channel/lists/:channel:通过渠道获取支付配置
  • POST /pay/channel/set/transfer:转账设置
  • POST /pay/channel/set/all:多渠道设置
  • GET /pay/type/all:获取全部支付方式

2.2 支付审核

  • GET /pay/audit:支付审核
  • PUT /pay/pass/:out_trade_no:审核通过
  • PUT /pay/refuse/:out_trade_no:审核拒绝
  • GET /pay/detail/:id:支付单据详情

2.3 账单管理

  • GET /pay/account:账单列表
  • GET /pay/account/:id:账单详情
  • GET /pay/account/stat:账单统计
  • GET /pay/account/type:账单类型

2.4 退款管理

  • GET /pay/refund:退款列表
  • GET /pay/refund/status:获取退款状态
  • GET /pay/refund/:refund_no:退款详情
  • GET /pay/refund/type:退款方式
  • POST /pay/refund/transfer:退款转账

2.5 支付操作

  • POST /pay:去支付
  • GET /pay/info/:trade_type/:trade_id:支付信息
  • GET /pay/type/list:支付方式列表

2.6 转账管理

  • GET /pay/transfer_scene:获取转账场景
  • POST /pay/transfer_scene/set_scene_id/:scene:设置场景id
  • POST /pay/transfer_scene/set_trade_scene/:type:设置业务场景配置

3. 核心功能实现

3.1 支付渠道管理

3.1.1 渠道列表

  • 获取所有可用的支付渠道
  • 支持按渠道类型筛选
  • 显示渠道的配置状态

实现代码

php
// PayChannelService.php 中的 getChannelList 方法
public function getChannelList()
{
    $channel_list = PayChannelDict::getPayChannel();
    $where = array (
        ['id', '>', 0]
    );
    $pay_channel_list_temp = $this->model->where($where)->field('type, channel, config, sort, status')->select()->toArray();

    $pay_channel_list = [];
    foreach ($pay_channel_list_temp as $v) {
        $pay_channel_list[ $v[ 'channel' ] ][ $v[ 'type' ] ] = $v;
    }

    $pay_type_list = PayDict::getPayType();

    foreach ($channel_list as $k => $v) {
        $temp_item = $pay_channel_list[ $k ] ?? [];
        foreach ($v[ 'pay_type' ] as $item_k => $item_v) {
            if (isset($temp_item[ $item_k ])) {
                $temp_v_item = $temp_item[ $item_k ];
                $encrypt_params = $pay_type_list[$item_k]['encrypt_params'] ?? [];
                foreach ($temp_v_item['config'] as $config_k => $config_v) {
                    if ($config_v !== '' && in_array($config_k, $encrypt_params)) $temp_v_item['config'][$config_k] = CommonDict::ENCRYPT_STR;
                }
            } else {
                $temp_v_item = [ 'status' => 0, 'config' => $this->getConfigByPayType([], $item_k), 'sort' => 0 ];
            }
            $item_v[ 'config' ] = $temp_v_item[ 'config' ];
            $item_v[ 'status' ] = $temp_v_item[ 'status' ];
            $item_v[ 'sort' ] = $temp_v_item[ 'sort' ];
            $channel_list[ $k ][ 'pay_type' ][ $item_k ] = $item_v;
        }
        $temp_pay_type = array_values($channel_list[ $k ][ 'pay_type' ]);
        $sort = array_column($temp_pay_type, 'sort');
        array_multisort($sort, SORT_ASC, $temp_pay_type);
        $channel_list[ $k ][ 'pay_type' ] = $temp_pay_type;
    }
    return $channel_list;
}

3.1.2 渠道设置

  • 配置支付渠道的参数(如AppID、AppSecret等)
  • 启用/禁用支付渠道
  • 测试支付渠道的连接状态

实现代码

php
// PayChannelService.php 中的 set 方法
public function set(string $channel, string $type, array $data)
{
    $where = array (
        'type' => $type,
        'channel' => $channel
    );
    if (!array_key_exists($type, PayDict::getPayType())) throw new PayException('PATMENT_METHOD_INVALID');
    if ($channel != 'transfer') {
        if (!array_key_exists($channel, ChannelDict::getType())) throw new PayException('CHANNEL_MARK_INVALID');
    }
    $pay_channel = $this->core_pay_channel_service->find($where);

    if ($pay_channel->isEmpty()) {
        $data[ 'channel' ] = $channel;
        $data[ 'type' ] = $type;
        $data[ 'config' ] = $this->getConfigByPayType($data[ 'config' ], $type);
        $res = $this->model->create($data);
    } else {
        $config = $pay_channel->config;
        $data[ 'config' ] = $this->getConfigByPayType($data[ 'config' ], $type);
        foreach ($data[ 'config' ] as $config_k => $config_v) {
            if ($config_v == CommonDict::ENCRYPT_STR && isset($config[$config_k])) {
                $data[ 'config' ][$config_k] = $config[$config_k];
            }
        }
        $pay_channel->save($data);
    }
    return true;
}

配置格式处理代码

php
// PayChannelService.php 中的 getConfigByPayType 方法
public function getConfigByPayType($data, $type)
{
    $config = [];
    switch ($type) {
        case PayDict::WECHATPAY:
            $config = [
                'mch_id' => $data[ 'mch_id' ] ?? '',//商户号
                'mch_secret_key' => $data[ 'mch_secret_key' ] ?? '',//商户秘钥  现在默认认为是v3版
                'mch_secret_cert' => $data[ 'mch_secret_cert' ] ?? '',//商户私钥 字符串或路径
                'mch_public_cert_path' => $data[ 'mch_public_cert_path' ] ?? '',//商户公钥证书路径
                'wechat_public_cert_path' => $data['wechat_public_cert_path'] ?? '', // 微信支付公钥
                'wechat_public_cert_id' => $data['wechat_public_cert_id'] ?? '' // 微信支付公钥id
            ];
            break;
        case PayDict::ALIPAY:
            $config = [
                'app_id' => $data[ 'app_id' ] ?? '',// 必填-支付宝分配的 app_id
                'app_secret_cert' => $data[ 'app_secret_cert' ] ?? '',// 必填-应用私钥 字符串或路径
                'app_public_cert_path' => $data[ 'app_public_cert_path' ] ?? '',//必填-应用公钥证书 路径
                'alipay_public_cert_path' => $data[ 'alipay_public_cert_path' ] ?? '',//必填-支付宝公钥证书 路径
                'alipay_root_cert_path' => $data[ 'alipay_root_cert_path' ] ?? '',// 必填-支付宝根证书 路径
            ];
            break;
        case PayDict::OFFLINEPAY:
            $config = [
                'collection_name' => $data[ 'collection_name' ] ?? '',// 必填-收款账户名称
                'collection_bank' => $data[ 'collection_bank' ] ?? '',//必填-收款银行
                'collection_account' => $data[ 'collection_account' ] ?? '',//必填-收款账号
                'collection_desc' => $data[ 'collection_desc' ] ?? '',// 必填-转账说明
            ];
            break;
        default:
            $config = $data;
    }
    return $config;
}

3.1.3 转账设置

  • 配置转账相关的参数
  • 设置转账的默认渠道
  • 测试转账功能

实现代码

php
// PayChannelService.php 中的 setTransfer 方法
public function setTransfer($data)
{
    $wechatpay_config = $data[ 'wechatpay_config' ];
    $alipay_config = $data[ 'alipay_config' ];
    $this->set('transfer', PayDict::WECHATPAY, [
        'config' => $wechatpay_config,
        'status' => 1,
    ]);
    $this->set('transfer', PayDict::ALIPAY, [
        'config' => $alipay_config,
        'status' => 1,
    ]);
    return true;
}

3.2 支付审核

3.2.1 支付审核列表

  • 查看待审核的支付单据
  • 支持按时间、金额、状态等条件筛选
  • 批量审核功能

3.2.2 审核操作

  • 审核通过支付单据
  • 拒绝支付单据并填写原因
  • 记录审核操作日志

3.2.3 支付单据详情

  • 查看支付单据的详细信息
  • 查看支付的相关凭证
  • 查看支付的处理状态

3.3 账单管理

3.3.1 账单列表

  • 查看所有支付账单
  • 支持按时间、类型、金额等条件筛选
  • 支持分页和排序

3.3.2 账单详情

  • 查看账单的详细信息
  • 查看账单的支付记录
  • 查看账单的相关操作日志

3.3.3 账单统计

  • 按时间周期统计支付金额
  • 按支付渠道统计交易次数和金额
  • 生成账单统计报表

3.4 退款管理

3.4.1 退款列表

  • 查看所有退款申请
  • 支持按时间、金额、状态等条件筛选
  • 支持分页和排序

3.4.2 退款详情

  • 查看退款的详细信息
  • 查看退款的处理状态
  • 查看退款的相关凭证

3.4.3 退款操作

  • 处理退款申请
  • 执行退款转账
  • 记录退款操作日志

3.5 支付操作

3.5.1 发起支付

  • 生成支付订单
  • 调用支付渠道的接口
  • 返回支付参数

实现代码

php
// PayService.php 中的 pay 方法
public function pay(string $type, string $trade_type, int $trade_id, string $return_url = '', string $quit_url = '', string $buyer_id = '', string $voucher = '', string $openid = '')
{
    return ( new CorePayService() )->pay($trade_type, $trade_id, $type, ChannelDict::PC, $openid, $return_url, $quit_url, $buyer_id, $voucher);
}

3.5.2 支付信息查询

  • 查询支付订单的状态
  • 获取支付的详细信息
  • 处理支付结果回调

实现代码

php
// PayService.php 中的 getInfoByTrade 方法
public function getInfoByTrade(string $trade_type, int $trade_id)
{
    return ( new CorePayService() )->getInfoByTrade($trade_type, $trade_id, ChannelDict::H5);
}

3.5.3 支付方式列表

  • 获取可用的支付方式
  • 显示支付方式的配置状态
  • 支持按场景筛选支付方式

实现代码

php
// PayService.php 中的 getPayTypeList 方法
public function getPayTypeList()
{
    $pay_type_list = ( new CorePayService() )->getPayTypeByTrade('', ChannelDict::H5);
    if (!empty($pay_type_list)) {
        foreach ($pay_type_list as $k => $v) {
            if (!in_array($v['key'], [ PayDict::BALANCEPAY ])) {
                unset($pay_type_list[ $k ]);
            }
        }
        $pay_type_list = array_values($pay_type_list);
    }
    return $pay_type_list;
}

3.6 转账管理

3.6.1 转账场景管理

  • 获取支持的转账场景
  • 配置转账场景的参数
  • 测试转账场景的可用性

3.6.2 业务场景配置

  • 设置不同业务场景的转账规则
  • 配置转账的默认参数
  • 管理转账的限额和频率

4. 数据模型

4.1 支付渠道模型

  • 表名:pay_channel
  • 主要字段:
    • id:渠道ID
    • channel:渠道名称(如wechat、alipay等)
    • type:渠道类型(如app、h5、pc等)
    • config:配置参数(JSON格式)
    • status:状态(0:禁用,1:启用)
    • create_time:创建时间
    • update_time:更新时间

4.2 支付订单模型

  • 表名:pay
  • 主要字段:
    • id:订单ID
    • out_trade_no:商户订单号
    • trade_no:支付渠道订单号
    • trade_type:交易类型
    • total_amount:支付金额
    • status:支付状态
    • pay_time:支付时间
    • create_time:创建时间
    • update_time:更新时间

4.3 账单模型

  • 表名:account_log
  • 主要字段:
    • id:账单ID
    • uid:用户ID
    • username:用户名
    • type:账单类型
    • amount:金额
    • desc:描述
    • create_time:创建时间

4.4 退款模型

  • 表名:refund
  • 主要字段:
    • id:退款ID
    • refund_no:退款单号
    • out_trade_no:原订单号
    • refund_amount:退款金额
    • status:退款状态
    • refund_time:退款时间
    • create_time:创建时间
    • update_time:更新时间

5. 开发规范

5.1 代码结构

  • 控制器:位于 backend/app/adminapi/controller/pay/ 目录
  • 模型:位于 backend/app/model/pay/ 目录
  • 验证器:位于 backend/app/validate/pay/ 目录
  • 字典:位于 backend/app/dict/pay/ 目录
  • 核心支付:位于 backend/core/pay/ 目录

5.2 安全规范

  • 支付参数加密传输
  • 支付签名验证
  • 防止支付订单篡改
  • 敏感信息脱敏处理

5.3 错误处理

  • 支付异常捕获和处理
  • 退款失败的重试机制
  • 支付状态的一致性检查

5.4 日志记录

  • 支付操作的详细日志
  • 退款操作的详细日志
  • 渠道调用的详细日志

6. 注意事项

  1. 支付安全:支付相关操作涉及资金安全,需要严格的安全措施
  2. 渠道配置:不同支付渠道的配置参数不同,需要仔细配置
  3. 回调处理:支付回调需要处理好网络延迟和重复回调的情况
  4. 退款处理:退款操作需要谨慎,确保资金安全
  5. 账单对账:定期与支付渠道进行账单对账,确保资金准确

7. 开发流程

  1. 需求分析:明确支付管理的具体需求
  2. 渠道对接:选择需要对接的支付渠道
  3. 配置开发:开发支付渠道的配置功能
  4. 支付流程:实现支付的完整流程
  5. 退款流程:实现退款的完整流程
  6. 测试验证:测试各种支付场景
  7. 部署上线:将支付功能部署到生产环境

8. 常见问题

8.1 支付失败

  • 检查支付渠道配置是否正确
  • 检查支付金额是否符合渠道要求
  • 检查网络连接是否正常

8.2 退款失败

  • 检查退款金额是否超过原支付金额
  • 检查支付渠道是否支持退款
  • 检查退款的时间限制

8.3 回调处理

  • 确保回调地址可访问
  • 处理重复回调的情况
  • 验证回调签名的正确性

8.4 账单对账

  • 定期与支付渠道进行对账
  • 处理账单差异
  • 确保资金的准确性