更新统一使用 PHPDoc + PSR-19 标准注释

This commit is contained in:
技术老胡
2026-04-21 08:38:59 +08:00
parent dcd58e24ce
commit 9a16a88640
252 changed files with 9218 additions and 659 deletions

View File

@@ -28,13 +28,23 @@ use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use support\Request;
/**
* ePay mapi 兼容层烟雾测试命令。
*
* 用于验证真实商户、路由、插件配置和 mapi 调用是否连通,并输出落库后的订单快照。
*/
#[AsCommand('epay:mapi', '运行 ePay mapi 兼容接口烟雾测试')]
class EpayMapiTest extends Command
{
/**
* 配置命令参数。
*
* @return void
*/
protected function configure(): void
{
$this
->setDescription('自动读取真实商户、路由和插件配置,测试 ePay mapi 是否正常调用并返回结果。')
->setDescription('自动读取真实商户、路由和插件配置,测试 ePay mapi 是否正常调用并返回可用结果。')
->addOption('live', null, InputOption::VALUE_NONE, '使用真实数据库并发起实际 mapi 调用')
->addOption('merchant-id', null, InputOption::VALUE_OPTIONAL, '指定商户 ID')
->addOption('merchant-no', null, InputOption::VALUE_OPTIONAL, '指定商户号')
@@ -44,6 +54,13 @@ class EpayMapiTest extends Command
->addOption('out-trade-no', null, InputOption::VALUE_OPTIONAL, '商户订单号,默认自动生成');
}
/**
* 执行 ePay mapi 烟雾测试。
*
* @param InputInterface $input 命令输入
* @param OutputInterface $output 输出对象
* @return int 命令退出码
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$output->writeln('<info>epay mapi 烟雾测试</info>');
@@ -91,14 +108,15 @@ class EpayMapiTest extends Command
$this->writeRouteSnapshot($output, $route);
$payload = $this->buildPayload(
merchant: $merchant,
credential: $credential,
paymentType: $paymentType,
merchantOrderNo: $outTradeNo,
money: $money,
device: $device,
siteUrl: $siteUrl
$merchant,
$credential,
$paymentType,
$outTradeNo,
$money,
$device,
$siteUrl
);
/** @var EpayController $controller */
$controller = $this->resolve(EpayController::class);
$response = $controller->mapi($this->buildRequest($payload));
$responseData = $this->decodeResponse($response->rawBody());
@@ -115,6 +133,11 @@ class EpayMapiTest extends Command
}
}
/**
* 确保烟雾测试依赖可解析。
*
* @return void
*/
private function ensureDependencies(): void
{
$this->resolve(EpayController::class);
@@ -130,7 +153,13 @@ class EpayMapiTest extends Command
}
/**
* @return array{merchant:Merchant,credential:MerchantApiCredential,payment_type:PaymentType,route:array}
* 发现可用于测试的商户、凭证和路由上下文。
*
* @param int $merchantIdOption 商户 ID 选项
* @param string $merchantNoOption 商户编号选项
* @param string $typeCode 支付方式编码
* @return array 上下文数据
* @throws RuntimeException
*/
private function discoverContext(int $merchantIdOption, string $merchantNoOption, string $typeCode): array
{
@@ -144,7 +173,7 @@ class EpayMapiTest extends Command
$merchant = $this->pickMerchant($merchantIdOption, $merchantNoOption);
$credential = $this->findMerchantCredential((int) $merchant->id);
if (!$credential) {
throw new RuntimeException('商户未开通有效接口凭证: ' . $merchant->merchant_no);
throw new RuntimeException('商户未开通有效 API 凭证: ' . $merchant->merchant_no);
}
$route = $this->buildRouteSnapshot((int) $merchant->group_id, (int) $paymentType->id);
@@ -160,6 +189,14 @@ class EpayMapiTest extends Command
];
}
/**
* 挑选可用商户。
*
* @param int $merchantIdOption 商户 ID 选项
* @param string $merchantNoOption 商户编号选项
* @return Merchant 商户记录
* @throws RuntimeException
*/
private function pickMerchant(int $merchantIdOption, string $merchantNoOption): Merchant
{
/** @var MerchantRepository $merchantRepository */
@@ -195,6 +232,12 @@ class EpayMapiTest extends Command
return $merchant;
}
/**
* 查询商户凭证
*
* @param int $merchantId 商户ID
* @return MerchantApiCredential|null 商户 API 凭证
*/
private function findMerchantCredential(int $merchantId): ?MerchantApiCredential
{
/** @var MerchantApiCredentialRepository $repository */
@@ -208,7 +251,11 @@ class EpayMapiTest extends Command
}
/**
* @return array{bind:mixed,poll_group:PaymentPollGroup,candidates:array<int,array<string,mixed>>}|null
* 构建路由快照。
*
* @param int $merchantGroupId 商户分组ID
* @param int $payTypeId 支付类型ID
* @return array|null 路由快照
*/
private function buildRouteSnapshot(int $merchantGroupId, int $payTypeId): ?array
{
@@ -271,6 +318,18 @@ class EpayMapiTest extends Command
];
}
/**
* 构建 ePay mapi 请求载荷。
*
* @param Merchant $merchant 商户
* @param MerchantApiCredential $credential 商户 API 凭证
* @param PaymentType $paymentType 支付类型
* @param string $merchantOrderNo 商户订单号
* @param string $money 金额
* @param string $device 设备类型
* @param string $siteUrl 站点地址
* @return array 请求载荷
*/
private function buildPayload(
Merchant $merchant,
MerchantApiCredential $credential,
@@ -299,6 +358,13 @@ class EpayMapiTest extends Command
return $payload;
}
/**
* 根据响应和订单快照判定测试结果。
*
* @param array $responseData 响应数据
* @param array $orderSnapshot 订单快照
* @return string 判定结果
*/
private function classifyAttempt(array $responseData, array $orderSnapshot): string
{
$responseCode = (int) ($responseData['code'] ?? 0);
@@ -312,6 +378,13 @@ class EpayMapiTest extends Command
return ($payOrder && $bizOrder) ? 'pass' : 'fail';
}
/**
* 输出路由快照。
*
* @param OutputInterface $output 输出对象
* @param array $route 路由快照
* @return void
*/
private function writeRouteSnapshot(OutputInterface $output, array $route): void
{
/** @var PaymentPollGroup $pollGroup */
@@ -343,6 +416,15 @@ class EpayMapiTest extends Command
}
}
/**
* 输出测试结果。
*
* @param OutputInterface $output 输出对象
* @param array $payload 请求载荷
* @param array $responseData 响应数据
* @param array $orderSnapshot 订单快照
* @return void
*/
private function writeAttempt(OutputInterface $output, array $payload, array $responseData, array $orderSnapshot): void
{
$status = $this->classifyAttempt($responseData, $orderSnapshot);
@@ -418,6 +500,12 @@ class EpayMapiTest extends Command
}
}
/**
* 归纳支付参数快照。
*
* @param array $snapshot 支付参数快照
* @return array 归纳结果
*/
private function summarizePayParamsSnapshot(array $snapshot): array
{
if ($snapshot === []) {
@@ -458,21 +546,45 @@ class EpayMapiTest extends Command
return $summary;
}
/**
* 获取路由模式名称。
*
* @param int $routeMode 路由模式
* @return string 路由模式名称
*/
private function routeModeLabel(int $routeMode): string
{
return RouteConstant::routeModeMap()[$routeMode] ?? '未知';
}
/**
* 获取通道模式名称。
*
* @param int $channelMode 通道模式
* @return string 通道模式名称
*/
private function channelModeLabel(int $channelMode): string
{
return RouteConstant::channelModeMap()[$channelMode] ?? '未知';
}
/**
* 获取订单状态名称。
*
* @param int $status 状态
* @return string 订单状态名称
*/
private function orderStatusLabel(int $status): string
{
return TradeConstant::orderStatusMap()[$status] ?? '未知';
}
/**
* 生成商户订单号。
*
* @param string $base 基础订单号
* @return string 商户订单号
*/
private function buildMerchantOrderNo(string $base): string
{
$base = trim($base);
@@ -483,6 +595,13 @@ class EpayMapiTest extends Command
return 'EPAY-MAPI-' . FormatHelper::timestamp(time(), 'YmdHis') . random_int(1000, 9999);
}
/**
* 对载荷进行 MD5 签名。
*
* @param array $payload 请求载荷
* @param string $key 商户密钥
* @return string 签名结果
*/
private function signPayload(array $payload, string $key): string
{
$params = $payload;
@@ -502,6 +621,12 @@ class EpayMapiTest extends Command
return md5(implode('&', $query) . $key);
}
/**
* 构建模拟请求对象。
*
* @param array $payload 请求载荷
* @return Request 请求对象
*/
private function buildRequest(array $payload): Request
{
$body = http_build_query($payload, '', '&', PHP_QUERY_RFC1738);
@@ -523,6 +648,13 @@ class EpayMapiTest extends Command
return new Request($rawRequest);
}
/**
* 加载订单快照。
*
* @param int $merchantId 商户ID
* @param string $merchantOrderNo 商户订单号
* @return array 订单快照
*/
private function loadOrderSnapshot(int $merchantId, string $merchantOrderNo): array
{
/** @var BizOrderRepository $bizOrderRepository */
@@ -547,12 +679,24 @@ class EpayMapiTest extends Command
];
}
/**
* 解析站点地址。
*
* @return string 站点地址
*/
private function resolveSiteUrl(): string
{
$siteUrl = trim((string) sys_config('site_url'));
return $siteUrl !== '' ? rtrim($siteUrl, '/') : 'http://localhost:8787';
}
/**
* 归一化金额字符串。
*
* @param string $money 金额
* @return string 金额字符串
* @throws RuntimeException
*/
private function normalizeMoney(string $money): string
{
$money = trim($money);
@@ -567,18 +711,36 @@ class EpayMapiTest extends Command
return number_format((float) $money, 2, '.', '');
}
/**
* 归一化设备类型。
*
* @param string $device 设备类型
* @return string 设备类型
*/
private function normalizeDevice(string $device): string
{
$device = strtolower(trim($device));
return $device !== '' ? $device : 'pc';
}
/**
* 解析响应体。
*
* @param string $body 响应体
* @return array 解析结果
*/
private function decodeResponse(string $body): array
{
$decoded = json_decode($body, true);
return is_array($decoded) ? $decoded : ['raw' => $body];
}
/**
* 将值转为字符串。
*
* @param mixed $value 可转为字符串的值
* @return string 可展示字符串
*/
private function stringifyValue(mixed $value): string
{
if ($value === null) {
@@ -598,6 +760,13 @@ class EpayMapiTest extends Command
return (string) $value;
}
/**
* 限制字符串长度。
*
* @param string $value 待截断文本
* @param int $length 最大长度
* @return string 截断后的字符串
*/
private function limitString(string $value, int $length): string
{
$value = trim($value);
@@ -608,16 +777,34 @@ class EpayMapiTest extends Command
return strlen($value) <= $length ? $value : substr($value, 0, $length) . '...';
}
/**
* 归一化空白字符。
*
* @param string $value 待归一化文本
* @return string 归一化结果
*/
private function normalizeWhitespace(string $value): string
{
return preg_replace('/\s+/', ' ', trim($value)) ?: '';
}
/**
* 格式化 JSON。
*
* @param mixed $value 可编码为 JSON 的值
* @return string JSON 文本
*/
private function formatJson(mixed $value): string
{
return FormatHelper::json($value);
}
/**
* 格式化异常文本。
*
* @param Throwable $e 异常
* @return string 文本结果
*/
private function formatThrowable(\Throwable $e): string
{
$data = method_exists($e, 'getData') ? $e->getData() : [];
@@ -626,18 +813,42 @@ class EpayMapiTest extends Command
return $e::class . ': ' . $e->getMessage() . $suffix;
}
/**
* 读取字符串选项。
*
* @param InputInterface $input 命令输入
* @param string $name 选项名称
* @param string $default 默认值
* @return string 选项值
*/
private function optionString(InputInterface $input, string $name, string $default = ''): string
{
$value = $input->getOption($name);
return $value === null || $value === false ? $default : (is_string($value) ? $value : (string) $value);
}
/**
* 读取整数选项。
*
* @param InputInterface $input 命令输入
* @param string $name 选项名称
* @param int $default 默认值
* @return int 选项值
*/
private function optionInt(InputInterface $input, string $name, int $default = 0): int
{
$value = $input->getOption($name);
return is_numeric($value) ? (int) $value : $default;
}
/**
* 读取布尔选项。
*
* @param InputInterface $input 命令输入
* @param string $name 选项名称
* @param bool $default 默认值
* @return bool 布尔值
*/
private function optionBool(InputInterface $input, string $name, bool $default = false): bool
{
$value = $input->getOption($name);
@@ -650,6 +861,13 @@ class EpayMapiTest extends Command
return $filtered === null ? $default : $filtered;
}
/**
* 从容器中解析指定类实例。
*
* @param string $class 类名
* @return object 对象实例
* @throws RuntimeException
*/
private function resolve(string $class): object
{
try {

View File

@@ -18,9 +18,19 @@ use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
/**
* MpayTest 烟雾测试命令。
*
* 用于验证支付、退款、清结算、余额和追踪链路的核心依赖与关键流程。
*/
#[AsCommand('mpay:test', '运行支付、退款、清结算、余额和追踪烟雾测试')]
class MpayTest extends Command
{
/**
* 配置命令参数。
*
* @return void
*/
protected function configure(): void
{
$this
@@ -34,6 +44,13 @@ class MpayTest extends Command
->addOption('live', null, InputOption::VALUE_NONE, '在提供测试数据时运行真实数据库检查');
}
/**
* 运行选定链路的烟雾测试。
*
* @param InputInterface $input 命令输入
* @param OutputInterface $output 命令输出
* @return int 命令退出码
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$cases = $this->resolveCases($input);
@@ -73,7 +90,10 @@ class MpayTest extends Command
}
/**
* 根据命令行选项解析需要执行的测试项
* 根据命令行选项解析本次需要检查的链路
*
* @param InputInterface $input 命令输入
* @return array 测试项列表
*/
private function resolveCases(InputInterface $input): array
{
@@ -92,7 +112,10 @@ class MpayTest extends Command
}
/**
* 检查支付链路
* 校验支付下单与后续状态流转
*
* @param bool $live 是否使用真实数据
* @return array 检查结果
*/
private function checkPayment(bool $live): array
{
@@ -155,7 +178,10 @@ class MpayTest extends Command
}
/**
* 检查退款链路
* 校验退款创建与后续状态流转
*
* @param bool $live 是否使用真实数据
* @return array 检查结果
*/
private function checkRefund(bool $live): array
{
@@ -214,7 +240,10 @@ class MpayTest extends Command
}
/**
* 检查清结算链路
* 校验清结算单创建与入账结果
*
* @param bool $live 是否使用真实数据
* @return array 检查结果
*/
private function checkSettlement(bool $live): array
{
@@ -316,7 +345,10 @@ class MpayTest extends Command
}
/**
* 检查余额链路
* 校验商户余额快照查询
*
* @param bool $live 是否使用真实数据
* @return array 检查结果
*/
private function checkBalance(bool $live): array
{
@@ -360,7 +392,10 @@ class MpayTest extends Command
}
/**
* 检查统一追踪链路
* 校验追踪查询聚合结果
*
* @param bool $live 是否使用真实数据
* @return array 检查结果
*/
private function checkTrace(bool $live): array
{
@@ -399,6 +434,10 @@ class MpayTest extends Command
/**
* 从容器中解析指定类实例。
*
* @param string $class 类名
* @return object 对象实例
* @throws RuntimeException
*/
private function resolve(string $class): object
{
@@ -417,6 +456,11 @@ class MpayTest extends Command
/**
* 检查实例是否包含指定方法。
*
* @param object $instance 实例
* @param string $method 方法名
* @return void
* @throws RuntimeException
*/
private function ensureMethod(object $instance, string $method): void
{
@@ -427,6 +471,10 @@ class MpayTest extends Command
/**
* 读取字符串环境变量。
*
* @param string $key 环境变量名
* @param string $default 默认值
* @return string 字符串值
*/
private function envString(string $key, string $default = ''): string
{
@@ -437,6 +485,10 @@ class MpayTest extends Command
/**
* 读取整数环境变量。
*
* @param string $key 环境变量名
* @param int $default 默认值
* @return int 整数值
*/
private function envInt(string $key, int $default = 0): int
{
@@ -447,6 +499,10 @@ class MpayTest extends Command
/**
* 读取布尔环境变量。
*
* @param string $key 环境变量名
* @param bool $default 默认值
* @return bool 布尔值
*/
private function envBool(string $key, bool $default = false): bool
{
@@ -462,6 +518,10 @@ class MpayTest extends Command
/**
* 读取结构化环境变量。
*
* @param string $key 环境变量名
* @param array $default 默认值
* @return array 结构化数据
*/
private function envJson(string $key, array $default = []): array
{
@@ -476,6 +536,9 @@ class MpayTest extends Command
/**
* 生成测试编号。
*
* @param string $prefix 前缀
* @return string 测试编号
*/
private function generateTestNo(string $prefix): string
{
@@ -484,6 +547,9 @@ class MpayTest extends Command
/**
* 将异常格式化为可读文本。
*
* @param Throwable $e 异常
* @return string 文本结果
*/
private function formatThrowable(\Throwable $e): string
{
@@ -494,7 +560,13 @@ class MpayTest extends Command
}
/**
* 输出单个测试项的执行结果。
* 输出单个链路的检查结果。
*
* @param OutputInterface $output 输出对象
* @param string $case 测试项
* @param string $status 状态
* @param string $message 消息
* @return void
*/
private function writeResult(OutputInterface $output, string $case, string $status, string $message): void
{
@@ -508,3 +580,9 @@ class MpayTest extends Command
}
}

View File

@@ -11,14 +11,31 @@ use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* 系统配置同步命令。
*
* 将系统配置定义中的默认值同步到数据库,并刷新运行时配置缓存。
*/
#[AsCommand('system:config-sync', '同步系统配置默认值到数据库')]
class SystemConfigSync extends Command
{
/**
* 配置命令说明。
*
* @return void
*/
protected function configure(): void
{
$this->setDescription('同步 config/system_config.php 中定义的系统配置默认值到数据库。');
}
/**
* 将系统配置定义同步到数据库并刷新运行时缓存。
*
* @param InputInterface $input 命令输入
* @param OutputInterface $output 命令输出
* @return int 命令退出码
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
try {
@@ -68,3 +85,6 @@ class SystemConfigSync extends Command
}
}
}

View File

@@ -7,16 +7,35 @@ use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* 基础测试命令。
*
* 用于快速验证命令注册和控制台输出是否正常。
*/
#[AsCommand('test', 'test')]
class Test extends Command
{
/**
* 配置命令说明。
*
* @return void
*/
protected function configure(): void
{
}
/**
* 输出命令名以验证命令注册正常。
*
* @param InputInterface $input 命令输入
* @param OutputInterface $output 命令输出
* @return int 命令退出码
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$output->writeln('<info>Hello</info> <comment>' . $this->getName() . '</comment>');
return self::SUCCESS;
}
}

View File

@@ -16,6 +16,11 @@ class BaseController
{
/**
* 返回成功响应。
*
* @param mixed $data 响应数据
* @param string $message 响应消息
* @param int $code 响应码
* @return Response 响应对象
*/
protected function success(mixed $data = null, string $message = '操作成功', int $code = 200): Response
{
@@ -28,6 +33,11 @@ class BaseController
/**
* 返回失败响应。
*
* @param string $message 响应消息
* @param int $code 响应码
* @param mixed $data 响应数据
* @return Response 响应对象
*/
protected function fail(string $message = '操作失败', int $code = 500, mixed $data = null): Response
{
@@ -40,6 +50,9 @@ class BaseController
/**
* 返回统一分页响应。
*
* @param mixed $paginator 分页器实例
* @return Response 响应对象
*/
protected function page(mixed $paginator): Response
{
@@ -63,7 +76,10 @@ class BaseController
/**
* 通过校验器类验证请求数据。
*
* @param class-string $validatorClass
* @param array $data 请求数据
* @param string $validatorClass 校验器类
* @param string|null $scene 校验场景
* @return array 校验后的数据
*/
protected function validated(array $data, string $validatorClass, ?string $scene = null): array
{
@@ -80,6 +96,9 @@ class BaseController
/**
* 获取中间件预处理后的标准化参数。
*
* @param Request $request 请求对象
* @return array 标准化参数
*/
protected function payload(Request $request): array
{
@@ -95,6 +114,11 @@ class BaseController
/**
* 读取请求属性。
*
* @param Request $request 请求对象
* @param string $key 属性名
* @param mixed $default 默认值
* @return mixed 请求上下文值
*/
protected function requestAttribute(Request $request, string $key, mixed $default = null): mixed
{
@@ -103,6 +127,9 @@ class BaseController
/**
* 获取中间件注入的当前管理员 ID。
*
* @param Request $request 请求对象
* @return int 当前管理员ID
*/
protected function currentAdminId(Request $request): int
{
@@ -111,6 +138,9 @@ class BaseController
/**
* 获取中间件注入的当前商户 ID。
*
* @param Request $request 请求对象
* @return int 当前商户ID
*/
protected function currentMerchantId(Request $request): int
{
@@ -119,6 +149,9 @@ class BaseController
/**
* 获取中间件注入的当前商户编号。
*
* @param Request $request 请求对象
* @return string 当前商户编号
*/
protected function currentMerchantNo(Request $request): string
{
@@ -126,3 +159,8 @@ class BaseController
}
}

View File

@@ -43,9 +43,13 @@ class BaseModel extends Model
*
* 避免前端收到 ISO8601如 2026-04-02T01:50:40.000000Z)这类不直观的时间串,
* 统一改为后台常用的本地展示格式。
*
* @param DateTimeInterface $date 时间对象
* @return string 格式化后的日期时间
*/
protected function serializeDate(DateTimeInterface $date): string
{
return FormatHelper::dateTime($date);
}
}

View File

@@ -14,7 +14,7 @@ use support\Log;
/**
* 支付插件基类(建议所有插件继承)
*
* 目标:把“插件共性”集中在这里,具体渠道差异留给子类实现 `PaymentInterface`
* 目标:把“插件共性”集中在这里,具体渠道差异留给子类补齐支付动作能力
*
* 生命周期:
* - 服务层会在每次动作前调用 `init($channelConfig)` 注入该通道配置。
@@ -48,15 +48,19 @@ abstract class BasePayment implements PayPluginInterface
*/
protected array $channelConfig = [];
/** HTTP 请求客户端GuzzleHttp */
/**
* HTTP 请求客户端GuzzleHttp
*
* @var Client|null
*/
private ?Client $httpClient = null;
// ==================== 初始化 ====================
/**
* 初始化插件,加载通道配置并创建 HTTP 客户端
* 初始化插件,加载通道配置并创建 HTTP 客户端
*
* @param array<string, mixed> $channelConfig 道配置(商户号、密钥等)
* @param array $channelConfig 道配置
* @return void
*/
public function init(array $channelConfig): void
@@ -71,11 +75,11 @@ abstract class BasePayment implements PayPluginInterface
}
/**
* 获取通道配置项
* 获取通道配置项
*
* @param string $key 配置键
* @param mixed $default 默认值(键不存在时返回)
* @return mixed
* @param string $key 配置键
* @param mixed $default 默认值
* @return mixed 通道配置值
*/
protected function getConfig(string $key, mixed $default = null): mixed
{
@@ -84,31 +88,51 @@ abstract class BasePayment implements PayPluginInterface
// ==================== 插件元信息 ====================
/** 获取插件代码(唯一标识) */
/**
* 获取插件代码(唯一标识)。
*
* @return string 插件代码
*/
public function getCode(): string
{
return $this->paymentInfo['code'] ?? '';
}
/** 获取插件名称 */
/**
* 获取插件名称。
*
* @return string 插件名称
*/
public function getName(): string
{
return $this->paymentInfo['name'] ?? '';
}
/** 获取作者名称 */
/**
* 获取作者名称。
*
* @return string 作者名称
*/
public function getAuthorName(): string
{
return $this->paymentInfo['author'] ?? '';
}
/** 获取作者链接 */
/**
* 获取作者链接。
*
* @return string 作者链接
*/
public function getAuthorLink(): string
{
return $this->paymentInfo['link'] ?? '';
}
/** 获取版本号 */
/**
* 获取版本号。
*
* @return string 版本号
*/
public function getVersion(): string
{
return $this->paymentInfo['version'] ?? '';
@@ -117,9 +141,9 @@ abstract class BasePayment implements PayPluginInterface
// ==================== 能力声明 ====================
/**
* 获取插件支持的支付方式列表
* 获取插件支持的支付方式列表
*
* @return array<string> 支付方式代码数组,如 ['alipay', 'wechat']
* @return array 支持的支付方式编码
*/
public function getEnabledPayTypes(): array
{
@@ -127,9 +151,9 @@ abstract class BasePayment implements PayPluginInterface
}
/**
* 获取插件支持的转账方式列表
* 获取插件支持的转账方式列表
*
* @return array<string> 转账方式代码数组
* @return array 支持的转账方式编码
*/
public function getEnabledTransferTypes(): array
{
@@ -137,9 +161,9 @@ abstract class BasePayment implements PayPluginInterface
}
/**
* 获取插件配置表单结构(用于后台配置界面)
* 获取插件配置表单结构(用于后台配置界面)
*
* @return array<string, mixed> 表单字段定义数组
* @return array 配置表单结构
*/
public function getConfigSchema(): array
{
@@ -149,13 +173,13 @@ abstract class BasePayment implements PayPluginInterface
// ==================== HTTP 请求 ====================
/**
* 统一 HTTP 请求(对外调用支付渠道 API
* 统一 HTTP 请求(对外调用支付渠道 API
*
* @param string $method 请求方法GET/POST/PUT/DELETE 等)
* @param string $url 请求地址
* @param array<string, mixed> $options Guzzle 请求选项headers、json、form_params 等)
* @return ResponseInterface
* @throws PaymentException 未调用 init() 或渠道请求失败时
* @param string $method 请求方法
* @param string $url 请求地址
* @param array $options 请求选项
* @return ResponseInterface 响应对象
* @throws PaymentException
*/
protected function request(string $method, string $url, array $options = []): ResponseInterface
{
@@ -171,3 +195,8 @@ abstract class BasePayment implements PayPluginInterface
}
}
}

View File

@@ -15,11 +15,16 @@ abstract class BaseRepository
{
/**
* 当前仓储绑定的模型实例。
*
* @var Model
*/
protected Model $model;
/**
* 构造函数,绑定模型实例
* 构造方法
*
* @param Model $model 模型实例
* @return void
*/
public function __construct(Model $model)
{
@@ -28,6 +33,8 @@ abstract class BaseRepository
/**
* 获取查询构造器。
*
* @return \Illuminate\Database\Eloquent\Builder 查询构造器
*/
public function query()
{
@@ -36,6 +43,10 @@ abstract class BaseRepository
/**
* 按主键查询记录。
*
* @param int|string $id 主键
* @param array $columns 字段列表
* @return Model|null 记录或空
*/
public function find(int|string $id, array $columns = ['*']): ?Model
{
@@ -44,6 +55,9 @@ abstract class BaseRepository
/**
* 新增记录。
*
* @param array $data 新增数据
* @return Model 新增后的模型
*/
public function create(array $data): Model
{
@@ -52,6 +66,10 @@ abstract class BaseRepository
/**
* 按主键更新记录。
*
* @param int|string $id 主键
* @param array $data 更新数据
* @return bool 是否更新成功
*/
public function updateById(int|string $id, array $data): bool
{
@@ -60,6 +78,10 @@ abstract class BaseRepository
/**
* 按唯一键更新记录。
*
* @param int|string $key 键值
* @param array $data 更新数据
* @return bool 是否更新成功
*/
public function updateByKey(int|string $key, array $data): bool
{
@@ -68,6 +90,10 @@ abstract class BaseRepository
/**
* 按条件批量更新记录。
*
* @param array $where 条件
* @param array $data 更新数据
* @return int 受影响行数
*/
public function updateWhere(array $where, array $data): int
{
@@ -82,6 +108,9 @@ abstract class BaseRepository
/**
* 按主键删除记录。
*
* @param int|string $id 主键
* @return bool 是否删除成功
*/
public function deleteById(int|string $id): bool
{
@@ -90,6 +119,9 @@ abstract class BaseRepository
/**
* 按条件批量删除记录。
*
* @param array $where 条件
* @return int 受影响行数
*/
public function deleteWhere(array $where): int
{
@@ -104,6 +136,10 @@ abstract class BaseRepository
/**
* 按条件获取首条记录。
*
* @param array $where 条件
* @param array $columns 字段列表
* @return Model|null 记录或空
*/
public function firstBy(array $where = [], array $columns = ['*']): ?Model
{
@@ -118,6 +154,10 @@ abstract class BaseRepository
/**
* 先查后更,不存在则创建。
*
* @param array $where 条件
* @param array $data 更新数据
* @return Model 记录
*/
public function updateOrCreate(array $where, array $data = []): Model
{
@@ -156,6 +196,9 @@ abstract class BaseRepository
/**
* 按条件统计数量。
*
* @param array $where 条件
* @return int 数量
*/
public function countBy(array $where = []): int
{
@@ -170,6 +213,9 @@ abstract class BaseRepository
/**
* 判断条件下是否存在记录。
*
* @param array $where 条件
* @return bool 是否存在
*/
public function existsBy(array $where = []): bool
{
@@ -185,7 +231,11 @@ abstract class BaseRepository
/**
* 分页查询。
*
* @param array $where 条件数组,空值会被忽略
* @param array $where 条件
* @param int $page 页码
* @param int $pageSize 每页条数
* @param array $columns 字段列表
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator 分页结果
*/
public function paginate(array $where = [], int $page = 1, int $pageSize = 10, array $columns = ['*'])
{
@@ -198,3 +248,8 @@ abstract class BaseRepository
return $query->paginate($pageSize, $columns, 'page', $page);
}
}

View File

@@ -18,6 +18,9 @@ class BaseService
*
* 适用于 biz_no / pay_no / refund_no / settle_no / notify_no / ledger_no 等场景。
* 默认使用时间前缀 + 随机数,保证可读性和基本唯一性。
*
* @param string $prefix 单号前缀
* @return string 单号
*/
protected function generateNo(string $prefix = ''): string
{
@@ -31,6 +34,8 @@ class BaseService
* 获取当前时间字符串。
*
* 统一返回 `Y-m-d H:i:s` 格式,便于数据库写入和日志输出。
*
* @return string 时间字符串
*/
protected function now(): string
{
@@ -39,6 +44,9 @@ class BaseService
/**
* 金额格式化,单位为元。
*
* @param int $amount 金额(分)
* @return string 格式化后的金额
*/
protected function formatAmount(int $amount): string
{
@@ -47,6 +55,9 @@ class BaseService
/**
* 金额格式化0 时显示不限。
*
* @param int $amount 金额(分)
* @return string 格式化后的金额
*/
protected function formatAmountOrUnlimited(int $amount): string
{
@@ -55,6 +66,9 @@ class BaseService
/**
* 次数格式化0 时显示不限。
*
* @param int $count 次数
* @return string 格式化后的次数
*/
protected function formatCountOrUnlimited(int $count): string
{
@@ -63,6 +77,9 @@ class BaseService
/**
* 费率格式化,单位为百分点。
*
* @param int $basisPoints 基点值
* @return string 格式化后的费率
*/
protected function formatRate(int $basisPoints): string
{
@@ -71,6 +88,9 @@ class BaseService
/**
* 延迟格式化。
*
* @param int $latencyMs 延迟毫秒数
* @return string 格式化后的延迟
*/
protected function formatLatency(int $latencyMs): string
{
@@ -79,6 +99,10 @@ class BaseService
/**
* 日期格式化。
*
* @param mixed $value 日期时间值
* @param string $emptyText 为空时显示文案
* @return string 格式化后的日期
*/
protected function formatDate(mixed $value, string $emptyText = ''): string
{
@@ -87,6 +111,10 @@ class BaseService
/**
* 日期时间格式化。
*
* @param mixed $value 日期时间值
* @param string $emptyText 为空时显示文案
* @return string 格式化后的日期时间
*/
protected function formatDateTime(mixed $value, string $emptyText = ''): string
{
@@ -95,6 +123,10 @@ class BaseService
/**
* JSON 文本格式化。
*
* @param mixed $value JSON 值
* @param string $emptyText 为空时显示文案
* @return string 格式化后的 JSON 文本
*/
protected function formatJson(mixed $value, string $emptyText = ''): string
{
@@ -103,6 +135,11 @@ class BaseService
/**
* 映射表文本转换。
*
* @param int $value 待映射值
* @param array $map 映射表
* @param string $default 默认值
* @return string 映射后的文本
*/
protected function textFromMap(int $value, array $map, string $default = '未知'): string
{
@@ -111,6 +148,10 @@ class BaseService
/**
* 接口凭证明文脱敏。
*
* @param string $credentialValue 凭证原文
* @param bool $maskShortValue 是否对短值也进行脱敏
* @return string 脱敏后的文本
*/
protected function maskCredentialValue(string $credentialValue, bool $maskShortValue = true): string
{
@@ -119,6 +160,9 @@ class BaseService
/**
* 将模型或对象归一化成数组。
*
* @param mixed $value 模型实例、数组或可序列化对象
* @return array|null 归一化结果
*/
protected function normalizeModel(mixed $value): ?array
{
@@ -130,8 +174,8 @@ class BaseService
*
* 适合单次数据库事务,不包含自动重试逻辑。
*
* @param callable $callback 事务体
* @return mixed
* @param callable $callback 回调
* @return mixed 回调原始返回值
*/
protected function transaction(callable $callback)
{
@@ -144,6 +188,11 @@ class BaseService
* 支持重试的事务封装。
*
* 适合余额冻结、扣减、状态推进和幂等写入等容易发生锁冲突的场景。
*
* @param callable $callback 回调
* @param int $attempts 重试次数
* @param int $sleepMs 重试间隔毫秒数
* @return mixed 回调原始返回值
*/
protected function transactionRetry(callable $callback, int $attempts = 3, int $sleepMs = 50)
{

View File

@@ -9,19 +9,51 @@ namespace app\common\constant;
*/
final class AuthConstant
{
/**
* 管理员登录域。
*/
public const GUARD_ADMIN = 1;
/**
* 商户登录域。
*/
public const GUARD_MERCHANT = 2;
/**
* JWT 签名算法。
*/
public const JWT_ALG_HS256 = 'HS256';
/**
* 令牌禁用状态。
*/
public const TOKEN_STATUS_DISABLED = 0;
/**
* 令牌启用状态。
*/
public const TOKEN_STATUS_ENABLED = 1;
/**
* 登录禁用状态。
*/
public const LOGIN_STATUS_DISABLED = 0;
/**
* 登录启用状态。
*/
public const LOGIN_STATUS_ENABLED = 1;
/**
* API 签名类型MD5。
*/
public const API_SIGN_TYPE_MD5 = 0;
/**
* 获取签名类型映射。
*
* @return array<int, string> 签名类型名称表
*/
public static function signTypeMap(): array
{
return [
@@ -29,6 +61,11 @@ final class AuthConstant
];
}
/**
* 获取登录域映射。
*
* @return array<int, string> 登录域名称表
*/
public static function guardMap(): array
{
return [
@@ -37,3 +74,7 @@ final class AuthConstant
];
}
}

View File

@@ -3,16 +3,35 @@
namespace app\common\constant;
/**
* 通用状态常量
* 通用状态枚举
*/
final class CommonConstant
{
/**
* 禁用状态。
*/
public const STATUS_DISABLED = 0;
/**
* 启用状态。
*/
public const STATUS_ENABLED = 1;
/**
* 否。
*/
public const NO = 0;
/**
* 是。
*/
public const YES = 1;
/**
* 获取状态名称映射。
*
* @return array<int, string> 状态名称表
*/
public static function statusMap(): array
{
return [
@@ -21,6 +40,11 @@ final class CommonConstant
];
}
/**
* 获取是否名称映射。
*
* @return array<int, string> 是否名称表
*/
public static function yesNoMap(): array
{
return [
@@ -29,3 +53,7 @@ final class CommonConstant
];
}
}

View File

@@ -4,23 +4,69 @@ namespace app\common\constant;
/**
* 文件相关常量。
*
* 用于描述文件来源、可见性、场景、存储引擎和文件类型白名单。
*/
final class FileConstant
{
/**
* 上传来源。
*/
public const SOURCE_UPLOAD = 1;
/**
* 远程 URL 导入来源。
*/
public const SOURCE_REMOTE_URL = 2;
/**
* 公开可访问文件。
*/
public const VISIBILITY_PUBLIC = 1;
/**
* 私有文件。
*/
public const VISIBILITY_PRIVATE = 2;
/**
* 图片场景。
*/
public const SCENE_IMAGE = 1;
/**
* 证书场景。
*/
public const SCENE_CERTIFICATE = 2;
/**
* 文本场景。
*/
public const SCENE_TEXT = 3;
/**
* 其他场景。
*/
public const SCENE_OTHER = 4;
/**
* 本地存储引擎。
*/
public const STORAGE_LOCAL = 1;
/**
* 阿里云 OSS 存储引擎。
*/
public const STORAGE_ALIYUN_OSS = 2;
/**
* 腾讯云 COS 存储引擎。
*/
public const STORAGE_TENCENT_COS = 3;
/**
* 远程引用存储引擎。
*/
public const STORAGE_REMOTE_URL = 4;
public const CONFIG_DEFAULT_ENGINE = 'file_storage_default_engine';
@@ -42,6 +88,11 @@ final class FileConstant
public const CONFIG_COS_SECRET_KEY = 'file_storage_tencent_cos_secret_key';
public const CONFIG_COS_PUBLIC_DOMAIN = 'file_storage_tencent_cos_public_domain';
/**
* 获取文件来源映射。
*
* @return array<int, string> 来源名称表
*/
public static function sourceTypeMap(): array
{
return [
@@ -50,6 +101,11 @@ final class FileConstant
];
}
/**
* 获取文件可见性映射。
*
* @return array<int, string> 可见性名称表
*/
public static function visibilityMap(): array
{
return [
@@ -58,6 +114,11 @@ final class FileConstant
];
}
/**
* 获取文件场景映射。
*
* @return array<int, string> 场景名称表
*/
public static function sceneMap(): array
{
return [
@@ -68,6 +129,11 @@ final class FileConstant
];
}
/**
* 获取存储引擎映射。
*
* @return array<int, string> 存储引擎名称表
*/
public static function storageEngineMap(): array
{
return [
@@ -78,6 +144,11 @@ final class FileConstant
];
}
/**
* 获取可选存储引擎映射。
*
* @return array<int, string> 可选存储引擎名称表
*/
public static function selectableStorageEngineMap(): array
{
return [
@@ -87,6 +158,11 @@ final class FileConstant
];
}
/**
* 获取图片扩展名白名单。
*
* @return array<string, bool> 白名单集合
*/
public static function imageExtensionMap(): array
{
return [
@@ -100,6 +176,11 @@ final class FileConstant
];
}
/**
* 获取证书扩展名白名单。
*
* @return array<string, bool> 白名单集合
*/
public static function certificateExtensionMap(): array
{
return [
@@ -112,6 +193,11 @@ final class FileConstant
];
}
/**
* 获取文本扩展名白名单。
*
* @return array<string, bool> 白名单集合
*/
public static function textExtensionMap(): array
{
return [
@@ -128,8 +214,17 @@ final class FileConstant
];
}
/**
* 获取默认允许上传的扩展名。
*
* @return array<int, string> 扩展名列表
*/
public static function defaultAllowedExtensions(): array
{
return array_keys(self::imageExtensionMap() + self::certificateExtensionMap() + self::textExtensionMap());
}
}

View File

@@ -3,7 +3,7 @@
namespace app\common\constant;
/**
* 账户流水相关枚举。
* 账户流水枚举。
*/
final class LedgerConstant
{
@@ -22,6 +22,11 @@ final class LedgerConstant
public const DIRECTION_IN = 0;
public const DIRECTION_OUT = 1;
/**
* 获取业务类型映射。
*
* @return array<int, string> 业务类型名称表
*/
public static function bizTypeMap(): array
{
return [
@@ -34,6 +39,11 @@ final class LedgerConstant
];
}
/**
* 获取事件类型映射。
*
* @return array<int, string> 事件类型名称表
*/
public static function eventTypeMap(): array
{
return [
@@ -44,6 +54,11 @@ final class LedgerConstant
];
}
/**
* 获取流水方向映射。
*
* @return array<int, string> 方向名称表
*/
public static function directionMap(): array
{
return [
@@ -52,3 +67,7 @@ final class LedgerConstant
];
}
}

View File

@@ -7,14 +7,41 @@ namespace app\common\constant;
*/
final class MerchantConstant
{
/**
* 个人商户类型。
*/
public const TYPE_PERSON = 0;
/**
* 企业商户类型。
*/
public const TYPE_COMPANY = 1;
/**
* 其他商户类型。
*/
public const TYPE_OTHER = 2;
/**
* 低风险等级。
*/
public const RISK_LOW = 0;
/**
* 中风险等级。
*/
public const RISK_MEDIUM = 1;
/**
* 高风险等级。
*/
public const RISK_HIGH = 2;
/**
* 获取商户类型映射。
*
* @return array<int, string> 商户类型名称表
*/
public static function typeMap(): array
{
return [
@@ -24,6 +51,11 @@ final class MerchantConstant
];
}
/**
* 获取商户风险等级映射。
*
* @return array<int, string> 风险等级名称表
*/
public static function riskLevelMap(): array
{
return [
@@ -33,3 +65,7 @@ final class MerchantConstant
];
}
}

View File

@@ -3,7 +3,7 @@
namespace app\common\constant;
/**
* 通知与回调相关枚举。
* 通知与回调枚举。
*/
final class NotifyConstant
{
@@ -25,6 +25,11 @@ final class NotifyConstant
public const TASK_STATUS_SUCCESS = 1;
public const TASK_STATUS_FAILED = 2;
/**
* 获取通知类型映射。
*
* @return array<int, string> 通知类型名称表
*/
public static function notifyTypeMap(): array
{
return [
@@ -33,6 +38,11 @@ final class NotifyConstant
];
}
/**
* 获取回调类型映射。
*
* @return array<int, string> 回调类型名称表
*/
public static function callbackTypeMap(): array
{
return [
@@ -41,6 +51,11 @@ final class NotifyConstant
];
}
/**
* 验证状态Map
*
* @return array<int, string> 验证状态名称表
*/
public static function verifyStatusMap(): array
{
return [
@@ -50,6 +65,11 @@ final class NotifyConstant
];
}
/**
* 处理状态Map
*
* @return array<int, string> 处理状态名称表
*/
public static function processStatusMap(): array
{
return [
@@ -59,6 +79,11 @@ final class NotifyConstant
];
}
/**
* 获取任务状态映射。
*
* @return array<int, string> 任务状态名称表
*/
public static function taskStatusMap(): array
{
return [
@@ -68,3 +93,7 @@ final class NotifyConstant
];
}
}

View File

@@ -3,14 +3,30 @@
namespace app\common\constant;
/**
* 路由与通道编排相关枚举。
* 路由与通道编排枚举。
*
* 用于描述通道类型、通道模式以及轮询组的路由策略。
*/
final class RouteConstant
{
/**
* 平台代收通道类型。
*/
public const CHANNEL_TYPE_PLATFORM_COLLECT = 0;
/**
* 商户自有通道类型。
*/
public const CHANNEL_TYPE_MERCHANT_SELF = 1;
/**
* 代收通道模式。
*/
public const CHANNEL_MODE_COLLECT = 0;
/**
* 自收通道模式。
*/
public const CHANNEL_MODE_SELF = 1;
/**
@@ -28,6 +44,11 @@ final class RouteConstant
*/
public const ROUTE_MODE_FIRST_AVAILABLE = 2;
/**
* 获取通道类型名称映射。
*
* @return array<int, string> 通道类型名称表
*/
public static function channelTypeMap(): array
{
return [
@@ -36,6 +57,11 @@ final class RouteConstant
];
}
/**
* 获取通道模式名称映射。
*
* @return array<int, string> 通道模式名称表
*/
public static function channelModeMap(): array
{
return [
@@ -44,6 +70,11 @@ final class RouteConstant
];
}
/**
* 获取路由模式名称映射。
*
* @return array<int, string> 路由模式名称表
*/
public static function routeModeMap(): array
{
return [
@@ -53,3 +84,7 @@ final class RouteConstant
];
}
}

View File

@@ -3,7 +3,7 @@
namespace app\common\constant;
/**
* 交易、订单与结算相关枚举。
* 交易、订单与结算状态枚举。
*/
final class TradeConstant
{
@@ -36,6 +36,11 @@ final class TradeConstant
public const REFUND_STATUS_FAILED = 3;
public const REFUND_STATUS_CLOSED = 4;
/**
* 获取清算周期映射。
*
* @return array<int, string> 清算周期名称表
*/
public static function settlementCycleMap(): array
{
return [
@@ -47,6 +52,11 @@ final class TradeConstant
];
}
/**
* 获取订单状态映射。
*
* @return array<int, string> 订单状态名称表
*/
public static function orderStatusMap(): array
{
return [
@@ -59,6 +69,11 @@ final class TradeConstant
];
}
/**
* 获取手续费状态映射。
*
* @return array<int, string> 手续费状态名称表
*/
public static function feeStatusMap(): array
{
return [
@@ -69,6 +84,11 @@ final class TradeConstant
];
}
/**
* 获取清算状态映射。
*
* @return array<int, string> 清算状态名称表
*/
public static function settlementStatusMap(): array
{
return [
@@ -79,6 +99,11 @@ final class TradeConstant
];
}
/**
* 获取退款状态映射。
*
* @return array<int, string> 退款状态名称表
*/
public static function refundStatusMap(): array
{
return [
@@ -90,6 +115,11 @@ final class TradeConstant
];
}
/**
* 获取可变更的订单状态列表。
*
* @return array<int, int> 状态列表
*/
public static function orderMutableStatuses(): array
{
return [
@@ -98,6 +128,11 @@ final class TradeConstant
];
}
/**
* 获取订单终态列表。
*
* @return array<int, int> 状态列表
*/
public static function orderTerminalStatuses(): array
{
return [
@@ -108,11 +143,22 @@ final class TradeConstant
];
}
/**
* 判断订单是否为终态。
*
* @param int $status 状态
* @return bool 是否为终态
*/
public static function isOrderTerminalStatus(int $status): bool
{
return in_array($status, self::orderTerminalStatuses(), true);
}
/**
* 获取可变更的退款状态列表。
*
* @return array<int, int> 状态列表
*/
public static function refundMutableStatuses(): array
{
return [
@@ -122,6 +168,11 @@ final class TradeConstant
];
}
/**
* 获取退款终态列表。
*
* @return array<int, int> 状态列表
*/
public static function refundTerminalStatuses(): array
{
return [
@@ -130,11 +181,22 @@ final class TradeConstant
];
}
/**
* 判断退款是否为终态。
*
* @param int $status 状态
* @return bool 是否为终态
*/
public static function isRefundTerminalStatus(int $status): bool
{
return in_array($status, self::refundTerminalStatuses(), true);
}
/**
* 获取可变更的清算状态列表。
*
* @return array<int, int> 状态列表
*/
public static function settlementMutableStatuses(): array
{
return [
@@ -142,6 +204,11 @@ final class TradeConstant
];
}
/**
* 获取清算终态列表。
*
* @return array<int, int> 状态列表
*/
public static function settlementTerminalStatuses(): array
{
return [
@@ -150,8 +217,18 @@ final class TradeConstant
];
}
/**
* 判断清算是否为终态。
*
* @param int $status 状态
* @return bool 是否为终态
*/
public static function isSettlementTerminalStatus(int $status): bool
{
return in_array($status, self::settlementTerminalStatuses(), true);
}
}

View File

@@ -4,58 +4,88 @@ declare(strict_types=1);
namespace app\common\interface;
/**
* 支付插件基础契约接口
* 支付插件基础契约接口
*
* 职责边界:
* - `PayPluginInterface`:插件生命周期 + 元信息(后台展示/可配置/可路由
* - `PaymentInterface`:支付动作能力下单/查询/关单/退款/回调
* - `PayPluginInterface`:插件生命周期和元信息,用于后台展示、配置和路由。
* - `PaymentInterface`:支付动作能力,用于下单查询关单退款回调。
*
* 约定:
* - `init()` 会在每次发起支付/退款等动作前由服务层调用,用于注入该通道对应的插件配置。
* - 元信息方法应为纯读取,不要依赖外部状态或数据库。
* - `init()` 会在每次发起支付退款前由服务层调用,用于注入该通道对应的插件配置。
* - 元信息方法应为纯读取,不要依赖外部状态或数据库。
*/
interface PayPluginInterface
{
/**
* 初始化插件注入通道配置
* 初始化插件注入通道配置
*
* 典型来源:`ma_payment_plugin_conf.config`,并由服务层额外合并通道信息、支付方式声明等上下文。
* 插件应在这里完成:缓存配置、初始化 SDK/HTTP 客户端等。
*
* @param array<string, mixed> $channelConfig
* @param array $channelConfig 渠道配置
* @return void
*/
public function init(array $channelConfig): void;
/** 插件代码(与 ma_payment_plugin.code 对应) */
/**
* 获取插件代码。
*
* @return string 插件代码
*/
public function getCode(): string;
/** 插件名称(用于后台展示) */
/**
* 获取插件名称。
*
* @return string 插件名称
*/
public function getName(): string;
/** 插件作者名称(用于后台展示) */
/**
* 获取作者名称。
*
* @return string 作者名称
*/
public function getAuthorName(): string;
/** 插件作者链接(用于后台展示) */
/**
* 获取作者链接。
*
* @return string 作者链接
*/
public function getAuthorLink(): string;
/** 插件版本号(用于后台展示) */
/**
* 获取版本号。
*
* @return string 版本号
*/
public function getVersion(): string;
/**
* 插件声明支持的支付方式编码
* 获取插件声明支持的支付方式编码
*
* @return array<string>
* @return array 支持的支付方式编码
*/
public function getEnabledPayTypes(): array;
/** 插件声明支持的转账方式编码 */
/**
* 获取插件声明支持的转账方式编码。
*
* @return array 支持的转账方式编码
*/
public function getEnabledTransferTypes(): array;
/**
* 插件配置结构(用于后台渲染表单/校验)
* 获取插件配置结构
*
* @return array<string, mixed>
* @return array 配置结构
*/
public function getConfigSchema(): array;
}

View File

@@ -9,91 +9,74 @@ use support\Request;
use support\Response;
/**
* 支付插件接口
* 支付动作能力接口
*
* 所有支付插件必须实现此接口,用于统一下单、订单查询、关闭、退款回调通知等核心能力
* 建议继承 BasePayment 获 HTTP 请求等通用能力,再实现本接口。
* 所有支付插件必须实现此接口,用于统一下单、订单查询、关闭、退款回调通知。
* 建议继承 `BasePayment` HTTP 请求等通用能力,再实现本接口。
*
* 异常约定:实现类在业务失败时应抛出 PaymentException便于统一处理和返回。
* 异常约定:实现类在业务失败时应抛出 `PaymentException`,便于统一处理和返回。
*/
interface PaymentInterface
{
// ==================== 订单操作 ====================
/**
* 统一下单
* 发起支付下单
*
* @param array<string, mixed> $order 订单数据,通常包含:
* - order_id: 系统支付单号,建议直接使用 pay_no
* - amount: 金额(分)
* - subject: 商品标题
* - body: 商品描述
* - callback_url: 第三方异步回调地址(回调到本系统)
* - return_url: 支付完成跳转地址
* @return array<string, mixed> 支付参数,需包含 pay_params、chan_order_no、chan_trade_no
* @throws PaymentException 下单失败、渠道异常、参数错误等
* @param array $order 订单
* @return array 下单结果
*/
public function pay(array $order): array;
/**
* 查询订单状态
* 查询订单状态
*
* @param array<string, mixed> $order 订单数据(至少含 order_id、chan_order_no
* @return array<string, mixed> 订单状态信息,通常包含:
* - status: 订单状态
* - chan_trade_no: 渠道交易号
* - pay_amount: 实付金额
* @throws PaymentException 查询失败、渠道异常等
* @param array $order 订单参数
* @return array 查询结果
*/
public function query(array $order): array;
/**
* 关闭订单
* 关闭订单
*
* @param array<string, mixed> $order 订单数据(至少含 order_id、chan_order_no
* @return array<string, mixed> 关闭结果,通常包含 success、msg
* @throws PaymentException 关闭失败、渠道异常等
* @param array $order 订单参数
* @return array 关闭结果
*/
public function close(array $order): array;
/**
* 申请退款
* 申请退款
*
* @param array<string, mixed> $order 退款数据,通常包含:
* - order_id: 原支付单号
* - chan_order_no: 渠道订单号
* - refund_amount: 退款金额(分)
* - refund_no: 退款单号
* @return array<string, mixed> 退款结果,通常包含 success、chan_refund_no、msg
* @throws PaymentException 退款失败、渠道异常等
* @param array $order 订单参数
* @return array 退款结果
*/
public function refund(array $order): array;
// ==================== 异步通知 ====================
/**
* 解析并验证支付回调通知
* 解析并验证支付回调通知
*
* @param Request $request 支付渠道的异步通知请求GET/POST 参数)
* @return array<string, mixed> 解析结果,通常包含:
* - success: 是否支付成功
* - status: 插件解析出的渠道状态文本
* - pay_order_id: 系统支付单号
* - chan_trade_no: 渠道交易号
* - chan_order_no: 渠道订单号
* - amount: 支付金额(分)
* - paid_at: 支付成功时间
* @throws PaymentException 验签失败、数据异常等
* @param Request $request 请求对象
* @return array 回调结果
*/
public function notify(Request $request): array;
/**
* 回调处理成功时返回给第三方的平台响应。
*
* @return string|Response 响应内容
*/
public function notifySuccess(): string|Response;
/**
* 回调处理失败时返回给第三方的平台响应。
*
* @return string|Response 响应内容
*/
public function notifyFail(): string|Response;
}

View File

@@ -17,7 +17,7 @@ class Cors implements MiddlewareInterface
* 处理请求。
*
* @param Request $request 请求对象
* @param callable $handler 下一个中间件处理函数
* @param callable $handler handler
* @return Response 响应对象
*/
public function process(Request $request, callable $handler): Response
@@ -32,3 +32,7 @@ class Cors implements MiddlewareInterface
]);
}
}

View File

@@ -5,7 +5,9 @@ declare(strict_types=1);
namespace app\common\payment;
use app\common\base\BasePayment;
use app\common\constant\FileConstant;
use app\common\interface\PaymentInterface;
use app\common\interface\PayPluginInterface;
use app\common\util\FormatHelper;
use app\exception\PaymentException;
use Psr\Http\Message\ResponseInterface;
@@ -15,14 +17,16 @@ use Yansongda\Pay\Pay;
use Yansongda\Supports\Collection;
/**
* 支付宝支付插件(基于 yansongda/pay ~3.7
* 支付宝支付插件
*
* 支持web电脑网站、h5手机网站、appAPP 支付、mini小程序、pos刷卡、scan扫码、transfer转账
* 基于 `yansongda/pay` 封装支付宝直连能力支持网页、H5、APP、小程序、刷卡、扫码和转账
*
* 通道配置app_id, app_secret_cert, app_public_cert_path, alipay_public_cert_path,
* alipay_root_cert_path, mode(0正式/1沙箱)
* 通道配置:`app_id`、`app_secret_cert`、`app_public_cert_path`、`alipay_public_cert_path`、
* `alipay_root_cert_path`、`mode`0 正式 / 1 沙箱)。
*
* 证书字段通过上传选择器保存 `object_key`,初始化时会自动解析成本地可读路径。
*/
class AlipayPayment extends BasePayment implements PaymentInterface
class AlipayPayment extends BasePayment implements PaymentInterface, PayPluginInterface
{
private const PRODUCT_WEB = 'alipay_web';
private const PRODUCT_H5 = 'alipay_h5';
@@ -56,6 +60,11 @@ class AlipayPayment extends BasePayment implements PaymentInterface
'transfer' => self::PRODUCT_TRANSFER,
];
/**
* 插件元信息。
*
* @var array<string, mixed>
*/
protected array $paymentInfo = [
'code' => 'alipay',
'name' => '支付宝直连',
@@ -67,9 +76,54 @@ class AlipayPayment extends BasePayment implements PaymentInterface
'config_schema' => [
["type" => "input", "field" => "app_id", "title" => "应用ID", "value" => "", "props" => ["placeholder" => "请输入应用ID"], "validate" => [["required" => true, "message" => "应用ID不能为空"]]],
["type" => "textarea", "field" => "app_secret_cert", "title" => "应用私钥", "value" => "", "props" => ["placeholder" => "请输入应用私钥", "rows" => 4], "validate" => [["required" => true, "message" => "应用私钥不能为空"]]],
["type" => "input", "field" => "app_public_cert_path", "title" => "应用公钥证书路径", "value" => "", "props" => ["placeholder" => "请输入应用公钥证书路径"], "validate" => [["required" => true, "message" => "应用公钥证书路径不能为空"]]],
["type" => "input", "field" => "alipay_public_cert_path", "title" => "支付宝公钥证书路径", "value" => "", "props" => ["placeholder" => "请输入支付宝公钥证书路径"], "validate" => [["required" => true, "message" => "支付宝公钥证书路径不能为空"]]],
["type" => "input", "field" => "alipay_root_cert_path", "title" => "支付宝根证书路径", "value" => "", "props" => ["placeholder" => "请输入支付宝根证书路径"], "validate" => [["required" => true, "message" => "支付宝根证书路径不能为空"]]],
[
"type" => "upload",
"field" => "app_public_cert_path",
"title" => "应用公钥证书",
"value" => "",
"props" => [
"fileUpload" => [
"selectorType" => "file",
"scene" => FileConstant::SCENE_CERTIFICATE,
"isLocal" => true,
"isPublic" => false,
"getKey" => "object_key",
],
],
"validate" => [["required" => true, "message" => "应用公钥证书不能为空"]],
],
[
"type" => "upload",
"field" => "alipay_public_cert_path",
"title" => "支付宝公钥证书",
"value" => "",
"props" => [
"fileUpload" => [
"selectorType" => "file",
"scene" => FileConstant::SCENE_CERTIFICATE,
"isLocal" => true,
"isPublic" => false,
"getKey" => "object_key",
],
],
"validate" => [["required" => true, "message" => "支付宝公钥证书不能为空"]],
],
[
"type" => "upload",
"field" => "alipay_root_cert_path",
"title" => "支付宝根证书",
"value" => "",
"props" => [
"fileUpload" => [
"selectorType" => "file",
"scene" => FileConstant::SCENE_CERTIFICATE,
"isLocal" => true,
"isPublic" => false,
"getKey" => "object_key",
],
],
"validate" => [["required" => true, "message" => "支付宝根证书不能为空"]],
],
[
"type" => "checkbox",
"field" => "enabled_products",
@@ -90,6 +144,12 @@ class AlipayPayment extends BasePayment implements PaymentInterface
],
];
/**
* 初始化支付宝插件。
*
* @param array $channelConfig 渠道配置
* @return void
*/
public function init(array $channelConfig): void
{
parent::init($channelConfig);
@@ -98,9 +158,9 @@ class AlipayPayment extends BasePayment implements PaymentInterface
'default' => [
'app_id' => $this->getConfig('app_id', ''),
'app_secret_cert' => $this->getConfig('app_secret_cert', ''),
'app_public_cert_path' => $this->getConfig('app_public_cert_path', ''),
'alipay_public_cert_path' => $this->getConfig('alipay_public_cert_path', ''),
'alipay_root_cert_path' => $this->getConfig('alipay_root_cert_path', ''),
'app_public_cert_path' => runtime_path((string) $this->getConfig('app_public_cert_path', '')),
'alipay_public_cert_path' => runtime_path((string) $this->getConfig('alipay_public_cert_path', '')),
'alipay_root_cert_path' => runtime_path((string) $this->getConfig('alipay_root_cert_path', '')),
'notify_url' => $this->getConfig('notify_url', ''),
'return_url' => $this->getConfig('return_url', ''),
'mode' => (int)($this->getConfig('mode', Pay::MODE_NORMAL)),
@@ -110,6 +170,14 @@ class AlipayPayment extends BasePayment implements PaymentInterface
Pay::config(array_merge($config, ['_force' => true]));
}
/**
* 根据订单上下文选择支付宝产品。
*
* @param array $order 订单上下文
* @param bool $validateEnabled 是否校验已开通产品
* @return string 产品编码
* @throws PaymentException
*/
private function chooseProduct(array $order, bool $validateEnabled = true): string
{
$enabled = $this->normalizeEnabledProducts($this->channelConfig['enabled_products'] ?? self::DEFAULT_ENABLED_PRODUCTS);
@@ -152,6 +220,12 @@ class AlipayPayment extends BasePayment implements PaymentInterface
return in_array($prefer, $enabled, true) ? $prefer : ($enabled[0] ?? self::PRODUCT_WEB);
}
/**
* 标准化已开通产品列表。
*
* @param array|string|null $products 已开通产品配置
* @return array 标准化后的产品编码列表
*/
private function normalizeEnabledProducts(mixed $products): array
{
if (is_string($products)) {
@@ -176,6 +250,12 @@ class AlipayPayment extends BasePayment implements PaymentInterface
return $normalized !== [] ? $normalized : self::DEFAULT_ENABLED_PRODUCTS;
}
/**
* 解析显式指定的产品。
*
* @param array $order 订单上下文
* @return string|null 产品编码
*/
private function resolveExplicitProduct(array $order): ?string
{
$context = $this->collectOrderContext($order);
@@ -197,6 +277,12 @@ class AlipayPayment extends BasePayment implements PaymentInterface
return null;
}
/**
* 归一化产品编码。
*
* @param mixed $value 原始产品标识
* @return string|null 标准化后的产品编码
*/
private function normalizeProductCode(mixed $value): ?string
{
$value = strtolower(trim((string) $value));
@@ -215,11 +301,23 @@ class AlipayPayment extends BasePayment implements PaymentInterface
return null;
}
/**
* 获取产品对应的动作名。
*
* @param string $product 产品编码
* @return string 动作名
*/
private function productAction(string $product): string
{
return self::PRODUCT_ACTION_MAP[$product] ?? $product;
}
/**
* 合并订单上下文。
*
* @param array $order 订单上下文
* @return array 合并后的上下文
*/
private function collectOrderContext(array $order): array
{
$context = $order;
@@ -236,6 +334,12 @@ class AlipayPayment extends BasePayment implements PaymentInterface
return $context;
}
/**
* 标准化参数包。
*
* @param array|string|null $param 原始参数包
* @return array<string, mixed> 参数数组
*/
private function normalizeParamBag(mixed $param): array
{
if (is_array($param)) {
@@ -257,6 +361,12 @@ class AlipayPayment extends BasePayment implements PaymentInterface
return [];
}
/**
* 构建基础下单参数。
*
* @param array $params 原始参数
* @return array 基础下单参数
*/
private function buildBasePayParams(array $params): array
{
$base = [
@@ -283,6 +393,14 @@ class AlipayPayment extends BasePayment implements PaymentInterface
return $base;
}
/**
* 从集合中提取首个非空值。
*
* @param Collection $result 结果集合
* @param array $keys 候选键
* @param mixed $default 默认值
* @return mixed 提取到的首个非空值
*/
private function extractCollectionValue(Collection $result, array $keys, mixed $default = ''): mixed
{
foreach ($keys as $key) {
@@ -295,6 +413,13 @@ class AlipayPayment extends BasePayment implements PaymentInterface
return $default;
}
/**
* 发起支付宝下单。
*
* @param array $order 订单上下文
* @return array 下单结果
* @throws PaymentException
*/
public function pay(array $order): array
{
$orderId = (string) ($order['order_id'] ?? $order['pay_no'] ?? '');
@@ -338,6 +463,12 @@ class AlipayPayment extends BasePayment implements PaymentInterface
}
}
/**
* 发起网页支付。
*
* @param array $params 基础参数
* @return array 下单结果
*/
private function doWeb(array $params): array
{
$response = Pay::alipay()->web($params);
@@ -358,6 +489,12 @@ class AlipayPayment extends BasePayment implements PaymentInterface
];
}
/**
* 发起 H5 支付。
*
* @param array $params 基础参数
* @return array 下单结果
*/
private function doH5(array $params): array
{
$returnUrl = $params['_return_url'] ?? $this->getConfig('return_url', '');
@@ -382,6 +519,12 @@ class AlipayPayment extends BasePayment implements PaymentInterface
];
}
/**
* 发起扫码支付。
*
* @param array $params 基础参数
* @return array 下单结果
*/
private function doScan(array $params): array
{
/** @var Collection $result */
@@ -402,6 +545,12 @@ class AlipayPayment extends BasePayment implements PaymentInterface
];
}
/**
* 发起 APP 支付。
*
* @param array $params 基础参数
* @return array 下单结果
*/
private function doApp(array $params): array
{
/** @var Collection $result */
@@ -422,6 +571,14 @@ class AlipayPayment extends BasePayment implements PaymentInterface
];
}
/**
* 发起小程序支付。
*
* @param array $params 基础参数
* @param array $order 订单上下文
* @return array 下单结果
* @throws PaymentException
*/
private function doMini(array $params, array $order): array
{
$context = $this->collectOrderContext($order);
@@ -454,6 +611,14 @@ class AlipayPayment extends BasePayment implements PaymentInterface
];
}
/**
* 发起刷卡支付。
*
* @param array $params 基础参数
* @param array $order 订单上下文
* @return array 下单结果
* @throws PaymentException
*/
private function doPos(array $params, array $order): array
{
$context = $this->collectOrderContext($order);
@@ -486,6 +651,14 @@ class AlipayPayment extends BasePayment implements PaymentInterface
];
}
/**
* 发起转账。
*
* @param array $params 基础参数
* @param array $order 订单上下文
* @return array 下单结果
* @throws PaymentException
*/
private function doTransfer(array $params, array $order): array
{
$context = $this->collectOrderContext($order);
@@ -537,6 +710,13 @@ class AlipayPayment extends BasePayment implements PaymentInterface
];
}
/**
* 查询支付宝订单状态。
*
* @param array $order 订单上下文
* @return array 查询结果
* @throws PaymentException
*/
public function query(array $order): array
{
$product = $this->chooseProduct($order, false);
@@ -569,6 +749,13 @@ class AlipayPayment extends BasePayment implements PaymentInterface
}
}
/**
* 关闭支付宝订单。
*
* @param array $order 订单上下文
* @return array 关闭结果
* @throws PaymentException
*/
public function close(array $order): array
{
$product = $this->chooseProduct($order, false);
@@ -591,6 +778,13 @@ class AlipayPayment extends BasePayment implements PaymentInterface
}
}
/**
* 发起支付宝退款。
*
* @param array $order 订单上下文
* @return array 退款结果
* @throws PaymentException
*/
public function refund(array $order): array
{
$product = $this->chooseProduct($order, false);
@@ -637,6 +831,13 @@ class AlipayPayment extends BasePayment implements PaymentInterface
}
}
/**
* 解析支付宝回调通知。
*
* @param Request $request 请求对象
* @return array 回调结果
* @throws PaymentException
*/
public function notify(Request $request): array
{
$params = array_merge($request->get(), $request->post());
@@ -670,13 +871,26 @@ class AlipayPayment extends BasePayment implements PaymentInterface
}
}
/**
* 返回回调成功响应。
*
* @return string|Response 响应内容
*/
public function notifySuccess(): string|Response
{
return 'success';
}
/**
* 返回回调失败响应。
*
* @return string|Response 响应内容
*/
public function notifyFail(): string|Response
{
return 'fail';
}
}

View File

@@ -15,6 +15,9 @@ class FormatHelper
{
/**
* 金额格式化,单位为元。
*
* @param int $amount 金额(分)
* @return string 格式化后的金额字符串
*/
public static function amount(int $amount): string
{
@@ -23,6 +26,9 @@ class FormatHelper
/**
* 金额格式化0 时显示不限。
*
* @param int $amount 金额(分)
* @return string 格式化后的金额字符串
*/
public static function amountOrUnlimited(int $amount): string
{
@@ -31,6 +37,9 @@ class FormatHelper
/**
* 次数格式化0 时显示不限。
*
* @param int $count 次数
* @return string 格式化后的次数字符串
*/
public static function countOrUnlimited(int $count): string
{
@@ -39,6 +48,9 @@ class FormatHelper
/**
* 费率格式化,单位为百分点。
*
* @param int $basisPoints 基点值
* @return string 格式化后的费率字符串
*/
public static function rate(int $basisPoints): string
{
@@ -47,6 +59,9 @@ class FormatHelper
/**
* 延迟格式化。
*
* @param int $latencyMs 延迟毫秒数
* @return string 格式化后的延迟字符串
*/
public static function latency(int $latencyMs): string
{
@@ -55,6 +70,10 @@ class FormatHelper
/**
* 日期格式化。
*
* @param mixed $value 日期值
* @param string $emptyText 为空时显示文案
* @return string 格式化后的日期字符串
*/
public static function date(mixed $value, string $emptyText = ''): string
{
@@ -63,6 +82,10 @@ class FormatHelper
/**
* 日期时间格式化。
*
* @param mixed $value 日期时间值
* @param string $emptyText 为空时显示文案
* @return string 格式化后的日期时间字符串
*/
public static function dateTime(mixed $value, string $emptyText = ''): string
{
@@ -71,6 +94,11 @@ class FormatHelper
/**
* 按时间戳格式化。
*
* @param int $timestamp Unix 时间戳
* @param string $pattern 输出格式
* @param string $emptyText 为空时显示文案
* @return string 格式化后的时间字符串
*/
public static function timestamp(int $timestamp, string $pattern = 'Y-m-d H:i:s', string $emptyText = ''): string
{
@@ -83,6 +111,10 @@ class FormatHelper
/**
* JSON 文本格式化。
*
* @param mixed $value JSON 值
* @param string $emptyText 为空时显示文案
* @return string 格式化后的 JSON 文本
*/
public static function json(mixed $value, string $emptyText = ''): string
{
@@ -106,6 +138,11 @@ class FormatHelper
/**
* 映射表文本转换。
*
* @param int $value 待映射值
* @param array<int, string> $map 映射表
* @param string $default 默认值
* @return string 映射后的文本
*/
public static function textFromMap(int $value, array $map, string $default = '未知'): string
{
@@ -114,6 +151,10 @@ class FormatHelper
/**
* 接口凭证明文脱敏。
*
* @param string $credentialValue 凭证原文
* @param bool $maskShortValue 是否对短值也进行脱敏
* @return string 脱敏后的文本
*/
public static function maskCredentialValue(string $credentialValue, bool $maskShortValue = true): string
{
@@ -132,6 +173,9 @@ class FormatHelper
/**
* 将模型或对象归一化成数组。
*
* @param mixed $value 模型、对象或数组
* @return array|null 归一化后的数组
*/
public static function normalizeModel(mixed $value): ?array
{
@@ -163,6 +207,11 @@ class FormatHelper
/**
* 统一格式化时间值。
*
* @param mixed $value 时间值
* @param string $pattern 输出格式
* @param string $emptyText 为空时显示文案
* @return string 格式化后的时间文本
*/
private static function formatTemporalValue(mixed $value, string $pattern, string $emptyText): string
{
@@ -186,3 +235,4 @@ class FormatHelper
return (string) $value;
}
}

View File

@@ -24,11 +24,11 @@ class JwtTokenManager
/**
* 签发 JWT并把会话态写入 Redis。
*
* @param string $guard 认证域名称,例如 admin 或 merchant
* @param array $claims JWT 自定义声明,通常包含主体 ID 等核心身份信息
* @param array $sessionData Redis 会话数据,通常包含用户展示信息和登录上下文
* @param int|null $ttlSeconds 有效期,单位秒;为空时使用 guard 默认 TTL
* @return array{token:string,expires_in:int,jti:string,claims:array,session:array}
* @param string $guard 登录域
* @param array<string, mixed> $claims JWT 声明
* @param array<string, mixed> $sessionData 会话数据
* @param int|null $ttlSeconds 过期秒数
* @return array{token:string,expires_in:int,jti:string,claims:array<string, mixed>,session:array<string, mixed>} 签发结果
*/
public function issue(string $guard, array $claims, array $sessionData, ?int $ttlSeconds = null): array
{
@@ -75,7 +75,11 @@ class JwtTokenManager
* - 再通过 jti 反查 Redis 会话,确保 token 仍然有效。
* - 每次命中会刷新最近访问时间。
*
* @return array{claims:array,session:array}|null
* @param string $guard 登录域
* @param string $token JWT 字符串
* @param string $ip 最近访问 IP
* @param string $userAgent 用户Agent
* @return array{claims:array<string, mixed>,session:array<string, mixed>}|null 验证结果
*/
public function verify(string $guard, string $token, string $ip = '', string $userAgent = ''): ?array
{
@@ -118,6 +122,10 @@ class JwtTokenManager
* 通过 token 撤销登录态。
*
* 适用于主动退出登录场景。
*
* @param string $guard 登录域
* @param string $token JWT 字符串
* @return bool 是否已撤销
*/
public function revoke(string $guard, string $token): bool
{
@@ -138,6 +146,10 @@ class JwtTokenManager
* 通过 jti 直接撤销登录态。
*
* 适用于已经掌握会话标识但没有原始 token 的补偿清理场景。
*
* @param string $guard 登录域
* @param string $jti 会话标识
* @return bool 是否已撤销
*/
public function revokeByJti(string $guard, string $jti): bool
{
@@ -152,6 +164,10 @@ class JwtTokenManager
* 根据 jti 获取会话数据。
*
* 返回值来自 Redis若已过期或不存在则返回 null。
*
* @param string $guard 登录域
* @param string $jti 会话标识
* @return array<string, mixed>|null 会话数据
*/
public function session(string $guard, string $jti): ?array
{
@@ -168,6 +184,10 @@ class JwtTokenManager
* 解码并校验 JWT。
*
* 只做签名、过期和 guard 校验,不处理 Redis 会话。
*
* @param string $guard 登录域
* @param string $token JWT 字符串
* @return array<string, mixed>|null JWT 载荷
*/
protected function decode(string $guard, string $token): ?array
{
@@ -195,6 +215,12 @@ class JwtTokenManager
/**
* 将会话数据写入 Redis并设置 TTL。
*
* @param string $guard 登录域
* @param string $jti 会话标识
* @param array<string, mixed> $session 会话数据
* @param int $ttlSeconds 过期秒数
* @return void
*/
protected function storeSession(string $guard, string $jti, array $session, int $ttlSeconds): void
{
@@ -209,6 +235,10 @@ class JwtTokenManager
* 构造 Redis 会话键。
*
* 最终格式由 guard 对应的 redis_prefix 加上 jti 组成。
*
* @param string $guard 登录域
* @param string $jti 会话标识
* @return string Redis 会话键
*/
protected function sessionKey(string $guard, string $jti): string
{
@@ -218,7 +248,9 @@ class JwtTokenManager
/**
* 获取指定认证域的配置。
*
* @throws \InvalidArgumentException 当 guard 未配置时抛出
* @param string $guard 登录域
* @return array<string, mixed> 认证配置
* @throws \InvalidArgumentException
*/
protected function guardConfig(string $guard): array
{
@@ -232,6 +264,11 @@ class JwtTokenManager
/**
* 校验 HS256 密钥长度,避免 firebase/php-jwt 抛出底层异常。
*
* @param string $guard 登录域
* @param string $secret 密钥
* @return void
* @throws RuntimeException
*/
protected function assertHmacSecretLength(string $guard, string $secret): void
{
@@ -252,3 +289,5 @@ class JwtTokenManager
));
}
}

View File

@@ -10,7 +10,13 @@ use Webman\Exception\BusinessException;
class BalanceInsufficientException extends BusinessException
{
/**
* 构造函数,组装异常信息
* 构造方法
*
* @param int $merchantId 商户ID
* @param int $needAmount needAmount
* @param int $availableAmount 可用Amount
* @param array $data 数据
* @return void
*/
public function __construct(int $merchantId = 0, int $needAmount = 0, int $availableAmount = 0, array $data = [])
{
@@ -31,3 +37,8 @@ class BalanceInsufficientException extends BusinessException
}
}
}

View File

@@ -12,7 +12,12 @@ use Webman\Exception\BusinessException;
class BusinessStateException extends BusinessException
{
/**
* 构造函数,组装异常信息
* 构造方法
*
* @param string $message message
* @param array $data 数据
* @param int $bizCode 业务Code
* @return void
*/
public function __construct(string $message = '业务状态不允许当前操作', array $data = [], int $bizCode = 40910)
{
@@ -23,3 +28,8 @@ class BusinessStateException extends BusinessException
}
}
}

View File

@@ -12,7 +12,12 @@ use Webman\Exception\BusinessException;
class ConflictException extends BusinessException
{
/**
* 构造函数,组装异常信息
* 构造方法
*
* @param string $message message
* @param array $data 数据
* @param int $bizCode 业务Code
* @return void
*/
public function __construct(string $message = '业务冲突', array $data = [], int $bizCode = 40900)
{
@@ -23,3 +28,8 @@ class ConflictException extends BusinessException
}
}
}

View File

@@ -10,7 +10,11 @@ use Webman\Exception\BusinessException;
class NotifyRetryExceededException extends BusinessException
{
/**
* 构造函数,组装异常信息
* 构造方法
*
* @param string $notifyNo 通知号
* @param array $data 数据
* @return void
*/
public function __construct(string $notifyNo = '', array $data = [])
{
@@ -29,3 +33,8 @@ class NotifyRetryExceededException extends BusinessException
}
}
}

View File

@@ -12,7 +12,12 @@ use Webman\Exception\BusinessException;
class PaymentException extends BusinessException
{
/**
* 构造函数,统一组装业务码与附加数据
* 构造方法
*
* @param string $message message
* @param int $bizCode 业务Code
* @param array $data 数据
* @return void
*/
public function __construct(string $message = '支付渠道处理失败', int $bizCode = 40200, array $data = [])
{
@@ -23,3 +28,8 @@ class PaymentException extends BusinessException
}
}
}

View File

@@ -12,7 +12,12 @@ use Webman\Exception\BusinessException;
class ResourceNotFoundException extends BusinessException
{
/**
* 构造函数,组装异常信息
* 构造方法
*
* @param string $message message
* @param array $data 数据
* @param int $bizCode 业务Code
* @return void
*/
public function __construct(string $message = '资源不存在', array $data = [], int $bizCode = 40400)
{
@@ -23,3 +28,8 @@ class ResourceNotFoundException extends BusinessException
}
}
}

View File

@@ -10,7 +10,12 @@ use Webman\Exception\BusinessException;
class ValidationException extends BusinessException
{
/**
* 构造函数,组装异常信息
* 构造方法
*
* @param string $message message
* @param int|array $bizCodeOrData 业务CodeOr数据
* @param array $data 数据
* @return void
*/
public function __construct(string $message = '参数校验失败', int|array $bizCodeOrData = 40001, array $data = [])
{
@@ -28,3 +33,8 @@ class ValidationException extends BusinessException
}
}
}

View File

@@ -10,11 +10,16 @@ use support\Response;
/**
* 商户账户控制器。
*
* @property MerchantAccountService $merchantAccountService 商户账户服务
*/
class MerchantAccountController extends BaseController
{
/**
* 构造函数,注入商户账户服务
* 构造方法
*
* @param MerchantAccountService $merchantAccountService 商户账户服务
* @return void
*/
public function __construct(
protected MerchantAccountService $merchantAccountService
@@ -23,6 +28,9 @@ class MerchantAccountController extends BaseController
/**
* 查询商户账户列表。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
@@ -39,6 +47,9 @@ class MerchantAccountController extends BaseController
/**
* 资金中心概览。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function summary(Request $request): Response
{
@@ -47,6 +58,10 @@ class MerchantAccountController extends BaseController
/**
* 查询商户账户详情。
*
* @param Request $request 请求对象
* @param string $id 商户账户ID
* @return Response 响应对象
*/
public function show(Request $request, string $id): Response
{
@@ -61,3 +76,8 @@ class MerchantAccountController extends BaseController
}
}

View File

@@ -10,11 +10,16 @@ use support\Response;
/**
* 商户账户流水控制器。
*
* @property MerchantAccountLedgerService $merchantAccountLedgerService 商户账户流水服务
*/
class MerchantAccountLedgerController extends BaseController
{
/**
* 构造函数,注入账户流水服务
* 构造方法
*
* @param MerchantAccountLedgerService $merchantAccountLedgerService 商户账户流水服务
* @return void
*/
public function __construct(
protected MerchantAccountLedgerService $merchantAccountLedgerService
@@ -23,6 +28,9 @@ class MerchantAccountLedgerController extends BaseController
/**
* 查询账户流水列表。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
@@ -39,6 +47,10 @@ class MerchantAccountLedgerController extends BaseController
/**
* 查询账户流水详情。
*
* @param Request $request 请求对象
* @param string $id 商户账户流水ID
* @return Response 响应对象
*/
public function show(Request $request, string $id): Response
{
@@ -52,3 +64,8 @@ class MerchantAccountLedgerController extends BaseController
return $this->success($ledger);
}
}

View File

@@ -3,6 +3,7 @@
namespace app\http\admin\controller\file;
use app\common\base\BaseController;
use app\exception\ValidationException;
use app\http\admin\validation\FileRecordValidator;
use app\service\file\FileRecordService;
use Webman\Http\UploadFile;
@@ -11,14 +12,28 @@ use support\Response;
/**
* 文件控制器。
*
* @property FileRecordService $fileRecordService 文件记录服务
*/
class FileRecordController extends BaseController
{
/**
* 构造方法。
*
* @param FileRecordService $fileRecordService 文件记录服务
* @return void
*/
public function __construct(
protected FileRecordService $fileRecordService
) {
}
/**
* 查询文件记录列表
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
$data = $this->validated($request->all(), FileRecordValidator::class, 'index');
@@ -32,11 +47,24 @@ class FileRecordController extends BaseController
);
}
/**
* 获取文件记录选项
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function options(Request $request): Response
{
return $this->success($this->fileRecordService->options());
}
/**
* 查询文件记录详情
*
* @param Request $request 请求对象
* @param string $id 文件记录ID
* @return Response 响应对象
*/
public function show(Request $request, string $id): Response
{
$data = $this->validated(['id' => (int) $id], FileRecordValidator::class, 'show');
@@ -44,12 +72,19 @@ class FileRecordController extends BaseController
return $this->success($this->fileRecordService->detail((int) $data['id']));
}
/**
* 上传文件记录
*
* @param Request $request 请求对象
* @return Response 响应对象
* @throws ValidationException
*/
public function upload(Request $request): Response
{
$data = $this->validated(array_merge($this->payload($request), ['scene' => $request->input('scene')]), FileRecordValidator::class, 'store');
$uploadedFile = $request->file('file');
if ($uploadedFile === null) {
return $this->fail('请先选择上传文件', 400);
throw new ValidationException('请先选择上传文件');
}
$createdBy = $this->currentAdminId($request);
@@ -63,6 +98,10 @@ class FileRecordController extends BaseController
}
}
if ($items === []) {
throw new ValidationException('上传文件无效');
}
return $this->success([
'list' => $items,
'total' => count($items),
@@ -70,12 +109,18 @@ class FileRecordController extends BaseController
}
if (!$uploadedFile instanceof UploadFile) {
return $this->fail('上传文件无效', 400);
throw new ValidationException('上传文件无效');
}
return $this->success($this->fileRecordService->upload($uploadedFile, $data, $createdBy, $createdByName));
}
/**
* 导入远程文件记录
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function importRemote(Request $request): Response
{
$data = $this->validated($this->payload($request), FileRecordValidator::class, 'importRemote');
@@ -92,6 +137,13 @@ class FileRecordController extends BaseController
);
}
/**
* 获取文件预览响应。
*
* @param Request $request 请求对象
* @param string $id 文件记录ID
* @return Response 响应对象
*/
public function preview(Request $request, string $id): Response
{
$data = $this->validated(['id' => (int) $id], FileRecordValidator::class, 'preview');
@@ -99,6 +151,13 @@ class FileRecordController extends BaseController
return $this->fileRecordService->previewResponse((int) $data['id']);
}
/**
* 获取文件下载响应。
*
* @param Request $request 请求对象
* @param string $id 文件记录ID
* @return Response 响应对象
*/
public function download(Request $request, string $id): Response
{
$data = $this->validated(['id' => (int) $id], FileRecordValidator::class, 'download');
@@ -106,13 +165,23 @@ class FileRecordController extends BaseController
return $this->fileRecordService->downloadResponse((int) $data['id']);
}
/**
* 删除文件记录
*
* @param Request $request 请求对象
* @param string $id 文件记录ID
* @return Response 响应对象
*/
public function destroy(Request $request, string $id): Response
{
$data = $this->validated(['id' => (int) $id], FileRecordValidator::class, 'destroy');
if (!$this->fileRecordService->delete((int) $data['id'])) {
return $this->fail('文件不存在', 404);
}
$this->fileRecordService->delete((int) $data['id']);
return $this->success(true);
}
}

View File

@@ -9,12 +9,17 @@ use support\Request;
use support\Response;
/**
* 商户接口凭证管理控制器。
* 商户 API 凭证管理控制器。
*
* @property MerchantApiCredentialService $merchantApiCredentialService 商户 API 凭证服务
*/
class MerchantApiCredentialController extends BaseController
{
/**
* 构造函数,注入商户 API 凭证服务
* 构造方法
*
* @param MerchantApiCredentialService $merchantApiCredentialService 商户 API 凭证服务
* @return void
*/
public function __construct(
protected MerchantApiCredentialService $merchantApiCredentialService
@@ -23,6 +28,9 @@ class MerchantApiCredentialController extends BaseController
/**
* 查询商户 API 凭证列表。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
@@ -39,6 +47,10 @@ class MerchantApiCredentialController extends BaseController
/**
* 查询商户 API 凭证详情。
*
* @param Request $request 请求对象
* @param string $id 商户 API 凭证ID
* @return Response 响应对象
*/
public function show(Request $request, string $id): Response
{
@@ -46,7 +58,7 @@ class MerchantApiCredentialController extends BaseController
$credential = $this->merchantApiCredentialService->findById((int) $data['id']);
if (!$credential) {
return $this->fail('商户接口凭证不存在', 404);
return $this->fail('商户 API 凭证不存在', 404);
}
return $this->success($credential);
@@ -54,6 +66,9 @@ class MerchantApiCredentialController extends BaseController
/**
* 新增商户 API 凭证。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function store(Request $request): Response
{
@@ -64,6 +79,10 @@ class MerchantApiCredentialController extends BaseController
/**
* 修改商户 API 凭证。
*
* @param Request $request 请求对象
* @param string $id 商户 API 凭证ID
* @return Response 响应对象
*/
public function update(Request $request, string $id): Response
{
@@ -75,7 +94,7 @@ class MerchantApiCredentialController extends BaseController
$credential = $this->merchantApiCredentialService->update((int) $data['id'], $data);
if (!$credential) {
return $this->fail('商户接口凭证不存在', 404);
return $this->fail('商户 API 凭证不存在', 404);
}
return $this->success($credential);
@@ -83,6 +102,10 @@ class MerchantApiCredentialController extends BaseController
/**
* 删除商户 API 凭证。
*
* @param Request $request 请求对象
* @param string $id 商户 API 凭证ID
* @return Response 响应对象
*/
public function destroy(Request $request, string $id): Response
{
@@ -90,14 +113,19 @@ class MerchantApiCredentialController extends BaseController
$credential = $this->merchantApiCredentialService->findById((int) $data['id']);
if (!$credential) {
return $this->fail('商户接口凭证不存在', 404);
return $this->fail('商户 API 凭证不存在', 404);
}
if (!$this->merchantApiCredentialService->delete((int) $data['id'])) {
return $this->fail('商户接口凭证删除失败');
return $this->fail('商户 API 凭证删除失败');
}
return $this->success(true);
}
}

View File

@@ -12,11 +12,16 @@ use support\Response;
* 商户管理控制器。
*
* 当前先提供商户列表查询,后续可继续扩展商户详情、新增、编辑等能力。
*
* @property MerchantService $merchantService 商户服务
*/
class MerchantController extends BaseController
{
/**
* 构造函数,注入商户服务
* 构造方法
*
* @param MerchantService $merchantService 商户服务
* @return void
*/
public function __construct(
protected MerchantService $merchantService
@@ -27,6 +32,9 @@ class MerchantController extends BaseController
* 查询商户列表。
*
* 返回值里额外携带启用中的商户分组选项,方便前端一次性渲染筛选条件。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
@@ -39,6 +47,10 @@ class MerchantController extends BaseController
/**
* 查询商户详情。
*
* @param Request $request 请求对象
* @param string $id 商户ID
* @return Response 响应对象
*/
public function show(Request $request, string $id): Response
{
@@ -54,6 +66,9 @@ class MerchantController extends BaseController
/**
* 新增商户。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function store(Request $request): Response
{
@@ -63,6 +78,10 @@ class MerchantController extends BaseController
/**
* 更新商户。
*
* @param Request $request 请求对象
* @param string $id 商户ID
* @return Response 响应对象
*/
public function update(Request $request, string $id): Response
{
@@ -80,6 +99,10 @@ class MerchantController extends BaseController
/**
* 删除商户。
*
* @param Request $request 请求对象
* @param string $id 商户ID
* @return Response 响应对象
*/
public function destroy(Request $request, string $id): Response
{
@@ -90,6 +113,10 @@ class MerchantController extends BaseController
/**
* 重置商户登录密码。
*
* @param Request $request 请求对象
* @param string $id 商户ID
* @return Response 响应对象
*/
public function resetPassword(Request $request, string $id): Response
{
@@ -100,7 +127,11 @@ class MerchantController extends BaseController
}
/**
* 生成或重置商户接口凭证。
* 生成或重置商户 API 凭证。
*
* @param Request $request 请求对象
* @param string $id 商户ID
* @return Response 响应对象
*/
public function issueCredential(Request $request, string $id): Response
{
@@ -111,6 +142,10 @@ class MerchantController extends BaseController
/**
* 查询商户总览。
*
* @param Request $request 请求对象
* @param string $id 商户ID
* @return Response 响应对象
*/
public function overview(Request $request, string $id): Response
{
@@ -121,6 +156,9 @@ class MerchantController extends BaseController
/**
* 查询商户下拉选项。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function options(Request $request): Response
{
@@ -129,6 +167,9 @@ class MerchantController extends BaseController
/**
* 远程查询商户选择项。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function selectOptions(Request $request): Response
{
@@ -139,3 +180,9 @@ class MerchantController extends BaseController
}
}

View File

@@ -12,11 +12,16 @@ use support\Response;
* 商户分组管理控制器。
*
* 负责商户分组的列表、详情、新增、修改和删除。
*
* @property MerchantGroupService $merchantGroupService 商户分组服务
*/
class MerchantGroupController extends BaseController
{
/**
* 构造函数,注入商户分组服务
* 构造方法
*
* @param MerchantGroupService $merchantGroupService 商户分组服务
* @return void
*/
public function __construct(
protected MerchantGroupService $merchantGroupService
@@ -24,9 +29,10 @@ class MerchantGroupController extends BaseController
}
/**
* GET /admin/merchant-groups
*
* 查询商户分组列表。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
@@ -42,9 +48,11 @@ class MerchantGroupController extends BaseController
}
/**
* GET /admin/merchant-groups/{id}
*
* 查询商户分组详情。
*
* @param Request $request 请求对象
* @param string $id 商户分组ID
* @return Response 响应对象
*/
public function show(Request $request, string $id): Response
{
@@ -59,9 +67,10 @@ class MerchantGroupController extends BaseController
}
/**
* POST /admin/merchant-groups
*
* 新增商户分组。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function store(Request $request): Response
{
@@ -71,9 +80,11 @@ class MerchantGroupController extends BaseController
}
/**
* PUT /admin/merchant-groups/{id}
*
* 修改商户分组。
*
* @param Request $request 请求对象
* @param string $id 商户分组ID
* @return Response 响应对象
*/
public function update(Request $request, string $id): Response
{
@@ -92,9 +103,11 @@ class MerchantGroupController extends BaseController
}
/**
* DELETE /admin/merchant-groups/{id}
*
* 删除商户分组。
*
* @param Request $request 请求对象
* @param string $id 商户分组ID
* @return Response 响应对象
*/
public function destroy(Request $request, string $id): Response
{
@@ -109,6 +122,9 @@ class MerchantGroupController extends BaseController
/**
* 查询商户分组下拉选项。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function options(Request $request): Response
{
@@ -116,3 +132,8 @@ class MerchantGroupController extends BaseController
}
}

View File

@@ -10,14 +10,28 @@ use support\Response;
/**
* 商户策略控制器。
*
* @property MerchantPolicyService $merchantPolicyService 商户策略服务
*/
class MerchantPolicyController extends BaseController
{
/**
* 构造方法。
*
* @param MerchantPolicyService $merchantPolicyService 商户策略服务
* @return void
*/
public function __construct(
protected MerchantPolicyService $merchantPolicyService
) {
}
/**
* 查询商户策略列表。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
$data = $this->validated($request->all(), MerchantPolicyValidator::class, 'index');
@@ -31,6 +45,13 @@ class MerchantPolicyController extends BaseController
);
}
/**
* 查询商户策略详情。
*
* @param Request $request 请求对象
* @param string $merchantId 商户ID
* @return Response 响应对象
*/
public function show(Request $request, string $merchantId): Response
{
$data = $this->validated(['merchant_id' => (int) $merchantId], MerchantPolicyValidator::class, 'show');
@@ -38,6 +59,12 @@ class MerchantPolicyController extends BaseController
return $this->success($this->merchantPolicyService->findByMerchantId((int) $data['merchant_id']));
}
/**
* 新增商户策略。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function store(Request $request): Response
{
$data = $this->validated($request->all(), MerchantPolicyValidator::class, 'store');
@@ -45,6 +72,13 @@ class MerchantPolicyController extends BaseController
return $this->success($this->merchantPolicyService->saveByMerchantId((int) $data['merchant_id'], $data));
}
/**
* 更新商户策略。
*
* @param Request $request 请求对象
* @param string $merchantId 商户ID
* @return Response 响应对象
*/
public function update(Request $request, string $merchantId): Response
{
$data = $this->validated(
@@ -56,6 +90,13 @@ class MerchantPolicyController extends BaseController
return $this->success($this->merchantPolicyService->saveByMerchantId((int) $data['merchant_id'], $data));
}
/**
* 删除商户策略。
*
* @param Request $request 请求对象
* @param string $merchantId 商户ID
* @return Response 响应对象
*/
public function destroy(Request $request, string $merchantId): Response
{
$data = $this->validated(['merchant_id' => (int) $merchantId], MerchantPolicyValidator::class, 'show');
@@ -64,3 +105,8 @@ class MerchantPolicyController extends BaseController
}
}

View File

@@ -10,11 +10,16 @@ use support\Response;
/**
* 通道日统计控制器。
*
* @property ChannelDailyStatService $channelDailyStatService 渠道日统计服务
*/
class ChannelDailyStatController extends BaseController
{
/**
* 构造函数,注入通道日统计服务
* 构造方法
*
* @param ChannelDailyStatService $channelDailyStatService 渠道日统计服务
* @return void
*/
public function __construct(
protected ChannelDailyStatService $channelDailyStatService
@@ -23,6 +28,9 @@ class ChannelDailyStatController extends BaseController
/**
* 查询通道日统计列表。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
@@ -39,6 +47,10 @@ class ChannelDailyStatController extends BaseController
/**
* 查询通道日统计详情。
*
* @param Request $request 请求对象
* @param string $id 渠道日统计ID
* @return Response 响应对象
*/
public function show(Request $request, string $id): Response
{
@@ -52,3 +64,8 @@ class ChannelDailyStatController extends BaseController
return $this->success($stat);
}
}

View File

@@ -10,11 +10,16 @@ use support\Response;
/**
* 渠道通知日志控制器。
*
* @property ChannelNotifyLogService $channelNotifyLogService 渠道通知日志服务
*/
class ChannelNotifyLogController extends BaseController
{
/**
* 构造函数,注入渠道通知日志服务
* 构造方法
*
* @param ChannelNotifyLogService $channelNotifyLogService 渠道通知日志服务
* @return void
*/
public function __construct(
protected ChannelNotifyLogService $channelNotifyLogService
@@ -23,6 +28,9 @@ class ChannelNotifyLogController extends BaseController
/**
* 查询渠道通知日志列表。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
@@ -39,6 +47,10 @@ class ChannelNotifyLogController extends BaseController
/**
* 查询渠道通知日志详情。
*
* @param Request $request 请求对象
* @param string $id 渠道通知日志ID
* @return Response 响应对象
*/
public function show(Request $request, string $id): Response
{
@@ -52,3 +64,8 @@ class ChannelNotifyLogController extends BaseController
return $this->success($log);
}
}

View File

@@ -10,11 +10,16 @@ use support\Response;
/**
* 支付回调日志控制器。
*
* @property PayCallbackLogService $payCallbackLogService 支付回调日志服务
*/
class PayCallbackLogController extends BaseController
{
/**
* 构造函数,注入支付回调日志服务
* 构造方法
*
* @param PayCallbackLogService $payCallbackLogService 支付回调日志服务
* @return void
*/
public function __construct(
protected PayCallbackLogService $payCallbackLogService
@@ -23,6 +28,9 @@ class PayCallbackLogController extends BaseController
/**
* 查询支付回调日志列表。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
@@ -39,6 +47,10 @@ class PayCallbackLogController extends BaseController
/**
* 查询支付回调日志详情。
*
* @param Request $request 请求对象
* @param string $id 支付回调日志ID
* @return Response 响应对象
*/
public function show(Request $request, string $id): Response
{
@@ -52,3 +64,8 @@ class PayCallbackLogController extends BaseController
return $this->success($log);
}
}

View File

@@ -12,11 +12,16 @@ use support\Response;
* 支付通道管理控制器。
*
* 负责支付通道的列表、详情、新增、修改和删除。
*
* @property PaymentChannelService $paymentChannelService 支付渠道服务
*/
class PaymentChannelController extends BaseController
{
/**
* 构造函数,注入支付通道服务
* 构造方法
*
* @param PaymentChannelService $paymentChannelService 支付渠道服务
* @return void
*/
public function __construct(
protected PaymentChannelService $paymentChannelService
@@ -24,9 +29,10 @@ class PaymentChannelController extends BaseController
}
/**
* GET /admin/payment-channels
*
* 查询支付通道列表。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
@@ -42,9 +48,11 @@ class PaymentChannelController extends BaseController
}
/**
* GET /admin/payment-channels/{id}
*
* 查询支付通道详情。
*
* @param Request $request 请求对象
* @param string $id 支付渠道ID
* @return Response 响应对象
*/
public function show(Request $request, string $id): Response
{
@@ -59,9 +67,10 @@ class PaymentChannelController extends BaseController
}
/**
* POST /admin/payment-channels
*
* 新增支付通道。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function store(Request $request): Response
{
@@ -71,9 +80,11 @@ class PaymentChannelController extends BaseController
}
/**
* PUT /admin/payment-channels/{id}
*
* 修改支付通道。
*
* @param Request $request 请求对象
* @param string $id 支付渠道ID
* @return Response 响应对象
*/
public function update(Request $request, string $id): Response
{
@@ -94,9 +105,11 @@ class PaymentChannelController extends BaseController
}
/**
* DELETE /admin/payment-channels/{id}
*
* 删除支付通道。
*
* @param Request $request 请求对象
* @param string $id 支付渠道ID
* @return Response 响应对象
*/
public function destroy(Request $request, string $id): Response
{
@@ -111,6 +124,9 @@ class PaymentChannelController extends BaseController
/**
* 查询启用中的通道选项。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function options(Request $request): Response
{
@@ -119,6 +135,9 @@ class PaymentChannelController extends BaseController
/**
* 查询路由编排场景下的通道选项。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function routeOptions(Request $request): Response
{
@@ -127,6 +146,9 @@ class PaymentChannelController extends BaseController
/**
* 远程查询支付通道选择项。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function selectOptions(Request $request): Response
{
@@ -136,3 +158,8 @@ class PaymentChannelController extends BaseController
return $this->success($this->paymentChannelService->searchOptions($request->all(), $page, $pageSize));
}
}

View File

@@ -12,14 +12,28 @@ use support\Response;
* 支付插件配置控制器。
*
* 负责插件公共配置的列表、详情、增删改和选项输出。
*
* @property PaymentPluginConfService $paymentPluginConfService 支付插件配置服务
*/
class PaymentPluginConfController extends BaseController
{
/**
* 构造方法。
*
* @param PaymentPluginConfService $paymentPluginConfService 支付插件配置服务
* @return void
*/
public function __construct(
protected PaymentPluginConfService $paymentPluginConfService
) {
}
/**
* 查询支付插件配置列表。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
$data = $this->validated($request->all(), PaymentPluginConfValidator::class, 'index');
@@ -29,6 +43,13 @@ class PaymentPluginConfController extends BaseController
return $this->page($this->paymentPluginConfService->paginate($data, $page, $pageSize));
}
/**
* 查询支付插件配置详情。
*
* @param Request $request 请求对象
* @param string $id 支付插件配置ID
* @return Response 响应对象
*/
public function show(Request $request, string $id): Response
{
$data = $this->validated(['id' => (int) $id], PaymentPluginConfValidator::class, 'show');
@@ -41,6 +62,12 @@ class PaymentPluginConfController extends BaseController
return $this->success($pluginConf);
}
/**
* 新增支付插件配置。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function store(Request $request): Response
{
$data = $this->validated($request->all(), PaymentPluginConfValidator::class, 'store');
@@ -48,6 +75,13 @@ class PaymentPluginConfController extends BaseController
return $this->success($this->paymentPluginConfService->create($data));
}
/**
* 更新支付插件配置。
*
* @param Request $request 请求对象
* @param string $id 支付插件配置ID
* @return Response 响应对象
*/
public function update(Request $request, string $id): Response
{
$data = $this->validated(
@@ -64,6 +98,13 @@ class PaymentPluginConfController extends BaseController
return $this->success($pluginConf);
}
/**
* 删除支付插件配置。
*
* @param Request $request 请求对象
* @param string $id 支付插件配置ID
* @return Response 响应对象
*/
public function destroy(Request $request, string $id): Response
{
$data = $this->validated(['id' => (int) $id], PaymentPluginConfValidator::class, 'destroy');
@@ -75,6 +116,12 @@ class PaymentPluginConfController extends BaseController
return $this->success(true);
}
/**
* 获取支付插件配置选项。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function options(Request $request): Response
{
$data = $this->validated($request->all(), PaymentPluginConfValidator::class, 'options');
@@ -86,6 +133,9 @@ class PaymentPluginConfController extends BaseController
/**
* 远程查询插件配置选项。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function selectOptions(Request $request): Response
{
@@ -96,3 +146,8 @@ class PaymentPluginConfController extends BaseController
return $this->success($this->paymentPluginConfService->searchOptions($data, $page, $pageSize));
}
}

View File

@@ -12,11 +12,16 @@ use support\Response;
* 支付插件管理控制器。
*
* 负责插件字典的列表、详情、刷新同步和状态备注维护。
*
* @property PaymentPluginService $paymentPluginService 支付插件服务
*/
class PaymentPluginController extends BaseController
{
/**
* 构造函数,注入支付插件服务
* 构造方法
*
* @param PaymentPluginService $paymentPluginService 支付插件服务
* @return void
*/
public function __construct(
protected PaymentPluginService $paymentPluginService
@@ -25,6 +30,9 @@ class PaymentPluginController extends BaseController
/**
* 查询支付插件列表。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
@@ -37,6 +45,10 @@ class PaymentPluginController extends BaseController
/**
* 查询支付插件详情。
*
* @param Request $request 请求对象
* @param string $code 编码
* @return Response 响应对象
*/
public function show(Request $request, string $code): Response
{
@@ -52,6 +64,10 @@ class PaymentPluginController extends BaseController
/**
* 修改支付插件。
*
* @param Request $request 请求对象
* @param string $code 编码
* @return Response 响应对象
*/
public function update(Request $request, string $code): Response
{
@@ -73,6 +89,9 @@ class PaymentPluginController extends BaseController
/**
* 从插件目录刷新同步支付插件。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function refresh(Request $request): Response
{
@@ -81,6 +100,9 @@ class PaymentPluginController extends BaseController
/**
* 查询支付插件下拉选项。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function options(Request $request): Response
{
@@ -91,6 +113,9 @@ class PaymentPluginController extends BaseController
/**
* 远程查询支付插件选项。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function selectOptions(Request $request): Response
{
@@ -103,6 +128,9 @@ class PaymentPluginController extends BaseController
/**
* 查询通道配置场景下的插件选项。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function channelOptions(Request $request): Response
{
@@ -113,6 +141,10 @@ class PaymentPluginController extends BaseController
/**
* 查询插件配置结构。
*
* @param Request $request 请求对象
* @param string $code 编码
* @return Response 响应对象
*/
public function schema(Request $request, string $code): Response
{
@@ -121,3 +153,8 @@ class PaymentPluginController extends BaseController
return $this->success($this->paymentPluginService->getSchema((string) $data['code']));
}
}

View File

@@ -10,14 +10,28 @@ use support\Response;
/**
* 商户分组路由绑定控制器。
*
* @property PaymentPollGroupBindService $paymentPollGroupBindService 支付轮询分组绑定服务
*/
class PaymentPollGroupBindController extends BaseController
{
/**
* 构造方法。
*
* @param PaymentPollGroupBindService $paymentPollGroupBindService 支付轮询分组绑定服务
* @return void
*/
public function __construct(
protected PaymentPollGroupBindService $paymentPollGroupBindService
) {
}
/**
* 查询支付轮询分组绑定列表
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
$data = $this->validated($request->all(), PaymentPollGroupBindValidator::class, 'index');
@@ -31,6 +45,13 @@ class PaymentPollGroupBindController extends BaseController
);
}
/**
* 查询支付轮询分组绑定详情
*
* @param Request $request 请求对象
* @param string $id 支付轮询分组绑定ID
* @return Response 响应对象
*/
public function show(Request $request, string $id): Response
{
$data = $this->validated(['id' => (int) $id], PaymentPollGroupBindValidator::class, 'show');
@@ -42,6 +63,12 @@ class PaymentPollGroupBindController extends BaseController
return $this->success($row);
}
/**
* 新增支付轮询分组绑定
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function store(Request $request): Response
{
$data = $this->validated($request->all(), PaymentPollGroupBindValidator::class, 'store');
@@ -49,6 +76,13 @@ class PaymentPollGroupBindController extends BaseController
return $this->success($this->paymentPollGroupBindService->create($data));
}
/**
* 更新支付轮询分组绑定
*
* @param Request $request 请求对象
* @param string $id 支付轮询分组绑定ID
* @return Response 响应对象
*/
public function update(Request $request, string $id): Response
{
$data = $this->validated(
@@ -65,6 +99,13 @@ class PaymentPollGroupBindController extends BaseController
return $this->success($row);
}
/**
* 删除支付轮询分组绑定
*
* @param Request $request 请求对象
* @param string $id 支付轮询分组绑定ID
* @return Response 响应对象
*/
public function destroy(Request $request, string $id): Response
{
$data = $this->validated(['id' => (int) $id], PaymentPollGroupBindValidator::class, 'destroy');
@@ -75,3 +116,8 @@ class PaymentPollGroupBindController extends BaseController
return $this->success(true);
}
}

View File

@@ -10,14 +10,28 @@ use support\Response;
/**
* 轮询组通道编排控制器。
*
* @property PaymentPollGroupChannelService $paymentPollGroupChannelService 支付轮询分组渠道服务
*/
class PaymentPollGroupChannelController extends BaseController
{
/**
* 构造方法。
*
* @param PaymentPollGroupChannelService $paymentPollGroupChannelService 支付轮询分组渠道服务
* @return void
*/
public function __construct(
protected PaymentPollGroupChannelService $paymentPollGroupChannelService
) {
}
/**
* 查询支付轮询分组渠道列表
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
$data = $this->validated($request->all(), PaymentPollGroupChannelValidator::class, 'index');
@@ -31,6 +45,13 @@ class PaymentPollGroupChannelController extends BaseController
);
}
/**
* 查询支付轮询分组渠道详情
*
* @param Request $request 请求对象
* @param string $id 支付轮询分组渠道ID
* @return Response 响应对象
*/
public function show(Request $request, string $id): Response
{
$data = $this->validated(['id' => (int) $id], PaymentPollGroupChannelValidator::class, 'show');
@@ -42,6 +63,12 @@ class PaymentPollGroupChannelController extends BaseController
return $this->success($row);
}
/**
* 新增支付轮询分组渠道
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function store(Request $request): Response
{
$data = $this->validated($request->all(), PaymentPollGroupChannelValidator::class, 'store');
@@ -49,6 +76,13 @@ class PaymentPollGroupChannelController extends BaseController
return $this->success($this->paymentPollGroupChannelService->create($data));
}
/**
* 更新支付轮询分组渠道
*
* @param Request $request 请求对象
* @param string $id 支付轮询分组渠道ID
* @return Response 响应对象
*/
public function update(Request $request, string $id): Response
{
$payload = $request->all();
@@ -67,6 +101,13 @@ class PaymentPollGroupChannelController extends BaseController
return $this->success($row);
}
/**
* 删除支付轮询分组渠道
*
* @param Request $request 请求对象
* @param string $id 支付轮询分组渠道ID
* @return Response 响应对象
*/
public function destroy(Request $request, string $id): Response
{
$data = $this->validated(['id' => (int) $id], PaymentPollGroupChannelValidator::class, 'destroy');
@@ -77,3 +118,8 @@ class PaymentPollGroupChannelController extends BaseController
return $this->success(true);
}
}

View File

@@ -12,11 +12,16 @@ use support\Response;
* 支付轮询组管理控制器。
*
* 负责轮询组的列表、详情、新增、修改和删除。
*
* @property PaymentPollGroupService $paymentPollGroupService 支付轮询分组服务
*/
class PaymentPollGroupController extends BaseController
{
/**
* 构造函数,注入轮询组服务
* 构造方法
*
* @param PaymentPollGroupService $paymentPollGroupService 支付轮询分组服务
* @return void
*/
public function __construct(
protected PaymentPollGroupService $paymentPollGroupService
@@ -24,9 +29,10 @@ class PaymentPollGroupController extends BaseController
}
/**
* GET /admin/payment-poll-groups
*
* 查询轮询组列表。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
@@ -42,9 +48,11 @@ class PaymentPollGroupController extends BaseController
}
/**
* GET /admin/payment-poll-groups/{id}
*
* 查询轮询组详情。
*
* @param Request $request 请求对象
* @param string $id 支付轮询分组ID
* @return Response 响应对象
*/
public function show(Request $request, string $id): Response
{
@@ -59,9 +67,10 @@ class PaymentPollGroupController extends BaseController
}
/**
* POST /admin/payment-poll-groups
*
* 新增轮询组。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function store(Request $request): Response
{
@@ -71,9 +80,11 @@ class PaymentPollGroupController extends BaseController
}
/**
* PUT /admin/payment-poll-groups/{id}
*
* 修改轮询组。
*
* @param Request $request 请求对象
* @param string $id 支付轮询分组ID
* @return Response 响应对象
*/
public function update(Request $request, string $id): Response
{
@@ -94,9 +105,11 @@ class PaymentPollGroupController extends BaseController
}
/**
* DELETE /admin/payment-poll-groups/{id}
*
* 删除轮询组。
*
* @param Request $request 请求对象
* @param string $id 支付轮询分组ID
* @return Response 响应对象
*/
public function destroy(Request $request, string $id): Response
{
@@ -111,9 +124,17 @@ class PaymentPollGroupController extends BaseController
/**
* 查询轮询组下拉选项。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function options(Request $request): Response
{
return $this->success($this->paymentPollGroupService->enabledOptions($request->all()));
}
}

View File

@@ -12,11 +12,16 @@ use support\Response;
* 支付方式管理控制器。
*
* 负责支付方式字典的列表、详情、新增、修改、删除和选项输出。
*
* @property PaymentTypeService $paymentTypeService 支付类型服务
*/
class PaymentTypeController extends BaseController
{
/**
* 构造函数,注入支付方式服务
* 构造方法
*
* @param PaymentTypeService $paymentTypeService 支付类型服务
* @return void
*/
public function __construct(
protected PaymentTypeService $paymentTypeService
@@ -25,6 +30,9 @@ class PaymentTypeController extends BaseController
/**
* 查询支付方式列表。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
@@ -37,6 +45,10 @@ class PaymentTypeController extends BaseController
/**
* 查询支付方式详情。
*
* @param Request $request 请求对象
* @param string $id 支付类型ID
* @return Response 响应对象
*/
public function show(Request $request, string $id): Response
{
@@ -52,6 +64,9 @@ class PaymentTypeController extends BaseController
/**
* 新增支付方式。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function store(Request $request): Response
{
@@ -62,6 +77,10 @@ class PaymentTypeController extends BaseController
/**
* 修改支付方式。
*
* @param Request $request 请求对象
* @param string $id 支付类型ID
* @return Response 响应对象
*/
public function update(Request $request, string $id): Response
{
@@ -83,6 +102,10 @@ class PaymentTypeController extends BaseController
/**
* 删除支付方式。
*
* @param Request $request 请求对象
* @param string $id 支付类型ID
* @return Response 响应对象
*/
public function destroy(Request $request, string $id): Response
{
@@ -97,9 +120,17 @@ class PaymentTypeController extends BaseController
/**
* 查询支付方式下拉选项。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function options(Request $request): Response
{
return $this->success($this->paymentTypeService->enabledOptions());
}
}

View File

@@ -9,14 +9,19 @@ use support\Request;
use support\Response;
/**
* 管理后台路由预览控制器。
* 管理后台路由解析控制器。
*
* 负责按商户分组、支付方式和金额条件解析可用通道。
*
* @property PaymentRouteService $paymentRouteService 支付路由服务
*/
class RouteController extends BaseController
{
/**
* 构造函数,注入路由服务
* 构造方法
*
* @param PaymentRouteService $paymentRouteService 支付路由服务
* @return void
*/
public function __construct(
protected PaymentRouteService $paymentRouteService
@@ -24,9 +29,10 @@ class RouteController extends BaseController
}
/**
* GET /admin/routes/resolve
*
* 解析路由结果。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function resolve(Request $request): Response
{
@@ -41,3 +47,8 @@ class RouteController extends BaseController
}
}

View File

@@ -12,11 +12,16 @@ use support\Response;
* 管理员用户管理控制器。
*
* 负责管理员账号的列表、详情、新增、修改和删除。
*
* @property AdminUserService $adminUserService 管理用户服务
*/
class AdminUserController extends BaseController
{
/**
* 构造函数,注入管理员用户服务
* 构造方法
*
* @param AdminUserService $adminUserService 管理用户服务
* @return void
*/
public function __construct(
protected AdminUserService $adminUserService
@@ -24,9 +29,10 @@ class AdminUserController extends BaseController
}
/**
* GET /adminapi/admin-users
*
* 查询管理员用户列表。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
@@ -42,9 +48,11 @@ class AdminUserController extends BaseController
}
/**
* GET /adminapi/admin-users/{id}
*
* 查询管理员用户详情。
*
* @param Request $request 请求对象
* @param string $id 管理用户ID
* @return Response 响应对象
*/
public function show(Request $request, string $id): Response
{
@@ -59,9 +67,10 @@ class AdminUserController extends BaseController
}
/**
* POST /adminapi/admin-users
*
* 新增管理员用户。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function store(Request $request): Response
{
@@ -71,9 +80,11 @@ class AdminUserController extends BaseController
}
/**
* PUT /adminapi/admin-users/{id}
*
* 修改管理员用户。
*
* @param Request $request 请求对象
* @param string $id 管理用户ID
* @return Response 响应对象
*/
public function update(Request $request, string $id): Response
{
@@ -92,9 +103,11 @@ class AdminUserController extends BaseController
}
/**
* DELETE /adminapi/admin-users/{id}
*
* 删除管理员用户。
*
* @param Request $request 请求对象
* @param string $id 管理用户ID
* @return Response 响应对象
*/
public function destroy(Request $request, string $id): Response
{
@@ -120,3 +133,8 @@ class AdminUserController extends BaseController
return $this->success(true);
}
}

View File

@@ -11,15 +11,31 @@ use support\Response;
/**
* 管理员认证控制器。
*
* @property AdminAuthService $adminAuthService 管理认证服务
* @property AdminUserService $adminUserService 管理用户服务
*/
class AuthController extends BaseController
{
/**
* 构造方法。
*
* @param AdminAuthService $adminAuthService 管理认证服务
* @param AdminUserService $adminUserService 管理用户服务
* @return void
*/
public function __construct(
protected AdminAuthService $adminAuthService,
protected AdminUserService $adminUserService
) {
}
/**
* 管理员登录。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function login(Request $request): Response
{
$data = $this->validated($request->all(), AuthValidator::class, 'login');
@@ -32,6 +48,12 @@ class AuthController extends BaseController
));
}
/**
* 管理员退出登录。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function logout(Request $request): Response
{
$token = trim((string) ($request->header('authorization', '') ?: $request->header('x-admin-token', '')));
@@ -47,7 +69,10 @@ class AuthController extends BaseController
}
/**
* 获取当前登录管理员信息
* 获取当前登录管理员信息
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function profile(Request $request): Response
{
@@ -63,3 +88,8 @@ class AuthController extends BaseController
}
}

View File

@@ -8,18 +8,42 @@ use app\service\system\config\SystemConfigPageService;
use support\Request;
use support\Response;
/**
* 系统配置页面控制器
*
* @property SystemConfigPageService $systemConfigPageService 系统配置页面服务
*/
class SystemConfigPageController extends BaseController
{
/**
* 构造方法。
*
* @param SystemConfigPageService $systemConfigPageService 系统配置页面服务
* @return void
*/
public function __construct(
protected SystemConfigPageService $systemConfigPageService
) {
}
/**
* 查询系统配置页面列表
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
return $this->success($this->systemConfigPageService->tabs());
}
/**
* 查询系统配置页面详情
*
* @param Request $request 请求对象
* @param string $groupCode 分组Code
* @return Response 响应对象
*/
public function show(Request $request, string $groupCode): Response
{
$data = $this->validated(['group_code' => $groupCode], SystemConfigPageValidator::class, 'show');
@@ -27,6 +51,13 @@ class SystemConfigPageController extends BaseController
return $this->success($this->systemConfigPageService->detail((string) $data['group_code']));
}
/**
* 新增系统配置页面
*
* @param Request $request 请求对象
* @param string $groupCode 分组Code
* @return Response 响应对象
*/
public function store(Request $request, string $groupCode): Response
{
$data = $this->validated(
@@ -40,3 +71,8 @@ class SystemConfigPageController extends BaseController
);
}
}

View File

@@ -9,22 +9,47 @@ use support\Response;
/**
* 管理后台系统数据控制器。
*
* @property SystemBootstrapService $systemBootstrapService 系统引导服务
*/
class SystemController extends BaseController
{
/**
* 构造方法。
*
* @param SystemBootstrapService $systemBootstrapService 系统引导服务
* @return void
*/
public function __construct(
protected SystemBootstrapService $systemBootstrapService
) {
}
/**
* 获取系统菜单树
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function menuTree(Request $request): Response
{
return $this->success($this->systemBootstrapService->getMenuTree('admin'));
}
/**
* 获取系统字典项
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function dictItems(Request $request): Response
{
return $this->success($this->systemBootstrapService->getDictItems((string) $request->get('code', '')));
}
}

View File

@@ -12,11 +12,16 @@ use support\Response;
* 支付订单管理控制器。
*
* 当前先提供列表查询,后续可以继续扩展支付单详情、关闭、重试等管理操作。
*
* @property PayOrderService $payOrderService 支付订单服务
*/
class PayOrderController extends BaseController
{
/**
* 构造函数,注入支付订单服务
* 构造方法
*
* @param PayOrderService $payOrderService 支付订单服务
* @return void
*/
public function __construct(
protected PayOrderService $payOrderService
@@ -25,6 +30,9 @@ class PayOrderController extends BaseController
/**
* 查询支付订单列表。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
@@ -36,3 +44,8 @@ class PayOrderController extends BaseController
}
}

View File

@@ -11,9 +11,17 @@ use support\Response;
/**
* 退款订单管理控制器。
*
* @property RefundService $refundService 退款服务
*/
class RefundOrderController extends BaseController
{
/**
* 构造方法。
*
* @param RefundService $refundService 退款服务
* @return void
*/
public function __construct(
protected RefundService $refundService
) {
@@ -21,6 +29,9 @@ class RefundOrderController extends BaseController
/**
* 查询退款订单列表。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
@@ -33,6 +44,10 @@ class RefundOrderController extends BaseController
/**
* 查询退款订单详情。
*
* @param Request $request 请求对象
* @param string $refundNo 退款单号
* @return Response 响应对象
*/
public function show(Request $request, string $refundNo): Response
{
@@ -41,6 +56,10 @@ class RefundOrderController extends BaseController
/**
* 重试退款。
*
* @param Request $request 请求对象
* @param string $refundNo 退款单号
* @return Response 响应对象
*/
public function retry(Request $request, string $refundNo): Response
{
@@ -54,3 +73,8 @@ class RefundOrderController extends BaseController
}
}

View File

@@ -11,11 +11,16 @@ use support\Response;
/**
* 清算订单控制器。
*
* @property SettlementOrderQueryService $settlementOrderQueryService 结算订单查询服务
*/
class SettlementOrderController extends BaseController
{
/**
* 构造函数,注入清算订单服务
* 构造方法
*
* @param SettlementOrderQueryService $settlementOrderQueryService 结算订单查询服务
* @return void
*/
public function __construct(
protected SettlementOrderQueryService $settlementOrderQueryService
@@ -24,6 +29,9 @@ class SettlementOrderController extends BaseController
/**
* 查询清算订单列表。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function index(Request $request): Response
{
@@ -40,6 +48,10 @@ class SettlementOrderController extends BaseController
/**
* 查询清算订单详情。
*
* @param Request $request 请求对象
* @param string $settleNo 结算单号
* @return Response 响应对象
*/
public function show(Request $request, string $settleNo): Response
{
@@ -51,3 +63,8 @@ class SettlementOrderController extends BaseController
}
}
}

View File

@@ -12,11 +12,16 @@ use Webman\MiddlewareInterface;
* 管理员认证中间件。
*
* 负责读取管理员 token并把管理员身份写入请求上下文。
*
* @property AdminAuthService $adminAuthService 管理认证服务
*/
class AdminAuthMiddleware implements MiddlewareInterface
{
/**
* 构造函数,注入对应依赖
* 构造方法
*
* @param AdminAuthService $adminAuthService 管理认证服务
* @return void
*/
public function __construct(
protected AdminAuthService $adminAuthService
@@ -25,6 +30,10 @@ class AdminAuthMiddleware implements MiddlewareInterface
/**
* 处理请求。
*
* @param Request $request 请求对象
* @param callable $handler handler
* @return Response 响应对象
*/
public function process(Request $request, callable $handler): Response
{
@@ -60,3 +69,8 @@ class AdminAuthMiddleware implements MiddlewareInterface
return $handler($request);
}
}

View File

@@ -9,6 +9,11 @@ use support\validation\Validator;
*/
class AdminUserValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'id' => 'sometimes|integer|min:1',
'keyword' => 'sometimes|string|max:128',
@@ -24,6 +29,11 @@ class AdminUserValidator extends Validator
'page_size' => 'sometimes|integer|min:1|max:100',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'id' => '管理员ID',
'keyword' => '关键词',
@@ -33,12 +43,17 @@ class AdminUserValidator extends Validator
'mobile' => '手机号',
'email' => '邮箱',
'is_super' => '超级管理员',
'status' => '状态',
'status' => '管理员状态',
'remark' => '备注',
'page' => '页码',
'page_size' => '每页条数',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'status', 'is_super', 'page', 'page_size'],
'store' => ['username', 'password', 'real_name', 'mobile', 'email', 'is_super', 'status', 'remark'],
@@ -47,6 +62,11 @@ class AdminUserValidator extends Validator
'destroy' => ['id'],
];
/**
* 配置新增管理员场景规则。
*
* @return static 校验器实例
*/
public function sceneStore(): static
{
return $this->appendRules([
@@ -58,6 +78,11 @@ class AdminUserValidator extends Validator
]);
}
/**
* 配置更新管理员场景规则。
*
* @return static 校验器实例
*/
public function sceneUpdate(): static
{
return $this->appendRules([
@@ -69,6 +94,11 @@ class AdminUserValidator extends Validator
]);
}
/**
* 配置管理员详情场景规则。
*
* @return static 校验器实例
*/
public function sceneShow(): static
{
return $this->appendRules([
@@ -76,8 +106,14 @@ class AdminUserValidator extends Validator
]);
}
/**
* 配置删除管理员场景规则。
*
* @return static 校验器实例
*/
public function sceneDestroy(): static
{
return $this->sceneShow();
}
}

View File

@@ -11,17 +11,34 @@ use support\validation\Validator;
*/
class AuthValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'username' => 'required|string|min:1|max:32',
'password' => 'required|string|min:6|max:100',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'username' => '用户名',
'password' => '密码',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'login' => ['username', 'password'],
];
}

View File

@@ -9,6 +9,11 @@ use support\validation\Validator;
*/
class ChannelDailyStatValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'id' => 'required|integer|min:1',
'keyword' => 'sometimes|string|max:128',
@@ -19,6 +24,11 @@ class ChannelDailyStatValidator extends Validator
'page_size' => 'sometimes|integer|min:1|max:100',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'id' => '统计ID',
'keyword' => '关键词',
@@ -29,8 +39,15 @@ class ChannelDailyStatValidator extends Validator
'page_size' => '每页条数',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'merchant_id', 'channel_id', 'stat_date', 'page', 'page_size'],
'show' => ['id'],
];
}

View File

@@ -9,6 +9,11 @@ use support\validation\Validator;
*/
class ChannelNotifyLogValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'id' => 'required|integer|min:1',
'keyword' => 'sometimes|string|max:128',
@@ -21,6 +26,11 @@ class ChannelNotifyLogValidator extends Validator
'page_size' => 'sometimes|integer|min:1|max:100',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'id' => '日志ID',
'keyword' => '关键词',
@@ -33,8 +43,15 @@ class ChannelNotifyLogValidator extends Validator
'page_size' => '每页条数',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'merchant_id', 'channel_id', 'notify_type', 'verify_status', 'process_status', 'page', 'page_size'],
'show' => ['id'],
];
}

View File

@@ -9,6 +9,11 @@ use support\validation\Validator;
*/
class FileRecordValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'id' => 'sometimes|integer|min:1',
'keyword' => 'sometimes|string|max:128',
@@ -21,6 +26,11 @@ class FileRecordValidator extends Validator
'page_size' => 'sometimes|integer|min:1|max:100',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'id' => '文件ID',
'keyword' => '关键字',
@@ -33,13 +43,20 @@ class FileRecordValidator extends Validator
'page_size' => '每页条数',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'scene', 'source_type', 'visibility', 'storage_engine', 'page', 'page_size'],
'show' => ['id'],
'destroy' => ['id'],
'preview' => ['id'],
'download' => ['id'],
'store' => ['scene', 'visibility'],
'importRemote' => ['remote_url', 'scene', 'visibility'],
'store' => ['scene', 'visibility', 'storage_engine'],
'importRemote' => ['remote_url', 'scene', 'visibility', 'storage_engine'],
];
}

View File

@@ -9,6 +9,11 @@ use support\validation\Validator;
*/
class MerchantAccountLedgerValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'id' => 'required|integer|min:1',
'keyword' => 'sometimes|string|max:128',
@@ -20,6 +25,11 @@ class MerchantAccountLedgerValidator extends Validator
'page_size' => 'sometimes|integer|min:1|max:100',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'id' => '流水ID',
'keyword' => '关键词',
@@ -31,8 +41,15 @@ class MerchantAccountLedgerValidator extends Validator
'page_size' => '每页条数',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'merchant_id', 'biz_type', 'event_type', 'direction', 'page', 'page_size'],
'show' => ['id'],
];
}

View File

@@ -9,6 +9,11 @@ use support\validation\Validator;
*/
class MerchantAccountValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'id' => 'required|integer|min:1',
'keyword' => 'sometimes|string|max:128',
@@ -17,6 +22,11 @@ class MerchantAccountValidator extends Validator
'page_size' => 'sometimes|integer|min:1|max:100',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'id' => '账户ID',
'keyword' => '关键词',
@@ -25,8 +35,15 @@ class MerchantAccountValidator extends Validator
'page_size' => '每页条数',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'merchant_id', 'page', 'page_size'],
'show' => ['id'],
];
}

View File

@@ -5,10 +5,15 @@ namespace app\http\admin\validation;
use support\validation\Validator;
/**
* 商户接口凭证参数校验器。
* 商户 API 凭证参数校验器。
*/
class MerchantApiCredentialValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'id' => 'sometimes|integer|min:1',
'keyword' => 'sometimes|string|max:128',
@@ -20,17 +25,27 @@ class MerchantApiCredentialValidator extends Validator
'page_size' => 'sometimes|integer|min:1|max:100',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'id' => '凭证ID',
'keyword' => '关键词',
'merchant_id' => '所属商户',
'sign_type' => '签名类型',
'api_key' => '接口凭证值',
'status' => '状态',
'status' => '接口凭证状态',
'page' => '页码',
'page_size' => '每页条数',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'merchant_id', 'status', 'page', 'page_size'],
'store' => ['merchant_id', 'sign_type', 'api_key', 'status'],
@@ -39,6 +54,11 @@ class MerchantApiCredentialValidator extends Validator
'destroy' => ['id'],
];
/**
* 配置新增接口凭证场景规则。
*
* @return static 校验器实例
*/
public function sceneStore(): static
{
return $this->appendRules([
@@ -48,6 +68,11 @@ class MerchantApiCredentialValidator extends Validator
]);
}
/**
* 配置更新接口凭证场景规则。
*
* @return static 校验器实例
*/
public function sceneUpdate(): static
{
return $this->appendRules([
@@ -57,6 +82,11 @@ class MerchantApiCredentialValidator extends Validator
]);
}
/**
* 配置接口凭证详情场景规则。
*
* @return static 校验器实例
*/
public function sceneShow(): static
{
return $this->appendRules([
@@ -64,6 +94,11 @@ class MerchantApiCredentialValidator extends Validator
]);
}
/**
* 配置删除接口凭证场景规则。
*
* @return static 校验器实例
*/
public function sceneDestroy(): static
{
return $this->sceneShow();

View File

@@ -11,6 +11,11 @@ use support\validation\Validator;
*/
class MerchantGroupValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'id' => 'sometimes|integer|min:1',
'keyword' => 'sometimes|string|max:128',
@@ -21,16 +26,26 @@ class MerchantGroupValidator extends Validator
'page_size' => 'sometimes|integer|min:1|max:100',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'id' => '分组ID',
'keyword' => '关键字',
'group_name' => '分组名称',
'status' => '状态',
'status' => '分组状态',
'remark' => '备注',
'page' => '页码',
'page_size' => '每页条数',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'group_name', 'status', 'page', 'page_size'],
'store' => ['group_name', 'status', 'remark'],
@@ -39,6 +54,11 @@ class MerchantGroupValidator extends Validator
'destroy' => ['id'],
];
/**
* 配置新增商户分组场景规则。
*
* @return static 校验器实例
*/
public function sceneStore(): static
{
return $this->appendRules([
@@ -47,6 +67,11 @@ class MerchantGroupValidator extends Validator
]);
}
/**
* 配置更新商户分组场景规则。
*
* @return static 校验器实例
*/
public function sceneUpdate(): static
{
return $this->appendRules([
@@ -56,6 +81,11 @@ class MerchantGroupValidator extends Validator
]);
}
/**
* 配置商户分组详情场景规则。
*
* @return static 校验器实例
*/
public function sceneShow(): static
{
return $this->appendRules([
@@ -63,8 +93,16 @@ class MerchantGroupValidator extends Validator
]);
}
/**
* 配置删除商户分组场景规则。
*
* @return static 校验器实例
*/
public function sceneDestroy(): static
{
return $this->sceneShow();
}
}

View File

@@ -9,6 +9,11 @@ use support\validation\Validator;
*/
class MerchantPolicyValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'id' => 'sometimes|integer|min:1',
'merchant_id' => 'sometimes|integer|min:1|exists:ma_merchant,id',
@@ -27,6 +32,11 @@ class MerchantPolicyValidator extends Validator
'page_size' => 'sometimes|integer|min:1|max:100',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'id' => '策略ID',
'merchant_id' => '所属商户',
@@ -45,6 +55,11 @@ class MerchantPolicyValidator extends Validator
'page_size' => '每页条数',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'merchant_id', 'group_id', 'has_policy', 'settlement_cycle_override', 'auto_payout', 'page', 'page_size'],
'show' => ['merchant_id'],
@@ -72,6 +87,11 @@ class MerchantPolicyValidator extends Validator
],
];
/**
* 配置新增商户策略场景规则。
*
* @return static 校验器实例
*/
public function sceneStore(): static
{
return $this->appendRules([
@@ -82,8 +102,15 @@ class MerchantPolicyValidator extends Validator
]);
}
/**
* 配置更新商户策略场景规则。
*
* @return static 校验器实例
*/
public function sceneUpdate(): static
{
return $this->sceneStore();
}
}

View File

@@ -11,6 +11,11 @@ use support\validation\Validator;
*/
class MerchantValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'id' => 'sometimes|integer|min:1',
'keyword' => 'sometimes|string|max:128',
@@ -35,11 +40,16 @@ class MerchantValidator extends Validator
'page_size' => 'sometimes|integer|min:1|max:100',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'id' => '商户ID',
'keyword' => '关键字',
'group_id' => '商户分组',
'status' => '状态',
'status' => '商户状态',
'merchant_type' => '商户类型',
'merchant_no' => '商户号',
'merchant_name' => '商户名称',
@@ -59,6 +69,11 @@ class MerchantValidator extends Validator
'page_size' => '每页条数',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'group_id', 'status', 'merchant_type', 'risk_level', 'page', 'page_size'],
'show' => ['id'],
@@ -101,6 +116,11 @@ class MerchantValidator extends Validator
'destroy' => ['id'],
];
/**
* 配置新增商户场景规则。
*
* @return static 校验器实例
*/
public function sceneStore(): static
{
return $this->appendRules([
@@ -114,6 +134,11 @@ class MerchantValidator extends Validator
]);
}
/**
* 配置更新商户场景规则。
*
* @return static 校验器实例
*/
public function sceneUpdate(): static
{
return $this->appendRules([
@@ -128,6 +153,11 @@ class MerchantValidator extends Validator
]);
}
/**
* 配置更新商户状态场景规则。
*
* @return static 校验器实例
*/
public function sceneUpdateStatus(): static
{
return $this->appendRules([
@@ -136,6 +166,11 @@ class MerchantValidator extends Validator
]);
}
/**
* 配置重置密码场景规则。
*
* @return static 校验器实例
*/
public function sceneResetPassword(): static
{
return $this->appendRules([
@@ -145,6 +180,11 @@ class MerchantValidator extends Validator
]);
}
/**
* 配置删除商户场景规则。
*
* @return static 校验器实例
*/
public function sceneDestroy(): static
{
return $this->appendRules([
@@ -152,3 +192,4 @@ class MerchantValidator extends Validator
]);
}
}

View File

@@ -9,6 +9,11 @@ use support\validation\Validator;
*/
class PayCallbackLogValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'id' => 'required|integer|min:1',
'keyword' => 'sometimes|string|max:128',
@@ -21,6 +26,11 @@ class PayCallbackLogValidator extends Validator
'page_size' => 'sometimes|integer|min:1|max:100',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'id' => '日志ID',
'keyword' => '关键词',
@@ -33,8 +43,15 @@ class PayCallbackLogValidator extends Validator
'page_size' => '每页条数',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'merchant_id', 'channel_id', 'callback_type', 'verify_status', 'process_status', 'page', 'page_size'],
'show' => ['id'],
];
}

View File

@@ -11,6 +11,11 @@ use support\validation\Validator;
*/
class PayOrderValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'keyword' => 'sometimes|string|max:128',
'merchant_id' => 'sometimes|integer|min:1',
@@ -22,18 +27,29 @@ class PayOrderValidator extends Validator
'page_size' => 'sometimes|integer|min:1|max:100',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'keyword' => '关键字',
'merchant_id' => '商户ID',
'pay_type_id' => '支付方式',
'status' => '状态',
'status' => '支付单状态',
'channel_mode' => '通道模式',
'callback_status' => '回调状态',
'callback_status' => '回调处理状态',
'page' => '页码',
'page_size' => '每页条数',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'merchant_id', 'pay_type_id', 'status', 'channel_mode', 'callback_status', 'page', 'page_size'],
];
}

View File

@@ -11,6 +11,11 @@ use support\validation\Validator;
*/
class PaymentChannelValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'id' => 'sometimes|integer|min:1',
'keyword' => 'sometimes|string|max:128',
@@ -33,6 +38,11 @@ class PaymentChannelValidator extends Validator
'page_size' => 'sometimes|integer|min:1|max:100',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'id' => '通道ID',
'keyword' => '关键字',
@@ -49,12 +59,17 @@ class PaymentChannelValidator extends Validator
'min_amount' => '最小金额',
'max_amount' => '最大金额',
'remark' => '备注',
'status' => '状态',
'status' => '通道状态',
'sort_no' => '排序',
'page' => '页码',
'page_size' => '每页条数',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'merchant_id', 'pay_type_id', 'plugin_code', 'channel_mode', 'status', 'page', 'page_size'],
'store' => ['merchant_id', 'name', 'split_rate_bp', 'cost_rate_bp', 'channel_mode', 'pay_type_id', 'plugin_code', 'api_config_id', 'daily_limit_amount', 'daily_limit_count', 'min_amount', 'max_amount', 'remark', 'status', 'sort_no'],
@@ -64,6 +79,11 @@ class PaymentChannelValidator extends Validator
'destroy' => ['id'],
];
/**
* 根据场景返回支付通道校验规则。
*
* @return array 校验规则
*/
public function rules(): array
{
$rules = parent::rules();
@@ -101,3 +121,6 @@ class PaymentChannelValidator extends Validator
};
}
}

View File

@@ -11,6 +11,11 @@ use support\validation\Validator;
*/
class PaymentPluginConfValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'id' => 'sometimes|integer|min:1',
'keyword' => 'sometimes|string|max:128',
@@ -24,6 +29,11 @@ class PaymentPluginConfValidator extends Validator
'ids' => 'sometimes|array',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'id' => '配置ID',
'keyword' => '关键字',
@@ -37,6 +47,11 @@ class PaymentPluginConfValidator extends Validator
'ids' => '配置ID集合',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'plugin_code', 'page', 'page_size'],
'store' => ['plugin_code', 'config', 'settlement_cycle_type', 'settlement_cutoff_time', 'remark'],
@@ -47,6 +62,11 @@ class PaymentPluginConfValidator extends Validator
'selectOptions' => ['keyword', 'plugin_code', 'page', 'page_size', 'ids'],
];
/**
* 根据场景返回支付插件配置校验规则。
*
* @return array 校验规则
*/
public function rules(): array
{
$rules = parent::rules();
@@ -66,3 +86,5 @@ class PaymentPluginConfValidator extends Validator
};
}
}

View File

@@ -11,6 +11,11 @@ use support\validation\Validator;
*/
class PaymentPluginValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'code' => 'sometimes|string|alpha_dash|min:2|max:32',
'status' => 'sometimes|integer|in:0,1',
@@ -23,10 +28,15 @@ class PaymentPluginValidator extends Validator
'ids' => 'sometimes|array',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'code' => '插件编码',
'name' => '插件名称',
'status' => '状态',
'status' => '插件状态',
'remark' => '备注',
'keyword' => '关键字',
'page' => '页码',
@@ -35,6 +45,11 @@ class PaymentPluginValidator extends Validator
'ids' => '插件编码集合',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'code', 'name', 'status', 'page', 'page_size'],
'update' => ['code', 'status', 'remark'],
@@ -43,3 +58,4 @@ class PaymentPluginValidator extends Validator
'selectOptions' => ['keyword', 'page', 'page_size', 'pay_type_code', 'ids'],
];
}

View File

@@ -11,6 +11,11 @@ use support\validation\Validator;
*/
class PaymentPollGroupBindValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'id' => 'sometimes|integer|min:1',
'keyword' => 'sometimes|string|max:128',
@@ -23,18 +28,28 @@ class PaymentPollGroupBindValidator extends Validator
'page_size' => 'sometimes|integer|min:1|max:100',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'id' => '绑定ID',
'keyword' => '关键字',
'merchant_group_id' => '商户分组',
'pay_type_id' => '支付方式',
'poll_group_id' => '轮询组',
'status' => '状态',
'status' => '分组绑定状态',
'remark' => '备注',
'page' => '页码',
'page_size' => '每页条数',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'merchant_group_id', 'pay_type_id', 'poll_group_id', 'status', 'page', 'page_size'],
'store' => ['merchant_group_id', 'pay_type_id', 'poll_group_id', 'status', 'remark'],
@@ -43,6 +58,11 @@ class PaymentPollGroupBindValidator extends Validator
'destroy' => ['id'],
];
/**
* 根据场景返回轮询组绑定校验规则。
*
* @return array 校验规则
*/
public function rules(): array
{
$rules = parent::rules();

View File

@@ -11,6 +11,11 @@ use support\validation\Validator;
*/
class PaymentPollGroupChannelValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'id' => 'sometimes|integer|min:1',
'keyword' => 'sometimes|string|max:128',
@@ -25,12 +30,17 @@ class PaymentPollGroupChannelValidator extends Validator
'page_size' => 'sometimes|integer|min:1|max:100',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'id' => '编排ID',
'keyword' => '关键字',
'poll_group_id' => '轮询组',
'channel_id' => '支付通道',
'status' => '状态',
'status' => '通道编排状态',
'sort_no' => '排序',
'weight' => '权重',
'is_default' => '默认通道',
@@ -39,6 +49,11 @@ class PaymentPollGroupChannelValidator extends Validator
'page_size' => '每页条数',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'poll_group_id', 'channel_id', 'status', 'page', 'page_size'],
'store' => ['poll_group_id', 'channel_id', 'sort_no', 'weight', 'is_default', 'status', 'remark'],
@@ -48,6 +63,11 @@ class PaymentPollGroupChannelValidator extends Validator
'destroy' => ['id'],
];
/**
* 根据场景返回轮询组通道校验规则。
*
* @return array 校验规则
*/
public function rules(): array
{
$rules = parent::rules();

View File

@@ -11,6 +11,11 @@ use support\validation\Validator;
*/
class PaymentPollGroupValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'id' => 'sometimes|integer|min:1',
'keyword' => 'sometimes|string|max:128',
@@ -23,18 +28,28 @@ class PaymentPollGroupValidator extends Validator
'page_size' => 'sometimes|integer|min:1|max:100',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'id' => '轮询组ID',
'keyword' => '关键字',
'group_name' => '轮询组名称',
'pay_type_id' => '支付方式',
'route_mode' => '路由模式',
'status' => '状态',
'status' => '轮询组状态',
'remark' => '备注',
'page' => '页码',
'page_size' => '每页条数',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'group_name', 'pay_type_id', 'route_mode', 'status', 'page', 'page_size'],
'store' => ['group_name', 'pay_type_id', 'route_mode', 'status', 'remark'],
@@ -44,6 +59,11 @@ class PaymentPollGroupValidator extends Validator
'destroy' => ['id'],
];
/**
* 根据场景返回支付轮询组校验规则。
*
* @return array 校验规则
*/
public function rules(): array
{
$rules = parent::rules();
@@ -73,3 +93,6 @@ class PaymentPollGroupValidator extends Validator
};
}
}

View File

@@ -11,6 +11,11 @@ use support\validation\Validator;
*/
class PaymentTypeValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'id' => 'sometimes|integer|min:1',
'keyword' => 'sometimes|string|max:128',
@@ -24,6 +29,11 @@ class PaymentTypeValidator extends Validator
'page_size' => 'sometimes|integer|min:1|max:100',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'id' => '支付方式ID',
'keyword' => '关键字',
@@ -31,12 +41,17 @@ class PaymentTypeValidator extends Validator
'name' => '支付方式名称',
'icon' => '图标',
'sort_no' => '排序',
'status' => '状态',
'status' => '支付方式状态',
'remark' => '备注',
'page' => '页码',
'page_size' => '每页条数',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'code', 'name', 'status', 'page', 'page_size'],
'store' => ['code', 'name', 'icon', 'sort_no', 'status', 'remark'],
@@ -46,6 +61,11 @@ class PaymentTypeValidator extends Validator
'destroy' => ['id'],
];
/**
* 根据场景返回支付类型校验规则。
*
* @return array 校验规则
*/
public function rules(): array
{
$rules = parent::rules();
@@ -73,3 +93,4 @@ class PaymentTypeValidator extends Validator
};
}
}

View File

@@ -11,6 +11,11 @@ use support\validation\Validator;
*/
class RefundActionValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'refund_no' => 'required|string|max:64',
'processing_at' => 'sometimes|date_format:Y-m-d H:i:s',
@@ -19,6 +24,11 @@ class RefundActionValidator extends Validator
'channel_refund_no' => 'sometimes|string|max:64',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'refund_no' => '退款单号',
'processing_at' => '处理时间',
@@ -27,6 +37,11 @@ class RefundActionValidator extends Validator
'channel_refund_no' => '渠道退款单号',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'retry' => ['refund_no', 'processing_at'],
'mark_fail' => ['refund_no', 'failed_at', 'last_error'],
@@ -34,3 +49,5 @@ class RefundActionValidator extends Validator
'mark_success' => ['refund_no', 'channel_refund_no'],
];
}

View File

@@ -11,6 +11,11 @@ use support\validation\Validator;
*/
class RefundOrderValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'keyword' => 'sometimes|string|max:128',
'merchant_id' => 'sometimes|integer|min:1',
@@ -21,6 +26,11 @@ class RefundOrderValidator extends Validator
'page_size' => 'sometimes|integer|min:1|max:100',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'keyword' => '关键字',
'merchant_id' => '商户ID',
@@ -31,7 +41,14 @@ class RefundOrderValidator extends Validator
'page_size' => '每页条数',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'merchant_id', 'pay_type_id', 'status', 'channel_mode', 'page', 'page_size'],
];
}

View File

@@ -7,10 +7,15 @@ use support\validation\Validator;
/**
* 路由解析参数校验器。
*
* 仅供管理后台预览路由使用
* 用于校验管理后台路由解析所需参数
*/
class RouteResolveValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'merchant_group_id' => 'required|integer|min:1',
'pay_type_id' => 'required|integer|min:1',
@@ -20,6 +25,11 @@ class RouteResolveValidator extends Validator
'stat_date' => 'sometimes|date_format:Y-m-d',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'merchant_group_id' => '商户分组',
'pay_type_id' => '支付方式',
@@ -29,7 +39,13 @@ class RouteResolveValidator extends Validator
'stat_date' => '统计日期',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'resolve' => ['merchant_group_id', 'pay_type_id', 'pay_amount', 'pay_type_code', 'channel_mode', 'stat_date'],
];
}

View File

@@ -9,6 +9,11 @@ use support\validation\Validator;
*/
class SettlementOrderValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'settle_no' => 'required|string|max:32',
'keyword' => 'sometimes|string|max:128',
@@ -20,19 +25,30 @@ class SettlementOrderValidator extends Validator
'page_size' => 'sometimes|integer|min:1|max:100',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'settle_no' => '清算单号',
'keyword' => '关键词',
'merchant_id' => '所属商户',
'channel_id' => '所属通道',
'status' => '状态',
'status' => '清算单状态',
'cycle_type' => '结算周期类型',
'page' => '页码',
'page_size' => '每页条数',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'index' => ['keyword', 'merchant_id', 'channel_id', 'status', 'cycle_type', 'page', 'page_size'],
'show' => ['settle_no'],
];
}

View File

@@ -4,20 +4,40 @@ namespace app\http\admin\validation;
use support\validation\Validator;
/**
* 系统配置页面校验器
*/
class SystemConfigPageValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'group_code' => 'required|string|min:1|max:50|regex:/^[a-z0-9_]+$/',
'values' => 'required|array',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'group_code' => '配置分组',
'values' => '配置值',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'show' => ['group_code'],
'store' => ['group_code', 'values'],
];
}

View File

@@ -12,12 +12,17 @@ use support\Response;
/**
* Epay 协议兼容控制器。
*
* 负责 submit.php、mapi.php 和 api.php 的入口场景校验与结果分发。
* 负责兼容入口场景校验与结果分发。
*
* @property EpayCompatService $epayCompatService Epay 兼容服务
*/
class EpayController extends BaseController
{
/**
* 构造函数,注入兼容服务
* 构造方法
*
* @param EpayCompatService $epayCompatService Epay 兼容服务
* @return void
*/
public function __construct(
protected EpayCompatService $epayCompatService
@@ -25,6 +30,9 @@ class EpayController extends BaseController
/**
* 页面跳转支付入口。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function submit(Request $request): Response
{
@@ -47,6 +55,9 @@ class EpayController extends BaseController
/**
* API 接口支付入口。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function mapi(Request $request): Response
{
@@ -69,6 +80,9 @@ class EpayController extends BaseController
/**
* 标准 API 接口入口。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function api(Request $request): Response
{
@@ -98,3 +112,8 @@ class EpayController extends BaseController
}
}
}

View File

@@ -10,14 +10,19 @@ use support\Request;
use support\Response;
/**
* 通知与回调记录控制器。
* 通知记录控制器。
*
* 负责渠道通知日志和商户通知任务的接入。
* 负责渠道通知日志和商户通知任务的接入,不承担真实业务回调处理
*
* @property NotifyService $notifyService 通知服务
*/
class NotifyController extends BaseController
{
/**
* 构造函数,注入通知服务
* 构造方法
*
* @param NotifyService $notifyService 通知服务
* @return void
*/
public function __construct(
protected NotifyService $notifyService
@@ -25,9 +30,12 @@ class NotifyController extends BaseController
}
/**
* POST /api/notify/channel
*
* 记录渠道通知日志。
*
* 用于保存外部渠道发来的通知原文,便于后续排查和审计。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function channel(Request $request): Response
{
@@ -37,9 +45,12 @@ class NotifyController extends BaseController
}
/**
* POST /api/notify/merchant
*
* 创建商户通知任务。
*
* 由支付或结算完成后触发,把通知任务交给异步通知链路处理。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function merchant(Request $request): Response
{
@@ -49,3 +60,8 @@ class NotifyController extends BaseController
}
}

View File

@@ -9,14 +9,19 @@ use support\Request;
use support\Response;
/**
* 路由预览控制器。
* 路由解析控制器。
*
* 用于返回指定商户分组、支付方式和金额条件下的路由解析结果
* 用于根据商户分组、支付方式和金额条件返回路由候选与最终选中通道
*
* @property PaymentRouteService $paymentRouteService 支付路由服务
*/
class RouteController extends BaseController
{
/**
* 构造函数,注入路由服务
* 构造方法
*
* @param PaymentRouteService $paymentRouteService 支付路由服务
* @return void
*/
public function __construct(
protected PaymentRouteService $paymentRouteService
@@ -24,9 +29,12 @@ class RouteController extends BaseController
}
/**
* GET /api/routes/resolve
*
* 解析支付路由。
*
* 这个接口会返回当前条件下的候选通道和最终命中的通道信息,通常用于下单前查看结果。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function resolve(Request $request): Response
{
@@ -41,3 +49,8 @@ class RouteController extends BaseController
}
}

View File

@@ -13,12 +13,17 @@ use support\Response;
/**
* 清算接口控制器。
*
* 负责清算单创建、查询和清算态推进。
* 负责清算单创建、查询和清算态推进。
*
* @property SettlementService $settlementService 结算服务
*/
class SettlementController extends BaseController
{
/**
* 构造函数,注入清算相关依赖
* 构造方法
*
* @param SettlementService $settlementService 结算服务
* @return void
*/
public function __construct(
protected SettlementService $settlementService,
@@ -26,7 +31,12 @@ class SettlementController extends BaseController
}
/**
* 创建清算单。
* 创建清算单。
*
* 会把传入的清算明细和汇总一起交给清算生命周期服务落库。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function create(Request $request): Response
{
@@ -37,7 +47,13 @@ class SettlementController extends BaseController
}
/**
* 查询清算单详情。
* 查询清算单详情。
*
* 用于查看批次金额、状态和关联支付单明细。
*
* @param Request $request 请求对象
* @param string $settleNo 结算单号
* @return Response 响应对象
*/
public function show(Request $request, string $settleNo): Response
{
@@ -49,7 +65,13 @@ class SettlementController extends BaseController
}
/**
* 标记清算成功。
* 标记清算成功。
*
* 会触发商户余额入账,并同步清算单、清算明细和关联支付单状态。
*
* @param Request $request 请求对象
* @param string $settleNo 结算单号
* @return Response 响应对象
*/
public function complete(Request $request, string $settleNo): Response
{
@@ -63,7 +85,13 @@ class SettlementController extends BaseController
}
/**
* 标记清算失败。
* 标记清算失败。
*
* 仅在清算批次未成功入账时使用,用于把批次推进到失败终态并保留原因。
*
* @param Request $request 请求对象
* @param string $settleNo 结算单号
* @return Response 响应对象
*/
public function failSettlement(Request $request, string $settleNo): Response
{
@@ -76,3 +104,7 @@ class SettlementController extends BaseController
return $this->success($this->settlementService->failSettlement($settleNo, (string) ($data['reason'] ?? '')));
}
}

View File

@@ -10,9 +10,17 @@ use support\Response;
/**
* 统一追踪查询控制器。
*
* @property TradeTraceService $tradeTraceService 交易追踪服务
*/
class TraceController extends BaseController
{
/**
* 构造方法。
*
* @param TradeTraceService $tradeTraceService 交易追踪服务
* @return void
*/
public function __construct(
protected TradeTraceService $tradeTraceService
) {
@@ -20,6 +28,10 @@ class TraceController extends BaseController
/**
* 查询指定追踪号对应的完整交易链路。
*
* @param Request $request 请求对象
* @param string $traceNo 追踪号
* @return Response 响应对象
*/
public function show(Request $request, string $traceNo): Response
{
@@ -37,3 +49,8 @@ class TraceController extends BaseController
return $this->success($result);
}
}

View File

@@ -15,14 +15,23 @@ use support\Request;
use support\Response;
/**
* 支付接口控制器。
* 收银台支付接口控制器。
*
* 负责支付预下单、支付查询、支付关闭和渠道回调入口。
* 负责支付预下单、支付查询、支付关闭、超时收口和渠道回调入口。
*
* @property PayOrderService $payOrderService 支付订单服务
* @property MerchantApiCredentialService $merchantApiCredentialService 商户 API 凭证服务
* @property PaymentTypeService $paymentTypeService 支付方式服务
*/
class PayController extends BaseController
{
/**
* 构造函数,注入支付单相关依赖
* 构造方法
*
* @param PayOrderService $payOrderService 支付订单服务
* @param MerchantApiCredentialService $merchantApiCredentialService 商户 API 凭证服务
* @param PaymentTypeService $paymentTypeService 支付类型服务
* @return void
*/
public function __construct(
protected PayOrderService $payOrderService,
@@ -32,7 +41,12 @@ class PayController extends BaseController
}
/**
* 支付预下单。
* 创建支付预下单并返回支付尝试结果
*
* 先对外部支付参数完成验签和归一化,再交给支付单尝试服务选择路由并创建支付单。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function prepare(Request $request): Response
{
@@ -47,6 +61,12 @@ class PayController extends BaseController
/**
* 查询支付单详情。
*
* 用于前端轮询支付结果或展示支付单当前状态。
*
* @param Request $request 请求对象
* @param string $payNo 支付单号
* @return Response 响应对象
*/
public function show(Request $request, string $payNo): Response
{
@@ -59,6 +79,12 @@ class PayController extends BaseController
/**
* 关闭支付单。
*
* 仅对尚未完成的支付单生效,通常由业务系统在用户主动取消时调用。
*
* @param Request $request 请求对象
* @param string $payNo 支付单号
* @return Response 响应对象
*/
public function close(Request $request, string $payNo): Response
{
@@ -73,6 +99,12 @@ class PayController extends BaseController
/**
* 标记支付单超时。
*
* 用于订单到达超时时间后的状态收口,后续由生命周期服务统一处理手续费释放和订单同步。
*
* @param Request $request 请求对象
* @param string $payNo 支付单号
* @return Response 响应对象
*/
public function timeout(Request $request, string $payNo): Response
{
@@ -86,7 +118,14 @@ class PayController extends BaseController
}
/**
* 处理渠道回调。
* 处理支付回调。
*
* 当路径里携带 `payNo` 时,进入第三方插件回调链路;
* 当未携带 `payNo` 时,按平台统一回调载荷进入渠道回调处理。
*
* @param Request $request 请求对象
* @param string $payNo 支付单号
* @return Response|string 字符串或响应对象
*/
public function callback(Request $request, string $payNo = ''): Response|string
{
@@ -103,6 +142,13 @@ class PayController extends BaseController
* 归一化外部支付下单参数并完成签名校验。
*
* 这层逻辑保留在控制器内,避免中间件承担业务验签职责。
* 同时把外部字段映射为系统内部支付单入参,并将回调基址写入扩展信息。
*
* @param Request $request 请求对象
* @param array $payload 请求载荷
* @return array 支付下单参数
* @throws \app\exception\ResourceNotFoundException
* @throws \app\exception\ValidationException
*/
private function normalizePreparePayload(Request $request, array $payload): array
{
@@ -113,6 +159,7 @@ class PayController extends BaseController
$typeCode = (string) $paymentType->code;
$money = (string) ($payload['money'] ?? '0');
// 外部协议按“元”传金额,系统内部统一转成“分”存储和计算。
$amount = (int) round(((float) $money) * 100);
return [
@@ -130,9 +177,16 @@ class PayController extends BaseController
'clientip' => (string) ($payload['clientip'] ?? ''),
'device' => (string) ($payload['device'] ?? ''),
'sign_type' => (string) ($payload['sign_type'] ?? 'MD5'),
// 回调基址会被插件和支付单后续流程复用。
'channel_callback_base_url' => (string) sys_config('site_url') . '/api/pay',
],
];
}
}

View File

@@ -13,12 +13,17 @@ use support\Response;
/**
* 退款接口控制器。
*
* 负责退款单创建与退款单查询
* 负责退款单创建、查询和终态推进入口
*
* @property RefundService $refundService 退款服务
*/
class RefundController extends BaseController
{
/**
* 构造函数,注入退款相关依赖
* 构造方法
*
* @param RefundService $refundService 退款服务
* @return void
*/
public function __construct(
protected RefundService $refundService,
@@ -27,6 +32,11 @@ class RefundController extends BaseController
/**
* 创建退款单。
*
* 以原支付单为基准创建退款申请,后续由退款生命周期服务推进处理中、成功或失败状态。
*
* @param Request $request 请求对象
* @return Response 响应对象
*/
public function create(Request $request): Response
{
@@ -37,6 +47,12 @@ class RefundController extends BaseController
/**
* 查询退款单详情。
*
* 用于退款进度展示和后台对账。
*
* @param Request $request 请求对象
* @param string $refundNo 退款单号
* @return Response 响应对象
*/
public function show(Request $request, string $refundNo): Response
{
@@ -49,6 +65,12 @@ class RefundController extends BaseController
/**
* 标记退款处理中。
*
* 由渠道侧或任务调度侧在退款请求已经受理后调用,用于推进退款状态机。
*
* @param Request $request 请求对象
* @param string $refundNo 退款单号
* @return Response 响应对象
*/
public function processing(Request $request, string $refundNo): Response
{
@@ -63,6 +85,12 @@ class RefundController extends BaseController
/**
* 退款重试。
*
* 仅用于失败态退款单重新发起处理,保持退款链路幂等和可恢复。
*
* @param Request $request 请求对象
* @param string $refundNo 退款单号
* @return Response 响应对象
*/
public function retry(Request $request, string $refundNo): Response
{
@@ -77,6 +105,12 @@ class RefundController extends BaseController
/**
* 标记退款失败。
*
* 用于把退款单推进到终态失败,并记录失败原因供运营和对账排查。
*
* @param Request $request 请求对象
* @param string $refundNo 退款单号
* @return Response 响应对象
*/
public function markFail(Request $request, string $refundNo): Response
{
@@ -91,3 +125,8 @@ class RefundController extends BaseController
}

View File

@@ -7,10 +7,15 @@ use support\validation\Validator;
/**
* ePay 兼容层请求校验器。
*
* 根据 submit、mapi、api.php 的不同入口场景做分场景校验,不依赖隐藏标记字段
* 用于校验兼容层不同入口的请求参数
*/
class EpayValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'act' => 'required|string|in:query,settle,order,orders,refund',
'pid' => 'required|integer|gt:0',
@@ -33,6 +38,11 @@ class EpayValidator extends Validator
'page' => 'sometimes|integer|gt:0',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'act' => '操作类型',
'pid' => '商户ID',
@@ -55,6 +65,11 @@ class EpayValidator extends Validator
'page' => '页码',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'submit' => ['pid', 'type', 'out_trade_no', 'notify_url', 'return_url', 'name', 'money', 'sign', 'sign_type', 'param'],
'mapi' => ['pid', 'type', 'out_trade_no', 'notify_url', 'return_url', 'name', 'money', 'clientip', 'device', 'sign', 'sign_type', 'param'],
@@ -67,6 +82,11 @@ class EpayValidator extends Validator
'refund_out_trade_no' => ['act', 'pid', 'key', 'out_trade_no', 'money', 'refund_no', 'reason'],
];
/**
* 根据场景返回 ePay 兼容层校验规则。
*
* @return array 校验规则
*/
public function rules(): array
{
$rules = parent::rules();
@@ -111,3 +131,4 @@ class EpayValidator extends Validator
};
}
}

View File

@@ -11,6 +11,11 @@ use support\validation\Validator;
*/
class NotifyChannelValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'notify_no' => 'sometimes|string|min:1|max:64',
'channel_id' => 'required|integer|min:1|exists:ma_payment_channel,id',
@@ -27,6 +32,11 @@ class NotifyChannelValidator extends Validator
'last_error' => 'nullable|string|max:255',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'notify_no' => '通知单号',
'channel_id' => '通道ID',
@@ -43,7 +53,14 @@ class NotifyChannelValidator extends Validator
'last_error' => '最后错误',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'store' => ['notify_no', 'channel_id', 'notify_type', 'biz_no', 'pay_no', 'channel_request_no', 'channel_trade_no', 'raw_payload', 'verify_status', 'process_status', 'retry_count', 'next_retry_at', 'last_error'],
];
}

View File

@@ -11,6 +11,11 @@ use support\validation\Validator;
*/
class NotifyMerchantValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'notify_no' => 'sometimes|string|min:1|max:64',
'merchant_id' => 'required|integer|min:1|exists:ma_merchant,id',
@@ -26,6 +31,11 @@ class NotifyMerchantValidator extends Validator
'last_response' => 'nullable|string|max:255',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'notify_no' => '通知单号',
'merchant_id' => '商户ID',
@@ -34,14 +44,21 @@ class NotifyMerchantValidator extends Validator
'pay_no' => '支付单号',
'notify_url' => '通知地址',
'notify_data' => '通知内容',
'status' => '状态',
'status' => '通知任务状态',
'retry_count' => '重试次数',
'next_retry_at' => '下次重试时间',
'last_notify_at' => '最后通知时间',
'last_response' => '最后响应',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'store' => ['notify_no', 'merchant_id', 'merchant_group_id', 'biz_no', 'pay_no', 'notify_url', 'notify_data', 'status', 'retry_count', 'next_retry_at', 'last_notify_at', 'last_response'],
];
}

View File

@@ -7,10 +7,15 @@ use support\validation\Validator;
/**
* 支付回调参数校验器。
*
* 用于校验渠道回调和主动查单回传参数
* 用于校验渠道回调和回调模拟入参
*/
class PayCallbackValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'pay_no' => 'required|string|min:1|max:64|exists:ma_pay_order,pay_no',
'success' => 'required|boolean',
@@ -29,15 +34,20 @@ class PayCallbackValidator extends Validator
'ext_json' => 'nullable|array',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'pay_no' => '支付单号',
'success' => '是否成功',
'success' => '支付是否成功',
'channel_id' => '通道ID',
'callback_type' => '回调类型',
'request_data' => '原始回调数据',
'verify_status' => '验签状态',
'process_status' => '处理状态',
'process_result' => '处理结果',
'process_result' => '处理详情',
'channel_trade_no' => '渠道交易号',
'channel_order_no' => '渠道订单号',
'fee_actual_amount' => '实际手续费',
@@ -47,7 +57,14 @@ class PayCallbackValidator extends Validator
'ext_json' => '扩展信息',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'callback' => ['pay_no', 'success', 'channel_id', 'callback_type', 'request_data', 'verify_status', 'process_status', 'process_result', 'channel_trade_no', 'channel_order_no', 'fee_actual_amount', 'paid_at', 'channel_error_code', 'channel_error_msg', 'ext_json'],
];
}

View File

@@ -11,6 +11,11 @@ use support\validation\Validator;
*/
class PayCloseValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'pay_no' => 'required|string|min:1|max:64|exists:ma_pay_order,pay_no',
'reason' => 'nullable|string|max:255',
@@ -18,6 +23,11 @@ class PayCloseValidator extends Validator
'ext_json' => 'nullable|array',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'pay_no' => '支付单号',
'reason' => '关闭原因',
@@ -25,7 +35,14 @@ class PayCloseValidator extends Validator
'ext_json' => '扩展信息',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'close' => ['pay_no', 'reason', 'closed_at', 'ext_json'],
];
}

View File

@@ -11,6 +11,11 @@ use support\validation\Validator;
*/
class PayPrepareValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'merchant_id' => 'required|integer|min:1|exists:ma_merchant,id',
'merchant_order_no' => 'required|string|min:1|max:64',
@@ -21,6 +26,11 @@ class PayPrepareValidator extends Validator
'ext_json' => 'nullable|array',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'merchant_id' => '商户ID',
'merchant_order_no' => '商户订单号',
@@ -31,7 +41,14 @@ class PayPrepareValidator extends Validator
'ext_json' => '扩展信息',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'prepare' => ['merchant_id', 'merchant_order_no', 'pay_type_id', 'pay_amount', 'subject', 'body', 'ext_json'],
];
}

View File

@@ -11,6 +11,11 @@ use support\validation\Validator;
*/
class PayTimeoutValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'pay_no' => 'required|string|min:1|max:64|exists:ma_pay_order,pay_no',
'reason' => 'nullable|string|max:255',
@@ -18,6 +23,11 @@ class PayTimeoutValidator extends Validator
'ext_json' => 'nullable|array',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'pay_no' => '支付单号',
'reason' => '超时原因',
@@ -25,7 +35,14 @@ class PayTimeoutValidator extends Validator
'ext_json' => '扩展信息',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'timeout' => ['pay_no', 'reason', 'timeout_at', 'ext_json'],
];
}

View File

@@ -11,6 +11,11 @@ use support\validation\Validator;
*/
class RefundActionValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'refund_no' => 'required|string|min:1|max:64|exists:ma_refund_order,refund_no',
'reason' => 'nullable|string|max:255',
@@ -20,6 +25,11 @@ class RefundActionValidator extends Validator
'ext_json' => 'nullable|array',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'refund_no' => '退款单号',
'reason' => '原因',
@@ -29,9 +39,16 @@ class RefundActionValidator extends Validator
'ext_json' => '扩展信息',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'processing' => ['refund_no', 'reason', 'last_error', 'processing_at', 'ext_json'],
'retry' => ['refund_no', 'reason', 'last_error', 'processing_at', 'ext_json'],
'fail' => ['refund_no', 'reason', 'last_error', 'failed_at', 'ext_json'],
];
}

View File

@@ -11,6 +11,11 @@ use support\validation\Validator;
*/
class RefundCreateValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'pay_no' => 'required|string|min:1|max:64|exists:ma_pay_order,pay_no',
'merchant_refund_no' => 'sometimes|string|min:1|max:64',
@@ -19,6 +24,11 @@ class RefundCreateValidator extends Validator
'ext_json' => 'nullable|array',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'pay_no' => '支付单号',
'merchant_refund_no' => '商户退款单号',
@@ -27,7 +37,14 @@ class RefundCreateValidator extends Validator
'ext_json' => '扩展信息',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'store' => ['pay_no', 'merchant_refund_no', 'refund_amount', 'reason', 'ext_json'],
];
}

View File

@@ -7,10 +7,15 @@ use support\validation\Validator;
/**
* 路由解析参数校验器。
*
* 用于校验路由预览所需参数。
* 用于校验路由解析所需参数。
*/
class RouteResolveValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'merchant_group_id' => 'required|integer|min:1|exists:ma_merchant_group,id',
'pay_type_id' => 'required|integer|min:1|exists:ma_payment_type,id',
@@ -18,6 +23,11 @@ class RouteResolveValidator extends Validator
'stat_date' => 'nullable|date_format:Y-m-d',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'merchant_group_id' => '商户分组ID',
'pay_type_id' => '支付方式',
@@ -25,7 +35,14 @@ class RouteResolveValidator extends Validator
'stat_date' => '统计日期',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'resolve' => ['merchant_group_id', 'pay_type_id', 'pay_amount', 'stat_date'],
];
}

View File

@@ -11,20 +11,37 @@ use support\validation\Validator;
*/
class SettlementActionValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'settle_no' => 'required|string|min:1|max:64|exists:ma_settlement_order,settle_no',
'reason' => 'nullable|string|max:255',
'ext_json' => 'nullable|array',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'settle_no' => '清算单号',
'reason' => '原因',
'ext_json' => '扩展信息',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'complete' => ['settle_no'],
'fail' => ['settle_no', 'reason', 'ext_json'],
];
}

View File

@@ -11,6 +11,11 @@ use support\validation\Validator;
*/
class SettlementCreateValidator extends Validator
{
/**
* 校验规则
*
* @var array
*/
protected array $rules = [
'settle_no' => 'sometimes|string|min:1|max:64',
'merchant_id' => 'required|integer|min:1|exists:ma_merchant,id',
@@ -38,6 +43,11 @@ class SettlementCreateValidator extends Validator
'items.*.item_status' => 'sometimes|integer|min:0',
];
/**
* 字段别名
*
* @var array
*/
protected array $attributes = [
'settle_no' => '清算单号',
'merchant_id' => '商户ID',
@@ -45,7 +55,7 @@ class SettlementCreateValidator extends Validator
'channel_id' => '通道ID',
'cycle_type' => '结算周期类型',
'cycle_key' => '结算周期键',
'status' => '状态',
'status' => '清算单状态',
'generated_at' => '生成时间',
'accounted_amount' => '入账金额',
'gross_amount' => '交易总额',
@@ -57,7 +67,14 @@ class SettlementCreateValidator extends Validator
'items' => '清算明细',
];
/**
* 校验场景
*
* @var array
*/
protected array $scenes = [
'store' => ['settle_no', 'merchant_id', 'merchant_group_id', 'channel_id', 'cycle_type', 'cycle_key', 'status', 'generated_at', 'accounted_amount', 'gross_amount', 'fee_amount', 'refund_amount', 'fee_reverse_amount', 'net_amount', 'ext_json', 'items', 'items.*.pay_no', 'items.*.refund_no', 'items.*.pay_amount', 'items.*.fee_amount', 'items.*.refund_amount', 'items.*.fee_reverse_amount', 'items.*.net_amount', 'items.*.item_status'],
];
}

Some files were not shown because too many files have changed in this diff Show More