mirror of
https://gitee.com/technical-laohu/mpay_v2_webman.git
synced 2026-05-17 06:20:25 +08:00
feat: 完善支付通道和收款监听链路
新增 ChannelNotifyPayloadInterface 等支付插件通知契约,规范 pay_no 定位和插件返回校验。 新增微信、支付宝、收钱吧、Postar 个人收款插件适配,支持余额识别与备注识别。 新增 receipt-watcher 后端进程、Redis 队列 job 和平台事件监听,覆盖收款流水通知、商户通知、退款派发、转账派发与清算完成。 补齐个人收款监听相关系统配置、仓储、服务费冻结明细、订单后台操作和通道测试能力。 重构支付单创建、回调、费用、风控、结算和通道统计链路,统一状态流转与幂等处理。
This commit is contained in:
@@ -125,7 +125,6 @@ class MerchantOverviewQueryService extends BaseService
|
||||
'has_credential' => $credential !== null,
|
||||
'credential_enabled' => (int) ($credential->status ?? 0) === CommonConstant::STATUS_ENABLED,
|
||||
'credential_status_text' => (int) ($credential->status ?? 0) === CommonConstant::STATUS_ENABLED ? '已开通' : '未开通',
|
||||
'sign_type_text' => $this->textFromMap((int) ($credential->sign_type ?? 0), \app\common\constant\AuthConstant::signTypeMap()),
|
||||
'credential_last_used_at' => $this->formatDateTime($credential->last_used_at ?? null),
|
||||
],
|
||||
'route' => [
|
||||
@@ -153,4 +152,3 @@ class MerchantOverviewQueryService extends BaseService
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ class MerchantAuthService extends BaseService
|
||||
* @param string $password 密码
|
||||
* @param string $ip 请求 IP
|
||||
* @param string $userAgent 用户代理
|
||||
* @return array{token: string, expires_in: int, merchant: Merchant, credential: array{status: int, sign_type: int, last_used_at: mixed}|null} 登录结果
|
||||
* @return array{token: string, expires_in: int, merchant: Merchant, credential: array{status: int, last_used_at: mixed}|null} 登录结果
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function authenticateCredentials(string $merchantNo, string $password, string $ip = '', string $userAgent = ''): array
|
||||
@@ -183,7 +183,7 @@ class MerchantAuthService extends BaseService
|
||||
* @param int $ttlSeconds 过期秒数
|
||||
* @param string $ip 请求 IP
|
||||
* @param string $userAgent 用户代理
|
||||
* @return array{token: string, expires_in: int, merchant: Merchant, credential: array{status: int, sign_type: int, last_used_at: mixed}|null} 登录结果
|
||||
* @return array{token: string, expires_in: int, merchant: Merchant, credential: array{status: int, last_used_at: mixed}|null} 登录结果
|
||||
* @throws ValidationException
|
||||
*/
|
||||
public function issueToken(int $merchantId, int $ttlSeconds = 86400, string $ip = '', string $userAgent = ''): array
|
||||
@@ -213,7 +213,6 @@ class MerchantAuthService extends BaseService
|
||||
'merchant' => $merchant,
|
||||
'credential' => $credential ? [
|
||||
'status' => (int) ($credential->status ?? 0),
|
||||
'sign_type' => (int) ($credential->sign_type ?? 0),
|
||||
'last_used_at' => $credential->last_used_at,
|
||||
] : null,
|
||||
];
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace app\service\merchant\portal;
|
||||
|
||||
use app\common\base\BaseService;
|
||||
use app\common\constant\AuthConstant;
|
||||
use app\exception\ResourceNotFoundException;
|
||||
use app\repository\merchant\base\MerchantRepository;
|
||||
use app\service\merchant\MerchantService;
|
||||
@@ -171,14 +170,4 @@ class MerchantPortalSupportService extends BaseService
|
||||
return $payTypeId > 0 ? '未知' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 签名类型文案。
|
||||
*
|
||||
* @param int $signType 签名类型
|
||||
* @return string 签名类型文本
|
||||
*/
|
||||
public function signTypeText(int $signType): string
|
||||
{
|
||||
return $this->textFromMap($signType, AuthConstant::signTypeMap());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,13 +62,11 @@ class MerchantApiCredentialQueryService extends BaseService
|
||||
->paginate(max(1, $pageSize), ['*'], 'page', max(1, $page));
|
||||
|
||||
$paginator->getCollection()->transform(function ($row) {
|
||||
$row->sign_type_text = $this->textFromMap((int) $row->sign_type, AuthConstant::signTypeMap());
|
||||
$row->status_text = $this->textFromMap((int) $row->status, AuthConstant::credentialStatusMap());
|
||||
$row->platform_public_key_preview = $this->maskCredentialValue(
|
||||
trim((string) config('epay.v2.platform_public_key', '')),
|
||||
false
|
||||
);
|
||||
$row->platform_sign_type_text = (string) config('epay.v2.sign_type', AuthConstant::API_SIGN_NAME_SHA256_WITH_RSA);
|
||||
|
||||
return $row;
|
||||
});
|
||||
@@ -114,7 +112,6 @@ class MerchantApiCredentialQueryService extends BaseService
|
||||
->select([
|
||||
'c.id',
|
||||
'c.merchant_id',
|
||||
'c.sign_type',
|
||||
'c.merchant_public_key',
|
||||
'c.status',
|
||||
'c.last_used_at',
|
||||
@@ -151,11 +148,9 @@ class MerchantApiCredentialQueryService extends BaseService
|
||||
|
||||
$row->api_key_preview = $this->maskCredentialValue((string) ($row->api_key ?? ''), false);
|
||||
$row->merchant_public_key_preview = $this->maskCredentialValue((string) ($row->merchant_public_key ?? ''), false);
|
||||
$row->sign_type_text = $this->textFromMap((int) $row->sign_type, AuthConstant::signTypeMap());
|
||||
$row->status_text = $this->textFromMap((int) $row->status, AuthConstant::credentialStatusMap());
|
||||
$row->platform_public_key_full = trim((string) config('epay.v2.platform_public_key', ''));
|
||||
$row->platform_public_key_preview = $this->maskCredentialValue((string) $row->platform_public_key_full, false);
|
||||
$row->platform_sign_type_text = (string) config('epay.v2.sign_type', AuthConstant::API_SIGN_NAME_SHA256_WITH_RSA);
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
@@ -96,7 +96,6 @@ class MerchantApiCredentialService extends BaseService
|
||||
throw new ValidationException('请至少选择一种要生成的凭证类型');
|
||||
}
|
||||
|
||||
$signType = (int) ($options['sign_type'] ?? ($current?->sign_type ?? AuthConstant::API_SIGN_TYPE_MD5));
|
||||
$status = (int) ($options['status'] ?? ($current?->status ?? AuthConstant::CREDENTIAL_STATUS_ENABLED));
|
||||
$credentialValue = $rotateV1 ? $this->generateCredentialValue() : trim((string) ($current?->api_key ?? ''));
|
||||
$merchantPrivateKey = '';
|
||||
@@ -112,7 +111,6 @@ class MerchantApiCredentialService extends BaseService
|
||||
['merchant_id' => $merchantId],
|
||||
[
|
||||
'merchant_id' => $merchantId,
|
||||
'sign_type' => $signType,
|
||||
'status' => $status,
|
||||
'api_key' => $credentialValue,
|
||||
'merchant_public_key' => $merchantPublicKey,
|
||||
@@ -274,19 +272,16 @@ class MerchantApiCredentialService extends BaseService
|
||||
* @param bool $isUpdate 是否更新
|
||||
* @param MerchantApiCredential|null $current 当前凭证
|
||||
* 更新场景下,空字符串视为“不修改”,避免手动配置时误清空已有密钥。
|
||||
* `sign_type` 在当前阶段只作为展示/默认接入说明,不再作为 V1/V2 互斥开关。
|
||||
*
|
||||
* @return array{merchant_id: int, sign_type: int, status: int, api_key?: string} 标准化后的写入数据
|
||||
* @return array{merchant_id: int, status: int, api_key?: string} 标准化后的写入数据
|
||||
*/
|
||||
private function normalizePayload(array $data, bool $isUpdate, ?MerchantApiCredential $current = null): array
|
||||
{
|
||||
// 更新场景下以现有记录的 merchant_id 为准,避免把凭证误挂到别的商户。
|
||||
$merchantId = (int) ($current?->merchant_id ?? ($data['merchant_id'] ?? 0));
|
||||
$currentSignType = (int) ($current?->sign_type ?? AuthConstant::API_SIGN_TYPE_MD5);
|
||||
$currentStatus = (int) ($current?->status ?? AuthConstant::CREDENTIAL_STATUS_ENABLED);
|
||||
$payload = [
|
||||
'merchant_id' => $merchantId,
|
||||
'sign_type' => (int) ($data['sign_type'] ?? $currentSignType),
|
||||
'status' => (int) ($data['status'] ?? $currentStatus),
|
||||
];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user