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:
@@ -5,6 +5,7 @@ namespace app\http\admin\controller\merchant;
|
||||
use app\common\base\BaseController;
|
||||
use app\http\admin\validation\MerchantApiCredentialValidator;
|
||||
use app\http\admin\validation\MerchantValidator;
|
||||
use app\service\merchant\auth\MerchantAuthService;
|
||||
use app\service\merchant\MerchantService;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
@@ -25,7 +26,8 @@ class MerchantController extends BaseController
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
protected MerchantService $merchantService
|
||||
protected MerchantService $merchantService,
|
||||
protected MerchantAuthService $merchantAuthService
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -127,6 +129,34 @@ class MerchantController extends BaseController
|
||||
return $this->success($this->merchantService->resetPassword((int) $data['id'], (string) $data['password']));
|
||||
}
|
||||
|
||||
/**
|
||||
* 签发商户后台临时登录令牌。
|
||||
*
|
||||
* 该入口只在管理后台登录态下可用,用于客服或运营从商户工作台直接进入当前商户后台。
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @param string $id 商户ID
|
||||
* @return Response 响应对象
|
||||
*/
|
||||
public function loginToken(Request $request, string $id): Response
|
||||
{
|
||||
$data = $this->validated(['id' => (int) $id], MerchantValidator::class, 'loginToken');
|
||||
$merchant = $this->merchantService->ensureMerchantEnabled((int) $data['id']);
|
||||
$issued = $this->merchantAuthService->issueToken(
|
||||
(int) $merchant->id,
|
||||
3600,
|
||||
(string) $request->getRealIp(),
|
||||
(string) $request->header('user-agent', '')
|
||||
);
|
||||
|
||||
return $this->success([
|
||||
'token' => (string) $issued['token'],
|
||||
'expires_in' => (int) $issued['expires_in'],
|
||||
'merchant_id' => (int) $merchant->id,
|
||||
'merchant_no' => (string) $merchant->merchant_no,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成或重置商户 API 凭证。
|
||||
*
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace app\http\admin\controller\payment;
|
||||
use app\common\base\BaseController;
|
||||
use app\http\admin\validation\PaymentChannelValidator;
|
||||
use app\service\payment\config\PaymentChannelService;
|
||||
use app\service\payment\config\PaymentChannelTestService;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
|
||||
@@ -14,6 +15,7 @@ use support\Response;
|
||||
* 负责支付通道的列表、详情、新增、修改和删除。
|
||||
*
|
||||
* @property PaymentChannelService $paymentChannelService 支付渠道服务
|
||||
* @property PaymentChannelTestService $paymentChannelTestService 支付通道测试服务
|
||||
*/
|
||||
class PaymentChannelController extends BaseController
|
||||
{
|
||||
@@ -21,10 +23,12 @@ class PaymentChannelController extends BaseController
|
||||
* 构造方法。
|
||||
*
|
||||
* @param PaymentChannelService $paymentChannelService 支付渠道服务
|
||||
* @param PaymentChannelTestService $paymentChannelTestService 支付通道测试服务
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
protected PaymentChannelService $paymentChannelService
|
||||
protected PaymentChannelService $paymentChannelService,
|
||||
protected PaymentChannelTestService $paymentChannelTestService
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -157,6 +161,25 @@ class PaymentChannelController extends BaseController
|
||||
|
||||
return $this->success($this->paymentChannelService->searchOptions($request->all(), $page, $pageSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起当前通道测试支付。
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @param string $id 支付渠道ID
|
||||
* @return Response 响应对象
|
||||
*/
|
||||
public function test(Request $request, string $id): Response
|
||||
{
|
||||
$data = $this->validated(
|
||||
array_merge($request->all(), ['id' => (int) $id]),
|
||||
PaymentChannelValidator::class,
|
||||
'test'
|
||||
);
|
||||
$data['client_ip'] = (string) $request->getRealIp();
|
||||
|
||||
return $this->success($this->paymentChannelTestService->submit((int) $data['id'], $data));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ use support\Response;
|
||||
class SystemConfigPageController extends BaseController
|
||||
{
|
||||
/**
|
||||
* 构造方法。
|
||||
* 构造方法。
|
||||
*
|
||||
* @param SystemConfigPageService $systemConfigPageService 系统配置页面服务
|
||||
* @return void
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace app\http\admin\controller\system;
|
||||
|
||||
use app\common\base\BaseController;
|
||||
use app\service\bootstrap\SystemBootstrapService;
|
||||
use app\service\system\config\SystemPublicConfigService;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
|
||||
@@ -11,17 +12,20 @@ use support\Response;
|
||||
* 管理后台系统数据控制器。
|
||||
*
|
||||
* @property SystemBootstrapService $systemBootstrapService 系统引导服务
|
||||
* @property SystemPublicConfigService $systemPublicConfigService 系统公开配置服务
|
||||
*/
|
||||
class SystemController extends BaseController
|
||||
{
|
||||
/**
|
||||
* 构造方法。
|
||||
* 构造方法。
|
||||
*
|
||||
* @param SystemBootstrapService $systemBootstrapService 系统引导服务
|
||||
* @param SystemPublicConfigService $systemPublicConfigService 系统公开配置服务
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
protected SystemBootstrapService $systemBootstrapService
|
||||
protected SystemBootstrapService $systemBootstrapService,
|
||||
protected SystemPublicConfigService $systemPublicConfigService
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -46,6 +50,17 @@ class SystemController extends BaseController
|
||||
{
|
||||
return $this->success($this->systemBootstrapService->getDictItems((string) $request->get('code', '')));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取管理后台公开展示配置。
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @return Response 响应对象
|
||||
*/
|
||||
public function publicConfig(Request $request): Response
|
||||
{
|
||||
return $this->success($this->systemPublicConfigService->adminPortal());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
namespace app\http\admin\controller\trade;
|
||||
|
||||
use app\common\base\BaseController;
|
||||
use app\http\admin\validation\PayOrderActionValidator;
|
||||
use app\http\admin\validation\PayOrderValidator;
|
||||
use app\service\payment\order\PayOrderAdminActionService;
|
||||
use app\service\payment\order\PayOrderService;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
@@ -14,6 +16,7 @@ use support\Response;
|
||||
* 当前提供列表查询和详情查看,便于后台直接排查支付链路。
|
||||
*
|
||||
* @property PayOrderService $payOrderService 支付订单服务
|
||||
* @property PayOrderAdminActionService $payOrderAdminActionService 支付订单后台操作服务
|
||||
*/
|
||||
class PayOrderController extends BaseController
|
||||
{
|
||||
@@ -21,10 +24,12 @@ class PayOrderController extends BaseController
|
||||
* 构造方法。
|
||||
*
|
||||
* @param PayOrderService $payOrderService 支付订单服务
|
||||
* @param PayOrderAdminActionService $payOrderAdminActionService 支付订单后台操作服务
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
protected PayOrderService $payOrderService
|
||||
protected PayOrderService $payOrderService,
|
||||
protected PayOrderAdminActionService $payOrderAdminActionService
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -40,7 +45,7 @@ class PayOrderController extends BaseController
|
||||
$page = max(1, (int) ($data['page'] ?? 1));
|
||||
$pageSize = max(1, (int) ($data['page_size'] ?? 10));
|
||||
|
||||
return $this->success($this->payOrderService->paginate($data, $page, $pageSize));
|
||||
return $this->success($this->payOrderService->paginate($data, $page, $pageSize, null, true));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,7 +63,151 @@ class PayOrderController extends BaseController
|
||||
'show'
|
||||
);
|
||||
|
||||
return $this->success($this->payOrderService->detail($payNo));
|
||||
return $this->success($this->payOrderService->detail($payNo, null, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询支付订单可操作项。
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @param string $payNo 支付单号
|
||||
* @return Response 响应对象
|
||||
*/
|
||||
public function actions(Request $request, string $payNo): Response
|
||||
{
|
||||
$this->validated(
|
||||
array_merge($request->all(), ['pay_no' => $payNo]),
|
||||
PayOrderActionValidator::class,
|
||||
'actions'
|
||||
);
|
||||
|
||||
return $this->success($this->payOrderAdminActionService->actions($payNo));
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新通知商户。
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @param string $payNo 支付单号
|
||||
* @return Response 响应对象
|
||||
*/
|
||||
public function renotify(Request $request, string $payNo): Response
|
||||
{
|
||||
$data = $this->validated(
|
||||
array_merge($this->payload($request), ['pay_no' => $payNo]),
|
||||
PayOrderActionValidator::class,
|
||||
'renotify'
|
||||
);
|
||||
|
||||
return $this->success($this->payOrderAdminActionService->renotify($payNo, $data, $this->currentAdminId($request)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 主动查询上游支付结果。
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @param string $payNo 支付单号
|
||||
* @return Response 响应对象
|
||||
*/
|
||||
public function activeQuery(Request $request, string $payNo): Response
|
||||
{
|
||||
$data = $this->validated(
|
||||
array_merge($this->payload($request), ['pay_no' => $payNo]),
|
||||
PayOrderActionValidator::class,
|
||||
'active_query'
|
||||
);
|
||||
|
||||
return $this->success($this->payOrderAdminActionService->activeQuery($payNo, $data, $this->currentAdminId($request)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发起 API 退款。
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @param string $payNo 支付单号
|
||||
* @return Response 响应对象
|
||||
*/
|
||||
public function apiRefund(Request $request, string $payNo): Response
|
||||
{
|
||||
$data = $this->validated(
|
||||
array_merge($this->payload($request), ['pay_no' => $payNo]),
|
||||
PayOrderActionValidator::class,
|
||||
'api_refund'
|
||||
);
|
||||
|
||||
return $this->success($this->payOrderAdminActionService->apiRefund($payNo, $data, $this->currentAdminId($request)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动退款。
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @param string $payNo 支付单号
|
||||
* @return Response 响应对象
|
||||
*/
|
||||
public function manualRefund(Request $request, string $payNo): Response
|
||||
{
|
||||
$data = $this->validated(
|
||||
array_merge($this->payload($request), ['pay_no' => $payNo]),
|
||||
PayOrderActionValidator::class,
|
||||
'manual_refund'
|
||||
);
|
||||
|
||||
return $this->success($this->payOrderAdminActionService->manualRefund($payNo, $data, $this->currentAdminId($request)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 手动补单。
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @param string $payNo 支付单号
|
||||
* @return Response 响应对象
|
||||
*/
|
||||
public function manualSuccess(Request $request, string $payNo): Response
|
||||
{
|
||||
$data = $this->validated(
|
||||
array_merge($this->payload($request), ['pay_no' => $payNo]),
|
||||
PayOrderActionValidator::class,
|
||||
'manual_success'
|
||||
);
|
||||
|
||||
return $this->success($this->payOrderAdminActionService->manualSuccess($payNo, $data, $this->currentAdminId($request)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 冻结支付订单。
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @param string $payNo 支付单号
|
||||
* @return Response 响应对象
|
||||
*/
|
||||
public function freeze(Request $request, string $payNo): Response
|
||||
{
|
||||
$data = $this->validated(
|
||||
array_merge($this->payload($request), ['pay_no' => $payNo]),
|
||||
PayOrderActionValidator::class,
|
||||
'freeze'
|
||||
);
|
||||
|
||||
return $this->success($this->payOrderAdminActionService->freeze($payNo, $data, $this->currentAdminId($request)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解冻支付订单。
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @param string $payNo 支付单号
|
||||
* @return Response 响应对象
|
||||
*/
|
||||
public function unfreeze(Request $request, string $payNo): Response
|
||||
{
|
||||
$data = $this->validated(
|
||||
array_merge($this->payload($request), ['pay_no' => $payNo]),
|
||||
PayOrderActionValidator::class,
|
||||
'unfreeze'
|
||||
);
|
||||
|
||||
return $this->success($this->payOrderAdminActionService->unfreeze($payNo, $data, $this->currentAdminId($request)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
namespace app\http\admin\controller\trade;
|
||||
|
||||
use app\common\base\BaseController;
|
||||
use app\exception\BusinessStateException;
|
||||
use app\exception\ResourceNotFoundException;
|
||||
use app\http\admin\validation\SettlementOrderValidator;
|
||||
use app\service\payment\settlement\SettlementOrderQueryService;
|
||||
use app\service\payment\settlement\SettlementService;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
|
||||
@@ -13,6 +15,7 @@ use support\Response;
|
||||
* 清算订单控制器。
|
||||
*
|
||||
* @property SettlementOrderQueryService $settlementOrderQueryService 结算订单查询服务
|
||||
* @property SettlementService $settlementService 清算服务
|
||||
*/
|
||||
class SettlementOrderController extends BaseController
|
||||
{
|
||||
@@ -20,10 +23,12 @@ class SettlementOrderController extends BaseController
|
||||
* 构造方法。
|
||||
*
|
||||
* @param SettlementOrderQueryService $settlementOrderQueryService 结算订单查询服务
|
||||
* @param SettlementService $settlementService 清算服务
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
protected SettlementOrderQueryService $settlementOrderQueryService
|
||||
protected SettlementOrderQueryService $settlementOrderQueryService,
|
||||
protected SettlementService $settlementService
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -62,6 +67,53 @@ class SettlementOrderController extends BaseController
|
||||
return $this->fail('清算订单不存在', 404);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清算入账。
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @param string $settleNo 清算单号
|
||||
* @return Response 响应对象
|
||||
*/
|
||||
public function complete(Request $request, string $settleNo): Response
|
||||
{
|
||||
$data = $this->validated(['settle_no' => $settleNo], SettlementOrderValidator::class, 'show');
|
||||
|
||||
try {
|
||||
return $this->success($this->settlementService->completeSettlement((string) $data['settle_no']));
|
||||
} catch (ResourceNotFoundException $e) {
|
||||
return $this->fail($e->getMessage(), $e->getCode());
|
||||
} catch (BusinessStateException $e) {
|
||||
return $this->fail($e->getMessage(), $e->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记清算失败。
|
||||
*
|
||||
* @param Request $request 请求对象
|
||||
* @param string $settleNo 清算单号
|
||||
* @return Response 响应对象
|
||||
*/
|
||||
public function markFailed(Request $request, string $settleNo): Response
|
||||
{
|
||||
$data = $this->validated(
|
||||
array_merge($request->all(), ['settle_no' => $settleNo]),
|
||||
SettlementOrderValidator::class,
|
||||
'fail'
|
||||
);
|
||||
|
||||
try {
|
||||
return $this->success($this->settlementService->failSettlement(
|
||||
(string) $data['settle_no'],
|
||||
(string) ($data['reason'] ?? '')
|
||||
));
|
||||
} catch (ResourceNotFoundException $e) {
|
||||
return $this->fail($e->getMessage(), $e->getCode());
|
||||
} catch (BusinessStateException $e) {
|
||||
return $this->fail($e->getMessage(), $e->getCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user