feat: 完善支付通道和收款监听链路

新增 ChannelNotifyPayloadInterface 等支付插件通知契约,规范 pay_no 定位和插件返回校验。

新增微信、支付宝、收钱吧、Postar 个人收款插件适配,支持余额识别与备注识别。

新增 receipt-watcher 后端进程、Redis 队列 job 和平台事件监听,覆盖收款流水通知、商户通知、退款派发、转账派发与清算完成。

补齐个人收款监听相关系统配置、仓储、服务费冻结明细、订单后台操作和通道测试能力。

重构支付单创建、回调、费用、风控、结算和通道统计链路,统一状态流转与幂等处理。
This commit is contained in:
技术老胡
2026-05-11 16:28:48 +08:00
parent 0e5de50337
commit fd1f53f2ee
136 changed files with 14416 additions and 3992 deletions

View File

@@ -2,181 +2,263 @@
use Webman\Route;
use app\common\middleware\Cors;
use app\http\admin\controller\system\AdminUserController;
use app\http\admin\controller\system\AuthController;
use app\http\admin\controller\account\MerchantAccountController;
use app\http\admin\controller\account\MerchantAccountLedgerController;
use app\http\admin\controller\file\FileRecordController;
use app\http\admin\controller\merchant\MerchantApiCredentialController;
use app\http\admin\controller\merchant\MerchantController;
use app\http\admin\controller\merchant\MerchantGroupController;
use app\http\admin\controller\merchant\MerchantPolicyController;
use app\http\admin\controller\ops\ChannelDailyStatController;
use app\http\admin\controller\ops\ChannelNotifyLogController;
use app\http\admin\controller\ops\MerchantNotifyTaskController;
use app\http\admin\controller\merchant\MerchantController;
use app\http\admin\controller\merchant\MerchantApiCredentialController;
use app\http\admin\controller\merchant\MerchantGroupController;
use app\http\admin\controller\merchant\MerchantPolicyController;
use app\http\admin\controller\ops\PayCallbackLogController;
use app\http\admin\controller\payment\PaymentChannelController;
use app\http\admin\controller\payment\PaymentPluginController;
use app\http\admin\controller\payment\PaymentPluginConfController;
use app\http\admin\controller\payment\PaymentPollGroupController;
use app\http\admin\controller\payment\PaymentPluginController;
use app\http\admin\controller\payment\PaymentPollGroupBindController;
use app\http\admin\controller\payment\PaymentPollGroupChannelController;
use app\http\admin\controller\payment\PaymentPollGroupController;
use app\http\admin\controller\payment\PaymentTypeController;
use app\http\admin\controller\payment\RouteController;
use app\http\admin\controller\trade\PayOrderController;
use app\http\admin\controller\ops\PayCallbackLogController;
use app\http\admin\controller\file\FileRecordController;
use app\http\admin\controller\trade\RefundOrderController;
use app\http\admin\controller\trade\SettlementOrderController;
use app\http\admin\controller\system\AdminUserController;
use app\http\admin\controller\system\AuthController;
use app\http\admin\controller\system\SystemConfigPageController;
use app\http\admin\controller\system\SystemController;
use app\http\admin\controller\trade\PayOrderController;
use app\http\admin\controller\trade\RefundOrderController;
use app\http\admin\controller\trade\SettlementOrderController;
use app\http\admin\middleware\AdminAuthMiddleware;
Route::any('/admin[/{path:.+}]', function () {
return view('/public/admin/index');
});
$serveAdminApp = static function () {
$indexPath = public_path('admin/index.html');
if (!is_file($indexPath)) {
return response('Admin page not found', 404);
}
return response(file_get_contents($indexPath), 200, [
'Content-Type' => 'text/html; charset=utf-8',
]);
};
// 管理后台项目:页面路由
Route::any('/admin', $serveAdminApp);
Route::any('/admin/', $serveAdminApp);
Route::any('/admin/{path:.+}', $serveAdminApp);
// 管理后台项目:接口路由
Route::group('/adminapi', function () {
// 公开接口
Route::post('/login', [AuthController::class, 'login'])->name('adminApiAuthLogin')->setParams(['real_name' => '管理员登录']);
Route::get('/system/public-config', [SystemController::class, 'publicConfig'])->name('adminApiSystemPublicConfig')->setParams(['real_name' => '管理后台公开配置']);
Route::group('', function () {
// 会话与当前用户
Route::post('/logout', [AuthController::class, 'logout'])->name('adminApiAuthLogout')->setParams(['real_name' => '退出登录']);
Route::get('/user/profile', [AuthController::class, 'profile'])->name('adminApiUserProfile')->setParams(['real_name' => '当前用户资料']);
Route::post('/user/change-password', [AuthController::class, 'changePassword'])->name('adminApiUserChangePassword')->setParams(['real_name' => '修改当前管理员密码']);
Route::get('/merchants', [MerchantController::class, 'index'])->name('adminApiMerchantsIndex')->setParams(['real_name' => '商户列表']);
Route::get('/merchants/options', [MerchantController::class, 'options'])->name('adminApiMerchantsOptions')->setParams(['real_name' => '商户选项']);
Route::get('/merchants/select-options', [MerchantController::class, 'selectOptions'])->name('adminApiMerchantsSelectOptions')->setParams(['real_name' => '商户选择选项']);
Route::get('/merchants/{id}', [MerchantController::class, 'show'])->name('adminApiMerchantsShow')->setParams(['real_name' => '商户详情']);
Route::get('/merchants/{id}/overview', [MerchantController::class, 'overview'])->name('adminApiMerchantsOverview')->setParams(['real_name' => '商户总览']);
Route::post('/merchants', [MerchantController::class, 'store'])->name('adminApiMerchantsStore')->setParams(['real_name' => '新增商户']);
Route::put('/merchants/{id}', [MerchantController::class, 'update'])->name('adminApiMerchantsUpdate')->setParams(['real_name' => '更新商户']);
Route::delete('/merchants/{id}', [MerchantController::class, 'destroy'])->name('adminApiMerchantsDestroy')->setParams(['real_name' => '删除商户']);
Route::post('/merchants/{id}/reset-password', [MerchantController::class, 'resetPassword'])->name('adminApiMerchantsResetPassword')->setParams(['real_name' => '重置商户密码']);
Route::post('/merchants/{id}/issue-credential', [MerchantController::class, 'issueCredential'])->name('adminApiMerchantsIssueCredential')->setParams(['real_name' => '生成或重置商户 API 凭证']);
// 商户档案
Route::group('/merchants', function () {
Route::get('', [MerchantController::class, 'index'])->name('adminApiMerchantsIndex')->setParams(['real_name' => '商户列表']);
Route::get('/options', [MerchantController::class, 'options'])->name('adminApiMerchantsOptions')->setParams(['real_name' => '商户选项']);
Route::get('/select-options', [MerchantController::class, 'selectOptions'])->name('adminApiMerchantsSelectOptions')->setParams(['real_name' => '商户选择选项']);
Route::post('', [MerchantController::class, 'store'])->name('adminApiMerchantsStore')->setParams(['real_name' => '新增商户']);
Route::get('/{id}/overview', [MerchantController::class, 'overview'])->name('adminApiMerchantsOverview')->setParams(['real_name' => '商户总览']);
Route::post('/{id}/reset-password', [MerchantController::class, 'resetPassword'])->name('adminApiMerchantsResetPassword')->setParams(['real_name' => '重置商户密码']);
Route::post('/{id}/login-token', [MerchantController::class, 'loginToken'])->name('adminApiMerchantsLoginToken')->setParams(['real_name' => '商户后台登录令牌']);
Route::post('/{id}/issue-credential', [MerchantController::class, 'issueCredential'])->name('adminApiMerchantsIssueCredential')->setParams(['real_name' => '生成或重置商户 API 凭证']);
Route::get('/{id}', [MerchantController::class, 'show'])->name('adminApiMerchantsShow')->setParams(['real_name' => '商户详情']);
Route::put('/{id}', [MerchantController::class, 'update'])->name('adminApiMerchantsUpdate')->setParams(['real_name' => '更新商户']);
Route::delete('/{id}', [MerchantController::class, 'destroy'])->name('adminApiMerchantsDestroy')->setParams(['real_name' => '删除商户']);
});
Route::get('/admin-users', [AdminUserController::class, 'index'])->name('adminApiAdminUsersIndex')->setParams(['real_name' => '管理员列表']);
Route::get('/admin-users/{id}', [AdminUserController::class, 'show'])->name('adminApiAdminUsersShow')->setParams(['real_name' => '管理员详情']);
Route::post('/admin-users', [AdminUserController::class, 'store'])->name('adminApiAdminUsersStore')->setParams(['real_name' => '新增管理员']);
Route::put('/admin-users/{id}', [AdminUserController::class, 'update'])->name('adminApiAdminUsersUpdate')->setParams(['real_name' => '更新管理员']);
Route::delete('/admin-users/{id}', [AdminUserController::class, 'destroy'])->name('adminApiAdminUsersDestroy')->setParams(['real_name' => '删除管理员']);
Route::group('/merchant-api-credentials', function () {
Route::get('', [MerchantApiCredentialController::class, 'index'])->name('adminApiMerchantApiCredentialsIndex')->setParams(['real_name' => '商户 API 凭证列表']);
Route::post('', [MerchantApiCredentialController::class, 'store'])->name('adminApiMerchantApiCredentialsStore')->setParams(['real_name' => '开通商户 API 凭证']);
Route::get('/{id}', [MerchantApiCredentialController::class, 'show'])->name('adminApiMerchantApiCredentialsShow')->setParams(['real_name' => '商户 API 凭证详情']);
Route::put('/{id}', [MerchantApiCredentialController::class, 'update'])->name('adminApiMerchantApiCredentialsUpdate')->setParams(['real_name' => '更新商户 API 凭证']);
Route::delete('/{id}', [MerchantApiCredentialController::class, 'destroy'])->name('adminApiMerchantApiCredentialsDestroy')->setParams(['real_name' => '删除商户 API 凭证']);
});
Route::group('/merchant-groups', function () {
Route::get('', [MerchantGroupController::class, 'index'])->name('adminApiMerchantGroupsIndex')->setParams(['real_name' => '商户分组列表']);
Route::get('/options', [MerchantGroupController::class, 'options'])->name('adminApiMerchantGroupsOptions')->setParams(['real_name' => '商户分组选项']);
Route::post('', [MerchantGroupController::class, 'store'])->name('adminApiMerchantGroupsStore')->setParams(['real_name' => '新增商户分组']);
Route::get('/{id}', [MerchantGroupController::class, 'show'])->name('adminApiMerchantGroupsShow')->setParams(['real_name' => '商户分组详情']);
Route::put('/{id}', [MerchantGroupController::class, 'update'])->name('adminApiMerchantGroupsUpdate')->setParams(['real_name' => '更新商户分组']);
Route::delete('/{id}', [MerchantGroupController::class, 'destroy'])->name('adminApiMerchantGroupsDestroy')->setParams(['real_name' => '删除商户分组']);
});
Route::get('/merchant-api-credentials', [MerchantApiCredentialController::class, 'index'])->name('adminApiMerchantApiCredentialsIndex')->setParams(['real_name' => '商户 API 凭证列表']);
Route::get('/merchant-api-credentials/{id}', [MerchantApiCredentialController::class, 'show'])->name('adminApiMerchantApiCredentialsShow')->setParams(['real_name' => '商户 API 凭证详情']);
Route::post('/merchant-api-credentials', [MerchantApiCredentialController::class, 'store'])->name('adminApiMerchantApiCredentialsStore')->setParams(['real_name' => '开通商户 API 凭证']);
Route::put('/merchant-api-credentials/{id}', [MerchantApiCredentialController::class, 'update'])->name('adminApiMerchantApiCredentialsUpdate')->setParams(['real_name' => '更新商户 API 凭证']);
Route::delete('/merchant-api-credentials/{id}', [MerchantApiCredentialController::class, 'destroy'])->name('adminApiMerchantApiCredentialsDestroy')->setParams(['real_name' => '删除商户 API 凭证']);
Route::group('/merchant-policies', function () {
Route::get('', [MerchantPolicyController::class, 'index'])->name('adminApiMerchantPoliciesIndex')->setParams(['real_name' => '商户策略列表']);
Route::post('', [MerchantPolicyController::class, 'store'])->name('adminApiMerchantPoliciesStore')->setParams(['real_name' => '新增商户策略']);
Route::get('/{merchantId}', [MerchantPolicyController::class, 'show'])->name('adminApiMerchantPoliciesShow')->setParams(['real_name' => '商户策略详情']);
Route::put('/{merchantId}', [MerchantPolicyController::class, 'update'])->name('adminApiMerchantPoliciesUpdate')->setParams(['real_name' => '更新商户策略']);
Route::delete('/{merchantId}', [MerchantPolicyController::class, 'destroy'])->name('adminApiMerchantPoliciesDestroy')->setParams(['real_name' => '删除商户策略']);
});
Route::get('/merchant-groups', [MerchantGroupController::class, 'index'])->name('adminApiMerchantGroupsIndex')->setParams(['real_name' => '商户分组列表']);
Route::get('/merchant-groups/options', [MerchantGroupController::class, 'options'])->name('adminApiMerchantGroupsOptions')->setParams(['real_name' => '商户分组选项']);
Route::get('/merchant-groups/{id}', [MerchantGroupController::class, 'show'])->name('adminApiMerchantGroupsShow')->setParams(['real_name' => '商户分组详情']);
Route::post('/merchant-groups', [MerchantGroupController::class, 'store'])->name('adminApiMerchantGroupsStore')->setParams(['real_name' => '新增商户分组']);
Route::put('/merchant-groups/{id}', [MerchantGroupController::class, 'update'])->name('adminApiMerchantGroupsUpdate')->setParams(['real_name' => '更新商户分组']);
Route::delete('/merchant-groups/{id}', [MerchantGroupController::class, 'destroy'])->name('adminApiMerchantGroupsDestroy')->setParams(['real_name' => '删除商户分组']);
// 支付配置
Route::group('/payment-types', function () {
Route::get('', [PaymentTypeController::class, 'index'])->name('adminApiPaymentTypesIndex')->setParams(['real_name' => '支付方式列表']);
Route::get('/options', [PaymentTypeController::class, 'options'])->name('adminApiPaymentTypesOptions')->setParams(['real_name' => '支付方式选项']);
Route::post('', [PaymentTypeController::class, 'store'])->name('adminApiPaymentTypesStore')->setParams(['real_name' => '新增支付方式']);
Route::get('/{id}', [PaymentTypeController::class, 'show'])->name('adminApiPaymentTypesShow')->setParams(['real_name' => '支付方式详情']);
Route::put('/{id}', [PaymentTypeController::class, 'update'])->name('adminApiPaymentTypesUpdate')->setParams(['real_name' => '更新支付方式']);
Route::delete('/{id}', [PaymentTypeController::class, 'destroy'])->name('adminApiPaymentTypesDestroy')->setParams(['real_name' => '删除支付方式']);
});
Route::get('/merchant-policies', [MerchantPolicyController::class, 'index'])->name('adminApiMerchantPoliciesIndex')->setParams(['real_name' => '商户策略列表']);
Route::get('/merchant-policies/{merchantId}', [MerchantPolicyController::class, 'show'])->name('adminApiMerchantPoliciesShow')->setParams(['real_name' => '商户策略详情']);
Route::post('/merchant-policies', [MerchantPolicyController::class, 'store'])->name('adminApiMerchantPoliciesStore')->setParams(['real_name' => '新增商户策略']);
Route::put('/merchant-policies/{merchantId}', [MerchantPolicyController::class, 'update'])->name('adminApiMerchantPoliciesUpdate')->setParams(['real_name' => '更新商户策略']);
Route::delete('/merchant-policies/{merchantId}', [MerchantPolicyController::class, 'destroy'])->name('adminApiMerchantPoliciesDestroy')->setParams(['real_name' => '删除商户策略']);
Route::group('/payment-plugins', function () {
Route::get('', [PaymentPluginController::class, 'index'])->name('adminApiPaymentPluginsIndex')->setParams(['real_name' => '支付插件列表']);
Route::get('/options', [PaymentPluginController::class, 'options'])->name('adminApiPaymentPluginsOptions')->setParams(['real_name' => '支付插件选项']);
Route::get('/select-options', [PaymentPluginController::class, 'selectOptions'])->name('adminApiPaymentPluginsSelectOptions')->setParams(['real_name' => '支付插件选择项']);
Route::get('/channel-options', [PaymentPluginController::class, 'channelOptions'])->name('adminApiPaymentPluginsChannelOptions')->setParams(['real_name' => '支付插件通道选项']);
Route::post('/refresh', [PaymentPluginController::class, 'refresh'])->name('adminApiPaymentPluginsRefresh')->setParams(['real_name' => '刷新支付插件']);
Route::get('/{code}/schema', [PaymentPluginController::class, 'schema'])->name('adminApiPaymentPluginsSchema')->setParams(['real_name' => '支付插件配置结构']);
Route::get('/{code}', [PaymentPluginController::class, 'show'])->name('adminApiPaymentPluginsShow')->setParams(['real_name' => '支付插件详情']);
Route::put('/{code}', [PaymentPluginController::class, 'update'])->name('adminApiPaymentPluginsUpdate')->setParams(['real_name' => '更新支付插件']);
});
Route::get('/payment-types', [PaymentTypeController::class, 'index'])->name('adminApiPaymentTypesIndex')->setParams(['real_name' => '支付方式列表']);
Route::get('/payment-types/options', [PaymentTypeController::class, 'options'])->name('adminApiPaymentTypesOptions')->setParams(['real_name' => '支付方式选项']);
Route::get('/payment-types/{id}', [PaymentTypeController::class, 'show'])->name('adminApiPaymentTypesShow')->setParams(['real_name' => '支付方式详情']);
Route::post('/payment-types', [PaymentTypeController::class, 'store'])->name('adminApiPaymentTypesStore')->setParams(['real_name' => '新增支付方式']);
Route::put('/payment-types/{id}', [PaymentTypeController::class, 'update'])->name('adminApiPaymentTypesUpdate')->setParams(['real_name' => '更新支付方式']);
Route::delete('/payment-types/{id}', [PaymentTypeController::class, 'destroy'])->name('adminApiPaymentTypesDestroy')->setParams(['real_name' => '删除支付方式']);
Route::group('/payment-plugin-confs', function () {
Route::get('', [PaymentPluginConfController::class, 'index'])->name('adminApiPaymentPluginConfsIndex')->setParams(['real_name' => '支付插件配置列表']);
Route::get('/options', [PaymentPluginConfController::class, 'options'])->name('adminApiPaymentPluginConfsOptions')->setParams(['real_name' => '支付插件配置选项']);
Route::get('/select-options', [PaymentPluginConfController::class, 'selectOptions'])->name('adminApiPaymentPluginConfsSelectOptions')->setParams(['real_name' => '支付插件配置选择项']);
Route::post('', [PaymentPluginConfController::class, 'store'])->name('adminApiPaymentPluginConfsStore')->setParams(['real_name' => '新增支付插件配置']);
Route::get('/{id}', [PaymentPluginConfController::class, 'show'])->name('adminApiPaymentPluginConfsShow')->setParams(['real_name' => '支付插件配置详情']);
Route::put('/{id}', [PaymentPluginConfController::class, 'update'])->name('adminApiPaymentPluginConfsUpdate')->setParams(['real_name' => '更新支付插件配置']);
Route::delete('/{id}', [PaymentPluginConfController::class, 'destroy'])->name('adminApiPaymentPluginConfsDestroy')->setParams(['real_name' => '删除支付插件配置']);
});
Route::get('/payment-plugins', [PaymentPluginController::class, 'index'])->name('adminApiPaymentPluginsIndex')->setParams(['real_name' => '支付插件列表']);
Route::get('/payment-plugins/options', [PaymentPluginController::class, 'options'])->name('adminApiPaymentPluginsOptions')->setParams(['real_name' => '支付插件选项']);
Route::get('/payment-plugins/select-options', [PaymentPluginController::class, 'selectOptions'])->name('adminApiPaymentPluginsSelectOptions')->setParams(['real_name' => '支付插件选择项']);
Route::get('/payment-plugins/channel-options', [PaymentPluginController::class, 'channelOptions'])->name('adminApiPaymentPluginsChannelOptions')->setParams(['real_name' => '支付插件通道选项']);
Route::get('/payment-plugins/{code}/schema', [PaymentPluginController::class, 'schema'])->name('adminApiPaymentPluginsSchema')->setParams(['real_name' => '支付插件配置结构']);
Route::get('/payment-plugins/{code}', [PaymentPluginController::class, 'show'])->name('adminApiPaymentPluginsShow')->setParams(['real_name' => '支付插件详情']);
Route::post('/payment-plugins/refresh', [PaymentPluginController::class, 'refresh'])->name('adminApiPaymentPluginsRefresh')->setParams(['real_name' => '刷新支付插件']);
Route::put('/payment-plugins/{code}', [PaymentPluginController::class, 'update'])->name('adminApiPaymentPluginsUpdate')->setParams(['real_name' => '更新支付插件']);
Route::group('/payment-channels', function () {
Route::get('', [PaymentChannelController::class, 'index'])->name('adminApiPaymentChannelsIndex')->setParams(['real_name' => '支付通道列表']);
Route::get('/options', [PaymentChannelController::class, 'options'])->name('adminApiPaymentChannelsOptions')->setParams(['real_name' => '支付通道选项']);
Route::get('/select-options', [PaymentChannelController::class, 'selectOptions'])->name('adminApiPaymentChannelsSelectOptions')->setParams(['real_name' => '支付通道选项']);
Route::get('/route-options', [PaymentChannelController::class, 'routeOptions'])->name('adminApiPaymentChannelsRouteOptions')->setParams(['real_name' => '支付通道路由选项']);
Route::post('', [PaymentChannelController::class, 'store'])->name('adminApiPaymentChannelsStore')->setParams(['real_name' => '新增支付通道']);
Route::post('/{id}/test', [PaymentChannelController::class, 'test'])->name('adminApiPaymentChannelsTest')->setParams(['real_name' => '测试支付通道']);
Route::get('/{id}', [PaymentChannelController::class, 'show'])->name('adminApiPaymentChannelsShow')->setParams(['real_name' => '支付通道详情']);
Route::put('/{id}', [PaymentChannelController::class, 'update'])->name('adminApiPaymentChannelsUpdate')->setParams(['real_name' => '更新支付通道']);
Route::delete('/{id}', [PaymentChannelController::class, 'destroy'])->name('adminApiPaymentChannelsDestroy')->setParams(['real_name' => '删除支付通道']);
});
Route::get('/payment-plugin-confs', [PaymentPluginConfController::class, 'index'])->name('adminApiPaymentPluginConfsIndex')->setParams(['real_name' => '支付插件配置列表']);
Route::get('/payment-plugin-confs/options', [PaymentPluginConfController::class, 'options'])->name('adminApiPaymentPluginConfsOptions')->setParams(['real_name' => '支付插件配置选项']);
Route::get('/payment-plugin-confs/select-options', [PaymentPluginConfController::class, 'selectOptions'])->name('adminApiPaymentPluginConfsSelectOptions')->setParams(['real_name' => '支付插件配置选择项']);
Route::get('/payment-plugin-confs/{id}', [PaymentPluginConfController::class, 'show'])->name('adminApiPaymentPluginConfsShow')->setParams(['real_name' => '支付插件配置详情']);
Route::post('/payment-plugin-confs', [PaymentPluginConfController::class, 'store'])->name('adminApiPaymentPluginConfsStore')->setParams(['real_name' => '新增支付插件配置']);
Route::put('/payment-plugin-confs/{id}', [PaymentPluginConfController::class, 'update'])->name('adminApiPaymentPluginConfsUpdate')->setParams(['real_name' => '更新支付插件配置']);
Route::delete('/payment-plugin-confs/{id}', [PaymentPluginConfController::class, 'destroy'])->name('adminApiPaymentPluginConfsDestroy')->setParams(['real_name' => '删除支付插件配置']);
Route::group('/payment-poll-groups', function () {
Route::get('', [PaymentPollGroupController::class, 'index'])->name('adminApiPaymentPollGroupsIndex')->setParams(['real_name' => '轮询组列表']);
Route::get('/options', [PaymentPollGroupController::class, 'options'])->name('adminApiPaymentPollGroupsOptions')->setParams(['real_name' => '轮询组选项']);
Route::post('', [PaymentPollGroupController::class, 'store'])->name('adminApiPaymentPollGroupsStore')->setParams(['real_name' => '新增轮询组']);
Route::get('/{id}', [PaymentPollGroupController::class, 'show'])->name('adminApiPaymentPollGroupsShow')->setParams(['real_name' => '轮询组详情']);
Route::put('/{id}', [PaymentPollGroupController::class, 'update'])->name('adminApiPaymentPollGroupsUpdate')->setParams(['real_name' => '更新轮询组']);
Route::delete('/{id}', [PaymentPollGroupController::class, 'destroy'])->name('adminApiPaymentPollGroupsDestroy')->setParams(['real_name' => '删除轮询组']);
});
Route::get('/payment-channels', [PaymentChannelController::class, 'index'])->name('adminApiPaymentChannelsIndex')->setParams(['real_name' => '支付通道列表']);
Route::get('/payment-channels/options', [PaymentChannelController::class, 'options'])->name('adminApiPaymentChannelsOptions')->setParams(['real_name' => '支付通道选项']);
Route::get('/payment-channels/select-options', [PaymentChannelController::class, 'selectOptions'])->name('adminApiPaymentChannelsSelectOptions')->setParams(['real_name' => '支付通道选择项']);
Route::get('/payment-channels/route-options', [PaymentChannelController::class, 'routeOptions'])->name('adminApiPaymentChannelsRouteOptions')->setParams(['real_name' => '支付通道路由选项']);
Route::get('/payment-channels/{id}', [PaymentChannelController::class, 'show'])->name('adminApiPaymentChannelsShow')->setParams(['real_name' => '支付通道详情']);
Route::post('/payment-channels', [PaymentChannelController::class, 'store'])->name('adminApiPaymentChannelsStore')->setParams(['real_name' => '新增支付通道']);
Route::put('/payment-channels/{id}', [PaymentChannelController::class, 'update'])->name('adminApiPaymentChannelsUpdate')->setParams(['real_name' => '更新支付通道']);
Route::delete('/payment-channels/{id}', [PaymentChannelController::class, 'destroy'])->name('adminApiPaymentChannelsDestroy')->setParams(['real_name' => '删除支付通道']);
Route::group('/payment-poll-group-channels', function () {
Route::get('', [PaymentPollGroupChannelController::class, 'index'])->name('adminApiPaymentPollGroupChannelsIndex')->setParams(['real_name' => '轮询组通道列表']);
Route::post('', [PaymentPollGroupChannelController::class, 'store'])->name('adminApiPaymentPollGroupChannelsStore')->setParams(['real_name' => '新增轮询组通道']);
Route::get('/{id}', [PaymentPollGroupChannelController::class, 'show'])->name('adminApiPaymentPollGroupChannelsShow')->setParams(['real_name' => '轮询组通道详情']);
Route::put('/{id}', [PaymentPollGroupChannelController::class, 'update'])->name('adminApiPaymentPollGroupChannelsUpdate')->setParams(['real_name' => '更新轮询组通道']);
Route::delete('/{id}', [PaymentPollGroupChannelController::class, 'destroy'])->name('adminApiPaymentPollGroupChannelsDestroy')->setParams(['real_name' => '删除轮询组通道']);
});
Route::get('/payment-poll-groups', [PaymentPollGroupController::class, 'index'])->name('adminApiPaymentPollGroupsIndex')->setParams(['real_name' => '轮询组列表']);
Route::get('/payment-poll-groups/options', [PaymentPollGroupController::class, 'options'])->name('adminApiPaymentPollGroupsOptions')->setParams(['real_name' => '轮询组选项']);
Route::get('/payment-poll-groups/{id}', [PaymentPollGroupController::class, 'show'])->name('adminApiPaymentPollGroupsShow')->setParams(['real_name' => '轮询组详情']);
Route::post('/payment-poll-groups', [PaymentPollGroupController::class, 'store'])->name('adminApiPaymentPollGroupsStore')->setParams(['real_name' => '新增轮询组']);
Route::put('/payment-poll-groups/{id}', [PaymentPollGroupController::class, 'update'])->name('adminApiPaymentPollGroupsUpdate')->setParams(['real_name' => '更新轮询组']);
Route::delete('/payment-poll-groups/{id}', [PaymentPollGroupController::class, 'destroy'])->name('adminApiPaymentPollGroupsDestroy')->setParams(['real_name' => '删除轮询组']);
Route::get('/payment-poll-group-channels', [PaymentPollGroupChannelController::class, 'index'])->name('adminApiPaymentPollGroupChannelsIndex')->setParams(['real_name' => '轮询组通道列表']);
Route::get('/payment-poll-group-channels/{id}', [PaymentPollGroupChannelController::class, 'show'])->name('adminApiPaymentPollGroupChannelsShow')->setParams(['real_name' => '轮询组通道详情']);
Route::post('/payment-poll-group-channels', [PaymentPollGroupChannelController::class, 'store'])->name('adminApiPaymentPollGroupChannelsStore')->setParams(['real_name' => '新增轮询组通道']);
Route::put('/payment-poll-group-channels/{id}', [PaymentPollGroupChannelController::class, 'update'])->name('adminApiPaymentPollGroupChannelsUpdate')->setParams(['real_name' => '更新轮询组通道']);
Route::delete('/payment-poll-group-channels/{id}', [PaymentPollGroupChannelController::class, 'destroy'])->name('adminApiPaymentPollGroupChannelsDestroy')->setParams(['real_name' => '删除轮询组通道']);
Route::get('/payment-poll-group-binds', [PaymentPollGroupBindController::class, 'index'])->name('adminApiPaymentPollGroupBindsIndex')->setParams(['real_name' => '轮询组绑定列表']);
Route::get('/payment-poll-group-binds/{id}', [PaymentPollGroupBindController::class, 'show'])->name('adminApiPaymentPollGroupBindsShow')->setParams(['real_name' => '轮询组绑定详情']);
Route::post('/payment-poll-group-binds', [PaymentPollGroupBindController::class, 'store'])->name('adminApiPaymentPollGroupBindsStore')->setParams(['real_name' => '新增轮询组绑定']);
Route::put('/payment-poll-group-binds/{id}', [PaymentPollGroupBindController::class, 'update'])->name('adminApiPaymentPollGroupBindsUpdate')->setParams(['real_name' => '更新轮询组绑定']);
Route::delete('/payment-poll-group-binds/{id}', [PaymentPollGroupBindController::class, 'destroy'])->name('adminApiPaymentPollGroupBindsDestroy')->setParams(['real_name' => '删除轮询组绑定']);
Route::group('/payment-poll-group-binds', function () {
Route::get('', [PaymentPollGroupBindController::class, 'index'])->name('adminApiPaymentPollGroupBindsIndex')->setParams(['real_name' => '轮询组绑定列表']);
Route::post('', [PaymentPollGroupBindController::class, 'store'])->name('adminApiPaymentPollGroupBindsStore')->setParams(['real_name' => '新增轮询组绑定']);
Route::get('/{id}', [PaymentPollGroupBindController::class, 'show'])->name('adminApiPaymentPollGroupBindsShow')->setParams(['real_name' => '轮询组绑定详情']);
Route::put('/{id}', [PaymentPollGroupBindController::class, 'update'])->name('adminApiPaymentPollGroupBindsUpdate')->setParams(['real_name' => '更新轮询组绑定']);
Route::delete('/{id}', [PaymentPollGroupBindController::class, 'destroy'])->name('adminApiPaymentPollGroupBindsDestroy')->setParams(['real_name' => '删除轮询组绑定']);
});
Route::get('/routes/resolve', [RouteController::class, 'resolve'])->name('adminApiRoutesResolve')->setParams(['real_name' => '解析路由']);
Route::get('/channel-daily-stats', [ChannelDailyStatController::class, 'index'])->name('adminApiChannelDailyStatsIndex')->setParams(['real_name' => '渠道日统计列表']);
Route::get('/channel-daily-stats/{id}', [ChannelDailyStatController::class, 'show'])->name('adminApiChannelDailyStatsShow')->setParams(['real_name' => '渠道日统计详情']);
// 文件存储
Route::group('/file-asset', function () {
Route::get('', [FileRecordController::class, 'index'])->name('adminApiFileRecordIndex')->setParams(['real_name' => '文件列表']);
Route::get('/options', [FileRecordController::class, 'options'])->name('adminApiFileRecordOptions')->setParams(['real_name' => '文件选项']);
Route::post('/upload', [FileRecordController::class, 'upload'])->name('adminApiFileRecordUpload')->setParams(['real_name' => '上传文件']);
Route::post('/import-remote', [FileRecordController::class, 'importRemote'])->name('adminApiFileRecordImportRemote')->setParams(['real_name' => '导入远程文件']);
Route::get('/{id}/preview', [FileRecordController::class, 'preview'])->name('adminApiFileRecordPreview')->setParams(['real_name' => '文件预览']);
Route::get('/{id}/download', [FileRecordController::class, 'download'])->name('adminApiFileRecordDownload')->setParams(['real_name' => '文件下载']);
Route::get('/{id}', [FileRecordController::class, 'show'])->name('adminApiFileRecordShow')->setParams(['real_name' => '文件详情']);
Route::delete('/{id}', [FileRecordController::class, 'destroy'])->name('adminApiFileRecordDestroy')->setParams(['real_name' => '删除文件']);
});
Route::get('/file-asset/options', [FileRecordController::class, 'options'])->name('adminApiFileRecordOptions')->setParams(['real_name' => '文件选项']);
Route::get('/file-asset', [FileRecordController::class, 'index'])->name('adminApiFileRecordIndex')->setParams(['real_name' => '文件列表']);
Route::post('/file-asset/upload', [FileRecordController::class, 'upload'])->name('adminApiFileRecordUpload')->setParams(['real_name' => '上传文件']);
Route::post('/file-asset/import-remote', [FileRecordController::class, 'importRemote'])->name('adminApiFileRecordImportRemote')->setParams(['real_name' => '导入远程文件']);
Route::get('/file-asset/{id}/preview', [FileRecordController::class, 'preview'])->name('adminApiFileRecordPreview')->setParams(['real_name' => '文件预览']);
Route::get('/file-asset/{id}/download', [FileRecordController::class, 'download'])->name('adminApiFileRecordDownload')->setParams(['real_name' => '文件下载']);
Route::get('/file-asset/{id}', [FileRecordController::class, 'show'])->name('adminApiFileRecordShow')->setParams(['real_name' => '文件详情']);
Route::delete('/file-asset/{id}', [FileRecordController::class, 'destroy'])->name('adminApiFileRecordDestroy')->setParams(['real_name' => '删除文件']);
// 交易订单
Route::group('/pay-orders', function () {
Route::get('', [PayOrderController::class, 'index'])->name('adminApiPayOrdersIndex')->setParams(['real_name' => '支付订单列表']);
Route::get('/{payNo}/actions', [PayOrderController::class, 'actions'])->name('adminApiPayOrdersActions')->setParams(['real_name' => '支付订单可操作项']);
Route::post('/{payNo}/renotify', [PayOrderController::class, 'renotify'])->name('adminApiPayOrdersRenotify')->setParams(['real_name' => '支付订单重新通知']);
Route::post('/{payNo}/query', [PayOrderController::class, 'activeQuery'])->name('adminApiPayOrdersActiveQuery')->setParams(['real_name' => '支付订单主动查询']);
Route::post('/{payNo}/api-refund', [PayOrderController::class, 'apiRefund'])->name('adminApiPayOrdersApiRefund')->setParams(['real_name' => '支付订单 API 退款']);
Route::post('/{payNo}/manual-refund', [PayOrderController::class, 'manualRefund'])->name('adminApiPayOrdersManualRefund')->setParams(['real_name' => '支付订单手动退款']);
Route::post('/{payNo}/manual-success', [PayOrderController::class, 'manualSuccess'])->name('adminApiPayOrdersManualSuccess')->setParams(['real_name' => '支付订单手动补单']);
Route::post('/{payNo}/freeze', [PayOrderController::class, 'freeze'])->name('adminApiPayOrdersFreeze')->setParams(['real_name' => '支付订单冻结']);
Route::post('/{payNo}/unfreeze', [PayOrderController::class, 'unfreeze'])->name('adminApiPayOrdersUnfreeze')->setParams(['real_name' => '支付订单解冻']);
Route::get('/{payNo}', [PayOrderController::class, 'show'])->name('adminApiPayOrdersShow')->setParams(['real_name' => '支付订单详情']);
});
Route::get('/pay-orders', [PayOrderController::class, 'index'])->name('adminApiPayOrdersIndex')->setParams(['real_name' => '支付订单列表']);
Route::get('/pay-orders/{payNo}', [PayOrderController::class, 'show'])->name('adminApiPayOrdersShow')->setParams(['real_name' => '支付订单详情']);
Route::get('/refund-orders', [RefundOrderController::class, 'index'])->name('adminApiRefundOrdersIndex')->setParams(['real_name' => '退款订单列表']);
Route::get('/refund-orders/{refundNo}', [RefundOrderController::class, 'show'])->name('adminApiRefundOrdersShow')->setParams(['real_name' => '退款订单详情']);
Route::post('/refund-orders/{refundNo}/retry', [RefundOrderController::class, 'retry'])->name('adminApiRefundOrdersRetry')->setParams(['real_name' => '退款重试']);
Route::group('/refund-orders', function () {
Route::get('', [RefundOrderController::class, 'index'])->name('adminApiRefundOrdersIndex')->setParams(['real_name' => '退款订单列表']);
Route::get('/{refundNo}', [RefundOrderController::class, 'show'])->name('adminApiRefundOrdersShow')->setParams(['real_name' => '退款订单详情']);
Route::post('/{refundNo}/retry', [RefundOrderController::class, 'retry'])->name('adminApiRefundOrdersRetry')->setParams(['real_name' => '退款重试']);
});
Route::get('/settlement-orders', [SettlementOrderController::class, 'index'])->name('adminApiSettlementOrdersIndex')->setParams(['real_name' => '清算订单列表']);
Route::get('/settlement-orders/{settleNo}', [SettlementOrderController::class, 'show'])->name('adminApiSettlementOrdersShow')->setParams(['real_name' => '清算订单详情']);
Route::group('/settlement-orders', function () {
Route::get('', [SettlementOrderController::class, 'index'])->name('adminApiSettlementOrdersIndex')->setParams(['real_name' => '清算订单列表']);
Route::post('/{settleNo}/complete', [SettlementOrderController::class, 'complete'])->name('adminApiSettlementOrdersComplete')->setParams(['real_name' => '清算订单入账']);
Route::post('/{settleNo}/fail', [SettlementOrderController::class, 'markFailed'])->name('adminApiSettlementOrdersFail')->setParams(['real_name' => '清算订单冲正']);
Route::get('/{settleNo}', [SettlementOrderController::class, 'show'])->name('adminApiSettlementOrdersShow')->setParams(['real_name' => '清算订单详情']);
});
Route::get('/channel-notify-logs', [ChannelNotifyLogController::class, 'index'])->name('adminApiChannelNotifyLogsIndex')->setParams(['real_name' => '渠道通知日志列表']);
Route::get('/channel-notify-logs/{id}', [ChannelNotifyLogController::class, 'show'])->name('adminApiChannelNotifyLogsShow')->setParams(['real_name' => '渠道通知日志详情']);
// 运维与日志
Route::group('/channel-daily-stats', function () {
Route::get('', [ChannelDailyStatController::class, 'index'])->name('adminApiChannelDailyStatsIndex')->setParams(['real_name' => '渠道日统计列表']);
Route::get('/{id}', [ChannelDailyStatController::class, 'show'])->name('adminApiChannelDailyStatsShow')->setParams(['real_name' => '渠道日统计详情']);
});
Route::get('/pay-callback-logs', [PayCallbackLogController::class, 'index'])->name('adminApiPayCallbackLogsIndex')->setParams(['real_name' => '支付回调日志列表']);
Route::get('/pay-callback-logs/{id}', [PayCallbackLogController::class, 'show'])->name('adminApiPayCallbackLogsShow')->setParams(['real_name' => '支付回调日志详情']);
Route::group('/channel-notify-logs', function () {
Route::get('', [ChannelNotifyLogController::class, 'index'])->name('adminApiChannelNotifyLogsIndex')->setParams(['real_name' => '渠道通知日志列表']);
Route::get('/{id}', [ChannelNotifyLogController::class, 'show'])->name('adminApiChannelNotifyLogsShow')->setParams(['real_name' => '渠道通知日志详情']);
});
Route::get('/merchant-notify-tasks', [MerchantNotifyTaskController::class, 'index'])->name('adminApiMerchantNotifyTasksIndex')->setParams(['real_name' => '商户通知任务列表']);
Route::get('/merchant-notify-tasks/{notifyNo}', [MerchantNotifyTaskController::class, 'show'])->name('adminApiMerchantNotifyTasksShow')->setParams(['real_name' => '商户通知任务详情']);
Route::post('/merchant-notify-tasks/{notifyNo}/retry', [MerchantNotifyTaskController::class, 'retry'])->name('adminApiMerchantNotifyTasksRetry')->setParams(['real_name' => '商户通知任务重试']);
Route::group('/pay-callback-logs', function () {
Route::get('', [PayCallbackLogController::class, 'index'])->name('adminApiPayCallbackLogsIndex')->setParams(['real_name' => '支付回调日志列表']);
Route::get('/{id}', [PayCallbackLogController::class, 'show'])->name('adminApiPayCallbackLogsShow')->setParams(['real_name' => '支付回调日志详情']);
});
Route::get('/merchant-accounts', [MerchantAccountController::class, 'index'])->name('adminApiMerchantAccountsIndex')->setParams(['real_name' => '资金账户列表']);
Route::get('/merchant-accounts/summary', [MerchantAccountController::class, 'summary'])->name('adminApiMerchantAccountsSummary')->setParams(['real_name' => '资金账户总览']);
Route::get('/merchant-accounts/{id}', [MerchantAccountController::class, 'show'])->name('adminApiMerchantAccountsShow')->setParams(['real_name' => '资金账户详情']);
Route::group('/merchant-notify-tasks', function () {
Route::get('', [MerchantNotifyTaskController::class, 'index'])->name('adminApiMerchantNotifyTasksIndex')->setParams(['real_name' => '商户通知任务列表']);
Route::get('/{notifyNo}', [MerchantNotifyTaskController::class, 'show'])->name('adminApiMerchantNotifyTasksShow')->setParams(['real_name' => '商户通知任务详情']);
Route::post('/{notifyNo}/retry', [MerchantNotifyTaskController::class, 'retry'])->name('adminApiMerchantNotifyTasksRetry')->setParams(['real_name' => '商户通知任务重试']);
});
Route::get('/account-ledgers', [MerchantAccountLedgerController::class, 'index'])->name('adminApiAccountLedgersIndex')->setParams(['real_name' => '资金流水列表']);
Route::get('/account-ledgers/{id}', [MerchantAccountLedgerController::class, 'show'])->name('adminApiAccountLedgersShow')->setParams(['real_name' => '资金流水详情']);
// 资金账户
Route::group('/merchant-accounts', function () {
Route::get('', [MerchantAccountController::class, 'index'])->name('adminApiMerchantAccountsIndex')->setParams(['real_name' => '资金账户列表']);
Route::get('/summary', [MerchantAccountController::class, 'summary'])->name('adminApiMerchantAccountsSummary')->setParams(['real_name' => '资金账户总览']);
Route::get('/{id}', [MerchantAccountController::class, 'show'])->name('adminApiMerchantAccountsShow')->setParams(['real_name' => '资金账户详情']);
});
Route::get('/system/menu-tree', [SystemController::class, 'menuTree'])->name('adminApiMenuTree')->setParams(['real_name' => '菜单树']);
Route::get('/system/dict-items', [SystemController::class, 'dictItems'])->name('adminApiDictItems')->setParams(['real_name' => '字典项']);
Route::group('/account-ledgers', function () {
Route::get('', [MerchantAccountLedgerController::class, 'index'])->name('adminApiAccountLedgersIndex')->setParams(['real_name' => '资金流水列表']);
Route::get('/{id}', [MerchantAccountLedgerController::class, 'show'])->name('adminApiAccountLedgersShow')->setParams(['real_name' => '资金流水详情']);
});
Route::get('/system-config-pages', [SystemConfigPageController::class, 'index'])->name('adminApiSystemConfigPagesIndex')->setParams(['real_name' => '系统配置页面列表']);
Route::get('/system-config-pages/{groupCode}', [SystemConfigPageController::class, 'show'])->name('adminApiSystemConfigPagesShow')->setParams(['real_name' => '系统配置页面详情']);
Route::post('/system-config-pages/{groupCode}', [SystemConfigPageController::class, 'store'])->name('adminApiSystemConfigPagesStore')->setParams(['real_name' => '保存系统配置页面']);
// 系统管理
Route::group('/admin-users', function () {
Route::get('', [AdminUserController::class, 'index'])->name('adminApiAdminUsersIndex')->setParams(['real_name' => '管理员列表']);
Route::post('', [AdminUserController::class, 'store'])->name('adminApiAdminUsersStore')->setParams(['real_name' => '新增管理员']);
Route::get('/{id}', [AdminUserController::class, 'show'])->name('adminApiAdminUsersShow')->setParams(['real_name' => '管理员详情']);
Route::put('/{id}', [AdminUserController::class, 'update'])->name('adminApiAdminUsersUpdate')->setParams(['real_name' => '更新管理员']);
Route::delete('/{id}', [AdminUserController::class, 'destroy'])->name('adminApiAdminUsersDestroy')->setParams(['real_name' => '删除管理员']);
});
Route::group('/system', function () {
Route::get('/menu-tree', [SystemController::class, 'menuTree'])->name('adminApiMenuTree')->setParams(['real_name' => '菜单树']);
Route::get('/dict-items', [SystemController::class, 'dictItems'])->name('adminApiDictItems')->setParams(['real_name' => '字典项']);
});
Route::group('/system-config-pages', function () {
Route::get('', [SystemConfigPageController::class, 'index'])->name('adminApiSystemConfigPagesIndex')->setParams(['real_name' => '系统配置页面列表']);
Route::get('/{groupCode}', [SystemConfigPageController::class, 'show'])->name('adminApiSystemConfigPagesShow')->setParams(['real_name' => '系统配置页面详情']);
Route::post('/{groupCode}', [SystemConfigPageController::class, 'store'])->name('adminApiSystemConfigPagesStore')->setParams(['real_name' => '保存系统配置页面']);
});
})->middleware([AdminAuthMiddleware::class]);
})->middleware([Cors::class]);

View File

@@ -5,7 +5,9 @@ use app\common\middleware\Cors;
use app\http\api\controller\cashier\CashierController;
use app\http\api\controller\epay\EpayV1Controller;
use app\http\api\controller\epay\EpayV2Controller;
use app\http\api\controller\system\SystemPublicConfigController;
// 收银台项目:页面路由
$serveCashierApp = static function () {
$indexPath = public_path('cashier/index.html');
if (!is_file($indexPath)) {
@@ -17,20 +19,6 @@ $serveCashierApp = static function () {
]);
};
// ePay V1 旧版接口
Route::group('', function () {
Route::any('/submit.php', [EpayV1Controller::class, 'submit'])->name('epayV1Submit')->setParams(['real_name' => 'ePay V1 页面跳转支付']);
Route::post('/mapi.php', [EpayV1Controller::class, 'mapi'])->name('epayV1Mapi')->setParams(['real_name' => 'ePay V1 接口支付']);
Route::any('/api.php', [EpayV1Controller::class, 'api'])->name('epayV1Api')->setParams(['real_name' => 'ePay V1 标准 API']);
})->middleware([Cors::class]);
// 收银台路由
Route::group('/api/cashier', function () {
Route::get('/context', [CashierController::class, 'context'])->name('cashierContext')->setParams(['real_name' => '收银台上下文']);
Route::post('/confirm', [CashierController::class, 'confirm'])->name('cashierConfirm')->setParams(['real_name' => '收银台确认支付']);
Route::get('/pay-order', [CashierController::class, 'payOrder'])->name('cashierPayOrder')->setParams(['real_name' => '收银台支付单详情']);
})->middleware([Cors::class]);
Route::group('/cashier', function () use ($serveCashierApp) {
Route::get('', $serveCashierApp)->name('cashierIndex')->setParams(['real_name' => '收银台首页']);
Route::any('/{bizNo:.+}', $serveCashierApp)->name('cashierDetail')->setParams(['real_name' => '收银台详情页']);
@@ -41,9 +29,25 @@ Route::group('/payment', function () use ($serveCashierApp) {
Route::any('/{path:.+}', $serveCashierApp)->name('paymentDetail')->setParams(['real_name' => '支付页详情']);
});
// ePay V2 新版接口
// 收银台项目:接口路由
Route::group('/api/cashier', function () {
Route::get('/config', [SystemPublicConfigController::class, 'cashier'])->name('cashierPublicConfig')->setParams(['real_name' => '收银台公开配置']);
Route::get('/context', [CashierController::class, 'context'])->name('cashierContext')->setParams(['real_name' => '收银台上下文']);
Route::post('/confirm', [CashierController::class, 'confirm'])->name('cashierConfirm')->setParams(['real_name' => '收银台确认支付']);
Route::get('/pay-order', [CashierController::class, 'payOrder'])->name('cashierPayOrder')->setParams(['real_name' => '收银台支付单详情']);
Route::get('/pay-order-status', [CashierController::class, 'payOrderStatus'])->name('cashierPayOrderStatus')->setParams(['real_name' => '收银台支付单状态']);
})->middleware([Cors::class]);
// 开放支付ePay V1 兼容入口
Route::group('', function () {
Route::any('/submit.php', [EpayV1Controller::class, 'submit'])->name('epayV1Submit')->setParams(['real_name' => 'ePay V1 页面跳转支付']);
Route::post('/mapi.php', [EpayV1Controller::class, 'mapi'])->name('epayV1Mapi')->setParams(['real_name' => 'ePay V1 接口支付']);
Route::any('/api.php', [EpayV1Controller::class, 'api'])->name('epayV1Api')->setParams(['real_name' => 'ePay V1 标准 API']);
})->middleware([Cors::class]);
// 开放支付ePay V2 标准接口
Route::group('/api', function () {
// 支付模块
// 支付订单
Route::group('/pay', function () {
// 文档约定是 POST同时兼容旧版 SDK `getPayLink()` 生成的 GET 请求。
Route::any('/submit', [EpayV2Controller::class, 'submit'])->name('epayV2PaySubmit')->setParams(['real_name' => 'ePay V2 页面跳转支付']);
@@ -52,16 +56,17 @@ Route::group('/api', function () {
Route::post('/refund', [EpayV2Controller::class, 'refund'])->name('epayV2PayRefund')->setParams(['real_name' => 'ePay V2 退款']);
Route::post('/refundquery', [EpayV2Controller::class, 'refundQuery'])->name('epayV2PayRefundQuery')->setParams(['real_name' => 'ePay V2 退款查询']);
Route::post('/close', [EpayV2Controller::class, 'close'])->name('epayV2PayClose')->setParams(['real_name' => 'ePay V2 关闭订单']);
Route::any('/{chanId:\d+}/notify', [EpayV2Controller::class, 'channelNotify'])->name('epayChannelNotify')->setParams(['real_name' => '支付通道通知']);
Route::any('/{payNo}/callback', [EpayV2Controller::class, 'callback'])->name('epayPayCallback')->setParams(['real_name' => '支付渠道回调']);
});
// 商户模块
// 商户查询
Route::group('/merchant', function () {
Route::post('/info', [EpayV2Controller::class, 'merchantInfo'])->name('epayV2MerchantInfo')->setParams(['real_name' => 'ePay V2 商户信息']);
Route::post('/orders', [EpayV2Controller::class, 'merchantOrders'])->name('epayV2MerchantOrders')->setParams(['real_name' => 'ePay V2 商户订单']);
});
// 转账模块
// 转账
Route::group('/transfer', function () {
Route::post('/submit', [EpayV2Controller::class, 'transferSubmit'])->name('epayV2TransferSubmit')->setParams(['real_name' => 'ePay V2 转账提交']);
Route::post('/query', [EpayV2Controller::class, 'transferQuery'])->name('epayV2TransferQuery')->setParams(['real_name' => 'ePay V2 转账查询']);

View File

@@ -2,56 +2,103 @@
use Webman\Route;
use app\common\middleware\Cors;
use app\http\mer\controller\system\AuthController;
use app\http\mer\controller\merchant\MerchantPortalController;
use app\http\mer\controller\trade\RefundOrderController;
use app\http\mer\controller\trade\PayOrderController;
use app\http\mer\controller\system\SystemController;
use app\http\mer\controller\file\FileRecordController;
use app\http\mer\controller\merchant\MerchantPortalController;
use app\http\mer\controller\system\AuthController;
use app\http\mer\controller\system\SystemController;
use app\http\mer\controller\trade\PayOrderController;
use app\http\mer\controller\trade\RefundOrderController;
use app\http\mer\middleware\MerchantAuthMiddleware;
Route::any('/mer[/{path:.+}]', function () {
return view('/public/mer/index');
});
$serveMerchantApp = static function () {
$indexPath = public_path('mer/index.html');
if (!is_file($indexPath)) {
return response('Merchant page not found', 404);
}
return response(file_get_contents($indexPath), 200, [
'Content-Type' => 'text/html; charset=utf-8',
]);
};
// 商户后台项目:页面路由
Route::any('/mer', $serveMerchantApp);
Route::any('/mer/', $serveMerchantApp);
Route::any('/mer/{path:.+}', $serveMerchantApp);
// 商户后台项目:接口路由
Route::group('/merapi', function () {
// 公开接口
Route::post('/login', [AuthController::class, 'login'])->name('merchantApiAuthLogin')->setParams(['real_name' => '商户登录']);
Route::get('/system/public-config', [SystemController::class, 'publicConfig'])->name('merchantApiSystemPublicConfig')->setParams(['real_name' => '商户后台公开配置']);
Route::group('', function () {
// 会话与当前账号
Route::post('/logout', [AuthController::class, 'logout'])->name('merchantApiAuthLogout')->setParams(['real_name' => '退出登录']);
Route::get('/user/profile', [AuthController::class, 'profile'])->name('merchantApiUserProfile')->setParams(['real_name' => '当前登录账号']);
Route::get('/merchant/profile', [MerchantPortalController::class, 'profile'])->name('merchantApiPortalProfile')->setParams(['real_name' => '商户资料']);
Route::put('/merchant/profile', [MerchantPortalController::class, 'updateProfile'])->name('merchantApiPortalProfileUpdate')->setParams(['real_name' => '更新商户资料']);
Route::post('/merchant/change-password', [MerchantPortalController::class, 'changePassword'])->name('merchantApiPortalChangePassword')->setParams(['real_name' => '修改登录密码']);
Route::get('/my-channels', [MerchantPortalController::class, 'myChannels'])->name('merchantApiPortalMyChannels')->setParams(['real_name' => '我的通道']);
Route::get('/my-channels/create-meta', [MerchantPortalController::class, 'channelCreateMeta'])->name('merchantApiPortalChannelCreateMeta')->setParams(['real_name' => '商户通道配置元数据']);
Route::post('/my-channels', [MerchantPortalController::class, 'createChannel'])->name('merchantApiPortalChannelCreate')->setParams(['real_name' => '新增商户通道']);
Route::put('/my-channels/{id}', [MerchantPortalController::class, 'updateChannel'])->name('merchantApiPortalChannelUpdate')->setParams(['real_name' => '修改商户通道']);
Route::delete('/my-channels/{id}', [MerchantPortalController::class, 'deleteChannel'])->name('merchantApiPortalChannelDelete')->setParams(['real_name' => '删除商户通道']);
Route::get('/plugin-configs', [MerchantPortalController::class, 'pluginConfigs'])->name('merchantApiPortalPluginConfigs')->setParams(['real_name' => '商户插件配置']);
Route::get('/plugin-configs/options', [MerchantPortalController::class, 'pluginConfigOptions'])->name('merchantApiPortalPluginConfigOptions')->setParams(['real_name' => '商户插件配置选项']);
Route::post('/plugin-configs', [MerchantPortalController::class, 'createPluginConfig'])->name('merchantApiPortalPluginConfigCreate')->setParams(['real_name' => '新增商户插件配置']);
Route::put('/plugin-configs/{id}', [MerchantPortalController::class, 'updatePluginConfig'])->name('merchantApiPortalPluginConfigUpdate')->setParams(['real_name' => '修改商户插件配置']);
Route::delete('/plugin-configs/{id}', [MerchantPortalController::class, 'deletePluginConfig'])->name('merchantApiPortalPluginConfigDelete')->setParams(['real_name' => '删除商户插件配置']);
// 商户资料
Route::group('/merchant', function () {
Route::get('/profile', [MerchantPortalController::class, 'profile'])->name('merchantApiPortalProfile')->setParams(['real_name' => '商户资料']);
Route::put('/profile', [MerchantPortalController::class, 'updateProfile'])->name('merchantApiPortalProfileUpdate')->setParams(['real_name' => '更新商户资料']);
Route::post('/change-password', [MerchantPortalController::class, 'changePassword'])->name('merchantApiPortalChangePassword')->setParams(['real_name' => '修改登录密码']);
});
// 通道与插件配置
Route::group('/my-channels', function () {
Route::get('', [MerchantPortalController::class, 'myChannels'])->name('merchantApiPortalMyChannels')->setParams(['real_name' => '我的通道']);
Route::get('/create-meta', [MerchantPortalController::class, 'channelCreateMeta'])->name('merchantApiPortalChannelCreateMeta')->setParams(['real_name' => '商户通道配置元数据']);
Route::post('', [MerchantPortalController::class, 'createChannel'])->name('merchantApiPortalChannelCreate')->setParams(['real_name' => '新增商户通道']);
Route::put('/{id}', [MerchantPortalController::class, 'updateChannel'])->name('merchantApiPortalChannelUpdate')->setParams(['real_name' => '修改商户通道']);
Route::delete('/{id}', [MerchantPortalController::class, 'deleteChannel'])->name('merchantApiPortalChannelDelete')->setParams(['real_name' => '删除商户通道']);
});
Route::group('/plugin-configs', function () {
Route::get('', [MerchantPortalController::class, 'pluginConfigs'])->name('merchantApiPortalPluginConfigs')->setParams(['real_name' => '商户插件配置']);
Route::get('/options', [MerchantPortalController::class, 'pluginConfigOptions'])->name('merchantApiPortalPluginConfigOptions')->setParams(['real_name' => '商户插件配置选项']);
Route::post('', [MerchantPortalController::class, 'createPluginConfig'])->name('merchantApiPortalPluginConfigCreate')->setParams(['real_name' => '新增商户插件配置']);
Route::put('/{id}', [MerchantPortalController::class, 'updatePluginConfig'])->name('merchantApiPortalPluginConfigUpdate')->setParams(['real_name' => '修改商户插件配置']);
Route::delete('/{id}', [MerchantPortalController::class, 'deletePluginConfig'])->name('merchantApiPortalPluginConfigDelete')->setParams(['real_name' => '删除商户插件配置']);
});
Route::get('/payment-plugins/{code}/schema', [MerchantPortalController::class, 'pluginSchema'])->name('merchantApiPortalPluginSchema')->setParams(['real_name' => '商户插件配置结构']);
Route::post('/file-asset/upload', [FileRecordController::class, 'upload'])->name('merchantApiFileRecordUpload')->setParams(['real_name' => '上传文件']);
Route::get('/file-asset/{id}/preview', [FileRecordController::class, 'preview'])->name('merchantApiFileRecordPreview')->setParams(['real_name' => '文件预览']);
Route::get('/file-asset/{id}/download', [FileRecordController::class, 'download'])->name('merchantApiFileRecordDownload')->setParams(['real_name' => '文件下载']);
Route::get('/route-preview', [MerchantPortalController::class, 'routePreview'])->name('merchantApiPortalRoutePreview')->setParams(['real_name' => '路由解析']);
Route::get('/api-credential', [MerchantPortalController::class, 'apiCredential'])->name('merchantApiPortalCredential')->setParams(['real_name' => '商户 API 凭证']);
Route::post('/api-credential/issue-credential', [MerchantPortalController::class, 'issueCredential'])->name('merchantApiPortalIssueCredential')->setParams(['real_name' => '生成或重置商户 API 凭证']);
Route::get('/settlement-records', [MerchantPortalController::class, 'settlementRecords'])->name('merchantApiPortalSettlementRecords')->setParams(['real_name' => '清算记录']);
Route::get('/settlement-records/{settleNo}', [MerchantPortalController::class, 'settlementRecordShow'])->name('merchantApiPortalSettlementRecordShow')->setParams(['real_name' => '清算记录详情']);
// 文件
Route::group('/file-asset', function () {
Route::post('/upload', [FileRecordController::class, 'upload'])->name('merchantApiFileRecordUpload')->setParams(['real_name' => '上传文件']);
Route::get('/{id}/preview', [FileRecordController::class, 'preview'])->name('merchantApiFileRecordPreview')->setParams(['real_name' => '文件预览']);
Route::get('/{id}/download', [FileRecordController::class, 'download'])->name('merchantApiFileRecordDownload')->setParams(['real_name' => '文件下载']);
});
// API 凭证
Route::group('/api-credential', function () {
Route::get('', [MerchantPortalController::class, 'apiCredential'])->name('merchantApiPortalCredential')->setParams(['real_name' => '商户 API 凭证']);
Route::post('/issue-credential', [MerchantPortalController::class, 'issueCredential'])->name('merchantApiPortalIssueCredential')->setParams(['real_name' => '生成或重置商户 API 凭证']);
});
// 资金与清算
Route::group('/settlement-records', function () {
Route::get('', [MerchantPortalController::class, 'settlementRecords'])->name('merchantApiPortalSettlementRecords')->setParams(['real_name' => '清算记录']);
Route::get('/{settleNo}', [MerchantPortalController::class, 'settlementRecordShow'])->name('merchantApiPortalSettlementRecordShow')->setParams(['real_name' => '清算记录详情']);
});
Route::get('/withdrawable-balance', [MerchantPortalController::class, 'withdrawableBalance'])->name('merchantApiPortalWithdrawableBalance')->setParams(['real_name' => '可提现余额']);
Route::get('/balance-flows', [MerchantPortalController::class, 'balanceFlows'])->name('merchantApiPortalBalanceFlows')->setParams(['real_name' => '资金流水']);
Route::get('/pay-orders', [PayOrderController::class, 'index'])->name('merchantApiPayOrdersIndex')->setParams(['real_name' => '支付订单']);
Route::get('/refund-orders', [RefundOrderController::class, 'index'])->name('merchantApiRefundOrdersIndex')->setParams(['real_name' => '退款订单']);
Route::get('/refund-orders/{refundNo}', [RefundOrderController::class, 'show'])->name('merchantApiRefundOrdersShow')->setParams(['real_name' => '退款订单详情']);
Route::post('/refund-orders/{refundNo}/retry', [RefundOrderController::class, 'retry'])
->name('merchantApiRefundOrdersRetry')
->setParams(['real_name' => '退款重试']);
Route::get('/system/menu-tree', [SystemController::class, 'menuTree'])->name('merchantApiMenuTree')->setParams(['real_name' => '菜单树']);
Route::get('/system/dict-items', [SystemController::class, 'dictItems'])->name('merchantApiDictItems')->setParams(['real_name' => '字典项']);
// 交易订单
Route::get('/pay-orders', [PayOrderController::class, 'index'])->name('merchantApiPayOrdersIndex')->setParams(['real_name' => '支付订单']);
Route::group('/refund-orders', function () {
Route::get('', [RefundOrderController::class, 'index'])->name('merchantApiRefundOrdersIndex')->setParams(['real_name' => '退款订单']);
Route::get('/{refundNo}', [RefundOrderController::class, 'show'])->name('merchantApiRefundOrdersShow')->setParams(['real_name' => '退款订单详情']);
Route::post('/{refundNo}/retry', [RefundOrderController::class, 'retry'])->name('merchantApiRefundOrdersRetry')->setParams(['real_name' => '退款重试']);
});
// 系统
Route::group('/system', function () {
Route::get('/menu-tree', [SystemController::class, 'menuTree'])->name('merchantApiMenuTree')->setParams(['real_name' => '菜单树']);
Route::get('/dict-items', [SystemController::class, 'dictItems'])->name('merchantApiDictItems')->setParams(['real_name' => '字典项']);
});
})->middleware([MerchantAuthMiddleware::class]);
})->middleware([Cors::class]);