PaymentTemplate.php 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2017~2025 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. 'signatureMethod' => 'platformCert', // 验签方式(platformCert平台证书 publicKey微信支付公钥)
  64. 'publicKeyId' => '',
  65. 'publicKey' => '',
  66. 'apiclientCert' => '',
  67. 'apiclientKey' => '',
  68. ],
  69. 'provider' => [
  70. 'spAppId' => '',
  71. 'spMchId' => '',
  72. 'spApiKey' => '',
  73. 'subAppId' => '',
  74. 'subMchId' => '',
  75. 'spSignatureMethod' => 'platformCert', // 验签方式(platformCert平台证书 publicKey微信支付公钥)
  76. 'spPublicKeyId' => '',
  77. 'spPublicKey' => '',
  78. 'spApiclientCert' => '',
  79. 'spApiclientKey' => ''
  80. ]
  81. ],
  82. PaymentMethodEnum::ALIPAY => [
  83. 'appId' => '',
  84. 'signType' => 'RSA2',
  85. 'signMode' => 10,
  86. 'alipayPublicKey' => '',
  87. 'appCertPublicKey' => '',
  88. 'alipayCertPublicKey' => '',
  89. 'alipayRootCert' => '',
  90. 'merchantPrivateKey' => ''
  91. ],
  92. ];
  93. }
  94. /**
  95. * 支付方式详情
  96. * @param int $templateId
  97. * @return static|array|null
  98. */
  99. public static function detail(int $templateId)
  100. {
  101. return self::get($templateId);
  102. }
  103. /**
  104. * 获取全部支付模板
  105. * @return array|static[]|\think\Collection
  106. * @throws \think\db\exception\DataNotFoundException
  107. * @throws \think\db\exception\DbException
  108. * @throws \think\db\exception\ModelNotFoundException
  109. */
  110. public function getAll()
  111. {
  112. return $this->where('is_delete', '=', 0)
  113. ->order(['sort' => 'asc', $this->getPk()])
  114. ->select();
  115. }
  116. /**
  117. * 获取支付模板
  118. * @param int $templateId 支付模板ID
  119. * @return array
  120. * @throws BaseException
  121. */
  122. public function getTemplateInfo(int $templateId): array
  123. {
  124. // 支付模板记录
  125. $template = static::detail($templateId);
  126. if (empty($template) || $template['is_delete']) {
  127. throwError('很抱歉,当前不存在支付模板');
  128. }
  129. // 格式化为数组格式
  130. $info = $template->toArray();
  131. // 记录证书文件名
  132. $methodConfig = $info['config'][$info['method']];
  133. $info['config'] = [$info['method'] => array_merge(
  134. $methodConfig,
  135. $this->certFileName($info['method'], $methodConfig, $template['store_id'])
  136. )];
  137. return $info;
  138. }
  139. /**
  140. * 记录证书文件名
  141. * @param string $method 支付方式类型
  142. * @param array $config 支付配置
  143. * @param int $storeId
  144. * @return array
  145. */
  146. private function certFileName(string $method, array $config, int $storeId): array
  147. {
  148. if ($method === PaymentMethodEnum::WECHAT) {
  149. $config['normal'] = $this->setCertFileNames($config['normal'], $method, [
  150. 'publicKey',
  151. 'apiclientCert',
  152. 'apiclientKey',
  153. 'platformCert'
  154. ], $storeId);
  155. $config['provider'] = $this->setCertFileNames($config['provider'], $method, [
  156. 'spPublicKey',
  157. 'spApiclientCert',
  158. 'spApiclientKey',
  159. 'platformCert'
  160. ], $storeId);
  161. }
  162. if ($method === PaymentMethodEnum::ALIPAY && $config['signMode'] == 10) {
  163. $config = $this->setCertFileNames($config, $method, [
  164. 'appCertPublicKey',
  165. 'alipayCertPublicKey',
  166. 'alipayRootCert'
  167. ], $storeId);
  168. }
  169. return $config;
  170. }
  171. /**
  172. * 批量设置证书文件名
  173. * @param array $config 配置项
  174. * @param string $method 支付方式类型
  175. * @param array $certNames
  176. * @param int $storeId 商城ID
  177. * @return array
  178. */
  179. private function setCertFileNames(array $config, string $method, array $certNames, int $storeId): array
  180. {
  181. foreach ($certNames as $name) {
  182. // 此处的判断是兼容V2模式下没有platformCert
  183. if (isset($config[$name])) {
  184. $config["{$name}Path"] = self::realPathCertFile($method, $config[$name], $storeId);
  185. }
  186. }
  187. return $config;
  188. }
  189. /**
  190. * 获取证书文件绝对路径
  191. * @param string $method 支付方式类型
  192. * @param string $fileName 证书文件名称
  193. * @return string|false
  194. */
  195. public static function realPathCertFile(string $method, string $fileName, int $storeId)
  196. {
  197. // 文件路径
  198. $filePath = self::certFolder($method, $storeId) . "/{$fileName}";
  199. return !empty($fileName) ? realpath($filePath) : '';
  200. }
  201. /**
  202. * 获取证书文件所在目录
  203. * @param string $method
  204. * @param int $storeId
  205. * @return string
  206. */
  207. public static function certFolder(string $method, int $storeId): string
  208. {
  209. return data_path() . "payment/{$method}/{$storeId}";
  210. }
  211. }