You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
6.7 KiB
217 lines
6.7 KiB
11 months ago
|
<?php
|
||
|
// +----------------------------------------------------------------------
|
||
|
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
|
||
|
// +----------------------------------------------------------------------
|
||
|
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
|
||
|
// +----------------------------------------------------------------------
|
||
|
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
|
||
|
// +----------------------------------------------------------------------
|
||
|
// | Author: 萤火科技 <admin@yiovo.com>
|
||
|
// +----------------------------------------------------------------------
|
||
|
declare (strict_types=1);
|
||
|
|
||
|
namespace app\common\model;
|
||
|
|
||
|
use cores\BaseModel;
|
||
|
use cores\exception\BaseException;
|
||
|
use app\common\library\helper;
|
||
|
use app\common\enum\payment\Method as PaymentMethodEnum;
|
||
|
|
||
|
/**
|
||
|
* 模型类:支付模板记录
|
||
|
* Class PaymentTemplate
|
||
|
* @package app\common\model
|
||
|
*/
|
||
|
class PaymentTemplate extends BaseModel
|
||
|
{
|
||
|
// 定义表名
|
||
|
protected $name = 'payment_template';
|
||
|
|
||
|
// 定义主键
|
||
|
protected $pk = 'template_id';
|
||
|
|
||
|
/**
|
||
|
* 获取器:支付配置
|
||
|
* @param string $value
|
||
|
* @return array
|
||
|
*/
|
||
|
public function getConfigAttr(string $value): array
|
||
|
{
|
||
|
$data = helper::jsonDecode($value);
|
||
|
return static::reorganize((new static)->defaultData(), $data);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 修改器:支付配置
|
||
|
* @param $value
|
||
|
* @return string
|
||
|
*/
|
||
|
public function setConfigAttr($value): string
|
||
|
{
|
||
|
return helper::jsonEncode($value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 默认配置
|
||
|
* @return array
|
||
|
*/
|
||
|
public function defaultData(): array
|
||
|
{
|
||
|
return [
|
||
|
PaymentMethodEnum::WECHAT => [
|
||
|
// 微信商户号类型(normal普通商户 provider子商户)
|
||
|
'mchType' => 'normal',
|
||
|
// 微信支付API版本(v2和v3)
|
||
|
'version' => 'v2',
|
||
|
'normal' => [
|
||
|
'appId' => '',
|
||
|
'mchId' => '',
|
||
|
'apiKey' => '',
|
||
|
'apiclientCert' => '',
|
||
|
'apiclientKey' => '',
|
||
|
],
|
||
|
'provider' => [
|
||
|
'spAppId' => '',
|
||
|
'spMchId' => '',
|
||
|
'spApiKey' => '',
|
||
|
'subAppId' => '',
|
||
|
'subMchId' => '',
|
||
|
'spApiclientCert' => '',
|
||
|
'spApiclientKey' => ''
|
||
|
]
|
||
|
],
|
||
|
PaymentMethodEnum::ALIPAY => [
|
||
|
'appId' => '',
|
||
|
'signType' => 'RSA2',
|
||
|
'signMode' => 10,
|
||
|
'alipayPublicKey' => '',
|
||
|
'appCertPublicKey' => '',
|
||
|
'alipayCertPublicKey' => '',
|
||
|
'alipayRootCert' => '',
|
||
|
'merchantPrivateKey' => ''
|
||
|
],
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 支付方式详情
|
||
|
* @param int $templateId
|
||
|
* @return static|array|null
|
||
|
*/
|
||
|
public static function detail(int $templateId)
|
||
|
{
|
||
|
return self::get($templateId);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 获取全部支付模板
|
||
|
* @return array|static[]|\think\Collection
|
||
|
* @throws \think\db\exception\DataNotFoundException
|
||
|
* @throws \think\db\exception\DbException
|
||
|
* @throws \think\db\exception\ModelNotFoundException
|
||
|
*/
|
||
|
public function getAll()
|
||
|
{
|
||
|
return $this->where('is_delete', '=', 0)
|
||
|
->order(['sort' => 'asc', $this->getPk()])
|
||
|
->select();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 获取支付模板
|
||
|
* @param int $templateId 支付模板ID
|
||
|
* @return array
|
||
|
* @throws BaseException
|
||
|
*/
|
||
|
public function getTemplateInfo(int $templateId): array
|
||
|
{
|
||
|
// 支付模板记录
|
||
|
$template = static::detail($templateId);
|
||
|
if (empty($template) || $template['is_delete']) {
|
||
|
throwError('很抱歉,当前不存在支付模板');
|
||
|
}
|
||
|
// 格式化为数组格式
|
||
|
$info = $template->toArray();
|
||
|
// 记录证书文件名
|
||
|
$methodConfig = $info['config'][$info['method']];
|
||
|
$info['config'] = [$info['method'] => array_merge(
|
||
|
$methodConfig,
|
||
|
$this->certFileName($info['method'], $methodConfig, $template['store_id'])
|
||
|
)];
|
||
|
return $info;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 记录证书文件名
|
||
|
* @param string $method 支付方式类型
|
||
|
* @param array $config 支付配置
|
||
|
* @param int $storeId
|
||
|
* @return array
|
||
|
*/
|
||
|
private function certFileName(string $method, array $config, int $storeId): array
|
||
|
{
|
||
|
if ($method === PaymentMethodEnum::WECHAT) {
|
||
|
$config['normal'] = $this->setCertFileNames($config['normal'], $method, [
|
||
|
'apiclientCert',
|
||
|
'apiclientKey',
|
||
|
'platformCert'
|
||
|
], $storeId);
|
||
|
$config['provider'] = $this->setCertFileNames($config['provider'], $method, [
|
||
|
'spApiclientCert',
|
||
|
'spApiclientKey',
|
||
|
'platformCert'
|
||
|
], $storeId);
|
||
|
}
|
||
|
if ($method === PaymentMethodEnum::ALIPAY && $config['signMode'] == 10) {
|
||
|
$config = $this->setCertFileNames($config, $method, [
|
||
|
'appCertPublicKey',
|
||
|
'alipayCertPublicKey',
|
||
|
'alipayRootCert'
|
||
|
], $storeId);
|
||
|
}
|
||
|
return $config;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 批量设置证书文件名
|
||
|
* @param array $config 配置项
|
||
|
* @param string $method 支付方式类型
|
||
|
* @param array $certNames
|
||
|
* @param int $storeId 商城ID
|
||
|
* @return array
|
||
|
*/
|
||
|
private function setCertFileNames(array $config, string $method, array $certNames, int $storeId): array
|
||
|
{
|
||
|
foreach ($certNames as $name) {
|
||
|
// 此处的判断是兼容V2模式下没有platformCert
|
||
|
if (isset($config[$name])) {
|
||
|
$config["{$name}Path"] = self::realPathCertFile($method, $config[$name], $storeId);
|
||
|
}
|
||
|
}
|
||
|
return $config;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 获取证书文件绝对路径
|
||
|
* @param string $method 支付方式类型
|
||
|
* @param string $fileName 证书文件名称
|
||
|
* @return string|false
|
||
|
*/
|
||
|
public static function realPathCertFile(string $method, string $fileName, int $storeId)
|
||
|
{
|
||
|
// 文件路径
|
||
|
$filePath = self::certFolder($method, $storeId) . "/{$fileName}";
|
||
|
return !empty($fileName) ? realpath($filePath) : '';
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 获取证书文件所在目录
|
||
|
* @param string $method
|
||
|
* @param int $storeId
|
||
|
* @return string
|
||
|
*/
|
||
|
public static function certFolder(string $method, int $storeId): string
|
||
|
{
|
||
|
return data_path() . "payment/{$method}/{$storeId}";
|
||
|
}
|
||
|
}
|