mirror of
https://gitee.com/technical-laohu/mpay_v2_webman.git
synced 2026-05-17 06:20:25 +08:00
feat: 完善支付通道和收款监听链路
新增 ChannelNotifyPayloadInterface 等支付插件通知契约,规范 pay_no 定位和插件返回校验。 新增微信、支付宝、收钱吧、Postar 个人收款插件适配,支持余额识别与备注识别。 新增 receipt-watcher 后端进程、Redis 队列 job 和平台事件监听,覆盖收款流水通知、商户通知、退款派发、转账派发与清算完成。 补齐个人收款监听相关系统配置、仓储、服务费冻结明细、订单后台操作和通道测试能力。 重构支付单创建、回调、费用、风控、结算和通道统计链路,统一状态流转与幂等处理。
This commit is contained in:
24
app/common/interface/ChannelNotifyInterface.php
Normal file
24
app/common/interface/ChannelNotifyInterface.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\interface;
|
||||
|
||||
use support\Request;
|
||||
|
||||
/**
|
||||
* HTTP 通道级通知定位接口。
|
||||
*
|
||||
* 适用于 SmsForwarder 这类通过 /api/pay/{chanId}/notify 进入的 HTTP 通知。
|
||||
* 通知内容通常不携带本系统支付单号,服务层先调用此方法定位 pay_no,
|
||||
* 定位成功后继续把同一个 Request 交给插件 notify() 走标准回调流程。
|
||||
*/
|
||||
interface ChannelNotifyInterface
|
||||
{
|
||||
/**
|
||||
* 根据 HTTP 通道级通知定位支付单。
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @return array{pay_no:string} 定位结果
|
||||
*/
|
||||
public function channelNotify(Request $request): array;
|
||||
}
|
||||
32
app/common/interface/ChannelNotifyPayloadInterface.php
Normal file
32
app/common/interface/ChannelNotifyPayloadInterface.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\interface;
|
||||
|
||||
/**
|
||||
* 非 HTTP 通道级数组载荷通知接口。
|
||||
*
|
||||
* 适用于 receipt_watcher 这类队列入口:外部监听工具已经把平台流水归一化为数组,
|
||||
* 并投递到 Redis 队列。服务层先调用 channelNotifyPayload() 定位 pay_no,再调用
|
||||
* notifyPayload() 获取标准插件通知结果,后续复用订单状态推进、回调日志和商户通知链路。
|
||||
*
|
||||
* 该接口不接收 Request,也不用于 /api/pay/{chanId}/notify 这类 HTTP 入口。
|
||||
*/
|
||||
interface ChannelNotifyPayloadInterface
|
||||
{
|
||||
/**
|
||||
* 根据数组载荷定位支付单。
|
||||
*
|
||||
* @param array<string, mixed> $payload 已归一化的通道通知载荷
|
||||
* @return array{pay_no:string} 定位结果
|
||||
*/
|
||||
public function channelNotifyPayload(array $payload): array;
|
||||
|
||||
/**
|
||||
* 解析数组载荷并返回标准插件通知结果。
|
||||
*
|
||||
* @param array<string, mixed> $payload 已归一化的通道通知载荷
|
||||
* @return array<string, mixed> 插件回调结果
|
||||
*/
|
||||
public function notifyPayload(array $payload): array;
|
||||
}
|
||||
@@ -24,18 +24,25 @@ interface PaymentInterface
|
||||
* 发起支付下单。
|
||||
*
|
||||
* 插件必须返回系统标准结构,服务层会严格校验后写入支付单 `ext_json.presentation`:
|
||||
* - `pay_product`:支付产品或上游支付方式,例如 `alipay`、`wxpay`、`alipay_h5`
|
||||
* - `pay_action`:支付动作,例如 `jump`、`qrcode`、`html`、`jsapi`
|
||||
* - `pay_params.type`:收银台承接类型,支持 `jump`、`web`、`h5`、`qrcode`、`html`、`jsapi`、`urlscheme`、`mini`、`pos`、`transfer`、`json`、`error`
|
||||
* - `chan_order_no`:渠道订单号,必须返回
|
||||
* - `pay_page`:收银台承接页类型,支持 `qrcode`、`html`、`jump`、`jsapi`、`urlscheme`、`error`、`ok`、`page`
|
||||
* - `pay_type`:支付方式,例如 `alipay`、`wxpay`、`unionpay`
|
||||
* - `pay_product`:插件调用的支付产品,例如 `scan`、`h5`、`jsapi`;没有更细产品时可与 `pay_type` 相同
|
||||
* - `pay_action`:插件调用动作或方法,例如 `qrcode`、`jump`、`html`、`jsapi`
|
||||
* - `pay_params`:插件调用支付产品返回的支付参数,平台不向其中补写展示字段
|
||||
* - `chan_order_no`:渠道订单号;`error`、`html`、`ok` 场景允许为空
|
||||
* - `chan_trade_no`:渠道交易号,可选;未生成时返回空字符串
|
||||
* - `ext_json`:插件私有轻量信息,可选;原始响应不要塞入支付单扩展
|
||||
*
|
||||
* `pay_params` 必须带上对应 `type` 的必要载荷:
|
||||
* - 跳转类:`redirect_url` / `payurl` / `mweb_url`
|
||||
* - 二维码类:`qrcode_text` / `qrcode_data` / `qrcode_url`
|
||||
* - 表单类:`html` 或 `action`
|
||||
* - JSAPI / URL Scheme / 小程序:对应拉起参数或跳转参数
|
||||
* `pay_params` 按对应 `pay_page` 放入承接页需要的固定字段:
|
||||
* - `qrcode`:`qrcode`,二维码文字内容。
|
||||
* - `html`:`html`,插件返回的 HTML 代码。
|
||||
* - `jump`:`url`,需要跳转的支付地址。
|
||||
* - `jsapi`:微信、支付宝官方 JSAPI 拉起参数。
|
||||
* - `urlscheme`:`urlscheme`,需要打开的应用或小程序地址。
|
||||
* - `error`:`error_msg`,承接页展示的错误信息。
|
||||
* - `ok`:无需固定支付参数,承接页会优先使用订单 `return_url` 返回商户。
|
||||
* - `page`:`_page`,已在收银台白名单注册的组件名,其他字段由该组件消费。
|
||||
*
|
||||
* 插件可把上游原始响应放入 `pay_params.raw` 方便排障,这是推荐约定,不由平台强制校验。
|
||||
*
|
||||
* @param array $order 订单参数
|
||||
* @return array 下单结果
|
||||
@@ -52,7 +59,6 @@ interface PaymentInterface
|
||||
* - `channel_status`:渠道原始状态,可选
|
||||
* - `message`:查询说明,可选
|
||||
* - `paid_at` / `failed_at`:终态时间,可选
|
||||
* - `ext_json`:插件私有轻量补充信息,可选
|
||||
*
|
||||
* @param array $order 订单参数
|
||||
* @return array 查询结果
|
||||
@@ -87,8 +93,6 @@ interface PaymentInterface
|
||||
* - `message`:回调处理说明,可选
|
||||
* - `channel_error_code` / `channel_error_msg`:渠道失败原因,可选
|
||||
* - `paid_at` / `failed_at`:支付成功或失败时间,可选
|
||||
* - `fee_actual_amount`:实际手续费,单位分,可选
|
||||
* - `ext_json`:插件私有的轻量补充信息,可选;原始回调和解析结果会进入回调日志,不要塞进支付单扩展
|
||||
*
|
||||
* 插件在验签失败、报文非法或关键字段缺失时,应直接抛出 `PaymentException`。
|
||||
* 只有在回调可信时,才返回标准结果数组。
|
||||
|
||||
31
app/common/interface/QueueJobInterface.php
Normal file
31
app/common/interface/QueueJobInterface.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\interface;
|
||||
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* 队列任务接口。
|
||||
*
|
||||
* Consumer 只关心消息消费协议,具体业务处理统一交给 Job,便于后续按任务维度管理、
|
||||
* 测试、统计和扩展失败处理。
|
||||
*/
|
||||
interface QueueJobInterface
|
||||
{
|
||||
/**
|
||||
* 处理队列消息。
|
||||
*
|
||||
* @param array<string, mixed> $data 队列消息
|
||||
* @return void
|
||||
*/
|
||||
public function handle(array $data): void;
|
||||
|
||||
/**
|
||||
* 处理消费失败。
|
||||
*
|
||||
* @param Throwable $exception 异常
|
||||
* @param array<string, mixed> $package 原始队列包
|
||||
* @return void
|
||||
*/
|
||||
public function failed(Throwable $exception, array $package): void;
|
||||
}
|
||||
38
app/common/interface/TransferPluginInterface.php
Normal file
38
app/common/interface/TransferPluginInterface.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\interface;
|
||||
|
||||
/**
|
||||
* 支付插件的可选转账能力接口。
|
||||
*
|
||||
* 支付插件默认不要求支持转账;只有显式实现本接口,并在插件元信息中声明
|
||||
* transfer_types 的插件,才会被转账链路选中。
|
||||
*/
|
||||
interface TransferPluginInterface
|
||||
{
|
||||
/**
|
||||
* 发起转账。
|
||||
*
|
||||
* @param array<string, mixed> $order 转账订单参数
|
||||
* @return array<string, mixed> 转账结果
|
||||
*/
|
||||
public function transfer(array $order): array;
|
||||
|
||||
/**
|
||||
* 查询转账状态。
|
||||
*
|
||||
* @param array<string, mixed> $order 转账订单参数
|
||||
* @return array<string, mixed> 查询结果
|
||||
*/
|
||||
public function transferQuery(array $order): array;
|
||||
|
||||
/**
|
||||
* 查询转账余额。
|
||||
*
|
||||
* @param array<string, mixed> $order 查询参数
|
||||
* @return array<string, mixed> 余额结果
|
||||
*/
|
||||
public function transferBalance(array $order): array;
|
||||
}
|
||||
Reference in New Issue
Block a user