// +---------------------------------------------------------------------- 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}"; } }