PaymentTemplate.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2017~2024 https://www.yiovo.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
  8. // +----------------------------------------------------------------------
  9. // | Author: 萤火科技 <admin@yiovo.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types=1);
  12. namespace app\common\model;
  13. use cores\BaseModel;
  14. use cores\exception\BaseException;
  15. use app\common\library\helper;
  16. use app\common\enum\payment\Method as PaymentMethodEnum;
  17. /**
  18. * 模型类:支付模板记录
  19. * Class PaymentTemplate
  20. * @package app\common\model
  21. */
  22. class PaymentTemplate extends BaseModel
  23. {
  24. // 定义表名
  25. protected $name = 'payment_template';
  26. // 定义主键
  27. protected $pk = 'template_id';
  28. /**
  29. * 获取器:支付配置
  30. * @param string $value
  31. * @return array
  32. */
  33. public function getConfigAttr(string $value): array
  34. {
  35. $data = helper::jsonDecode($value);
  36. return \resetOptions((new static)->defaultData(), $data);
  37. }
  38. /**
  39. * 修改器:支付配置
  40. * @param $value
  41. * @return string
  42. */
  43. public function setConfigAttr($value): string
  44. {
  45. return helper::jsonEncode($value);
  46. }
  47. /**
  48. * 默认配置
  49. * @return array
  50. */
  51. public function defaultData(): array
  52. {
  53. return [
  54. PaymentMethodEnum::WECHAT => [
  55. // 微信商户号类型(normal普通商户 provider子商户)
  56. 'mchType' => 'normal',
  57. // 微信支付API版本(v2和v3)
  58. 'version' => 'v2',
  59. 'normal' => [
  60. 'appId' => '',
  61. 'mchId' => '',
  62. 'apiKey' => '',
  63. 'apiclientCert' => '',
  64. 'apiclientKey' => '',
  65. ],
  66. 'provider' => [
  67. 'spAppId' => '',
  68. 'spMchId' => '',
  69. 'spApiKey' => '',
  70. 'subAppId' => '',
  71. 'subMchId' => '',
  72. 'spApiclientCert' => '',
  73. 'spApiclientKey' => ''
  74. ]
  75. ],
  76. PaymentMethodEnum::ALIPAY => [
  77. 'appId' => '',
  78. 'signType' => 'RSA2',
  79. 'signMode' => 10,
  80. 'alipayPublicKey' => '',
  81. 'appCertPublicKey' => '',
  82. 'alipayCertPublicKey' => '',
  83. 'alipayRootCert' => '',
  84. 'merchantPrivateKey' => ''
  85. ],
  86. ];
  87. }
  88. /**
  89. * 支付方式详情
  90. * @param int $templateId
  91. * @return static|array|null
  92. */
  93. public static function detail(int $templateId)
  94. {
  95. return self::get($templateId);
  96. }
  97. /**
  98. * 获取全部支付模板
  99. * @return array|static[]|\think\Collection
  100. * @throws \think\db\exception\DataNotFoundException
  101. * @throws \think\db\exception\DbException
  102. * @throws \think\db\exception\ModelNotFoundException
  103. */
  104. public function getAll()
  105. {
  106. return $this->where('is_delete', '=', 0)
  107. ->order(['sort' => 'asc', $this->getPk()])
  108. ->select();
  109. }
  110. /**
  111. * 获取支付模板
  112. * @param int $templateId 支付模板ID
  113. * @return array
  114. * @throws BaseException
  115. */
  116. public function getTemplateInfo(int $templateId): array
  117. {
  118. // 支付模板记录
  119. $template = static::detail($templateId);
  120. if (empty($template) || $template['is_delete']) {
  121. throwError('很抱歉,当前不存在支付模板');
  122. }
  123. // 格式化为数组格式
  124. $info = $template->toArray();
  125. // 记录证书文件名
  126. $methodConfig = $info['config'][$info['method']];
  127. $info['config'] = [$info['method'] => array_merge(
  128. $methodConfig,
  129. $this->certFileName($info['method'], $methodConfig, $template['store_id'])
  130. )];
  131. return $info;
  132. }
  133. /**
  134. * 记录证书文件名
  135. * @param string $method 支付方式类型
  136. * @param array $config 支付配置
  137. * @param int $storeId
  138. * @return array
  139. */
  140. private function certFileName(string $method, array $config, int $storeId): array
  141. {
  142. if ($method === PaymentMethodEnum::WECHAT) {
  143. $config['normal'] = $this->setCertFileNames($config['normal'], $method, [
  144. 'apiclientCert',
  145. 'apiclientKey',
  146. 'platformCert'
  147. ], $storeId);
  148. $config['provider'] = $this->setCertFileNames($config['provider'], $method, [
  149. 'spApiclientCert',
  150. 'spApiclientKey',
  151. 'platformCert'
  152. ], $storeId);
  153. }
  154. if ($method === PaymentMethodEnum::ALIPAY && $config['signMode'] == 10) {
  155. $config = $this->setCertFileNames($config, $method, [
  156. 'appCertPublicKey',
  157. 'alipayCertPublicKey',
  158. 'alipayRootCert'
  159. ], $storeId);
  160. }
  161. return $config;
  162. }
  163. /**
  164. * 批量设置证书文件名
  165. * @param array $config 配置项
  166. * @param string $method 支付方式类型
  167. * @param array $certNames
  168. * @param int $storeId 商城ID
  169. * @return array
  170. */
  171. private function setCertFileNames(array $config, string $method, array $certNames, int $storeId): array
  172. {
  173. foreach ($certNames as $name) {
  174. // 此处的判断是兼容V2模式下没有platformCert
  175. if (isset($config[$name])) {
  176. $config["{$name}Path"] = self::realPathCertFile($method, $config[$name], $storeId);
  177. }
  178. }
  179. return $config;
  180. }
  181. /**
  182. * 获取证书文件绝对路径
  183. * @param string $method 支付方式类型
  184. * @param string $fileName 证书文件名称
  185. * @return string|false
  186. */
  187. public static function realPathCertFile(string $method, string $fileName, int $storeId)
  188. {
  189. // 文件路径
  190. $filePath = self::certFolder($method, $storeId) . "/{$fileName}";
  191. return !empty($fileName) ? realpath($filePath) : '';
  192. }
  193. /**
  194. * 获取证书文件所在目录
  195. * @param string $method
  196. * @param int $storeId
  197. * @return string
  198. */
  199. public static function certFolder(string $method, int $storeId): string
  200. {
  201. return data_path() . "payment/{$method}/{$storeId}";
  202. }
  203. }