V3WechatPay.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. <?php
  2. /**
  3. * +----------------------------------------------------------------------
  4. * | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  5. * +----------------------------------------------------------------------
  6. * | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
  7. * +----------------------------------------------------------------------
  8. * | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  9. * +----------------------------------------------------------------------
  10. * | Author: CRMEB Team <admin@crmeb.com>
  11. * +----------------------------------------------------------------------
  12. */
  13. namespace crmeb\services\pay\storage;
  14. use app\services\pay\PayServices;
  15. use crmeb\exceptions\PayException;
  16. use crmeb\services\app\MiniProgramService;
  17. use crmeb\services\easywechat\Application;
  18. use crmeb\services\pay\BasePay;
  19. use crmeb\services\pay\PayInterface;
  20. use EasyWeChat\Payment\Order;
  21. use think\facade\Event;
  22. /**
  23. * Class 微信支付v3
  24. * @author 等风来
  25. * @email 136327134@qq.com
  26. * @date 2022/9/22
  27. * @package crmeb\services\pay\storage
  28. */
  29. class V3WechatPay extends BasePay implements PayInterface
  30. {
  31. /**
  32. * @var Application
  33. */
  34. protected $instance;
  35. /**
  36. * @param array $config
  37. * @return mixed|void
  38. * @author 等风来
  39. * @email 136327134@qq.com
  40. * @date 2022/9/22
  41. */
  42. protected function initialize(array $config = [])
  43. {
  44. $wechatAppid = sys_config('wechat_appid');
  45. $config = [
  46. 'app' => [
  47. 'appid' => sys_config('wechat_app_appid'),
  48. ],
  49. 'wechat' => [
  50. 'appid' => $wechatAppid,
  51. ],
  52. 'miniprog' => [
  53. 'appid' => sys_config('routine_appId'),
  54. ],
  55. 'web' => [
  56. 'appid' => $wechatAppid,
  57. ],
  58. 'v3_payment' => [
  59. 'mchid' => sys_config('pay_weixin_mchid'),
  60. 'key' => sys_config('pay_weixin_key_v3'),
  61. 'serial_no' => sys_config('pay_weixin_serial_no'),
  62. 'cert_path' => public_path() . $this->getPemPath(sys_config('pay_weixin_client_cert')),
  63. 'key_path' => public_path() . $this->getPemPath(sys_config('pay_weixin_client_key')),
  64. 'notify_url' => trim(sys_config('site_url')) . '/api/pay/notify/v3wechat',
  65. ]
  66. ];
  67. $config['v3_payment']['mer_type'] = $merType = sys_config('mer_type');
  68. if ($merType) {
  69. $config['v3_payment']['sub_mch_id'] = trim(sys_config('pay_sub_merchant_id'));
  70. $config['v3_payment']['sp_appid'] = trim(sys_config('sp_appid'));
  71. }
  72. $this->instance = new Application($config);
  73. }
  74. /**
  75. * 获取证书不带域名的路径
  76. * @param string $path
  77. * @return mixed|string
  78. * @author 等风来
  79. * @email 136327134@qq.com
  80. * @date 2022/9/22
  81. */
  82. public function getPemPath(string $path)
  83. {
  84. if (strstr($path, 'http://') === false && strstr($path, 'https://') === false) {
  85. return $path;
  86. } else {
  87. $res = parse_url($path);
  88. return $res['path'] ?? '';
  89. }
  90. }
  91. /**
  92. * 创建订单返回支付参数
  93. * @param string $orderId
  94. * @param string $totalFee
  95. * @param string $attach
  96. * @param string $body
  97. * @param string $detail
  98. * @param array $options
  99. * @return array|false|mixed|string
  100. * @author 等风来
  101. * @email 136327134@qq.com
  102. * @date 2022/9/22
  103. */
  104. public function create(string $orderId, string $totalFee, string $attach, string $body, string $detail, array $options = [])
  105. {
  106. $this->authSetPayType();
  107. switch ($this->payType) {
  108. case Order::NATIVE:
  109. $res = $this->instance->v3pay->nativePay($orderId, $totalFee, $body, $attach);
  110. $res['invalid'] = time() + 60;
  111. $res['logo'] = sys_config('wap_login_logo');
  112. return $res;
  113. case Order::APP:
  114. return $this->instance->v3pay->appPay($orderId, $totalFee, $body, $attach);
  115. case Order::JSAPI:
  116. if (empty($options['openid'])) {
  117. throw new PayException('缺少openid');
  118. }
  119. if (request()->isRoutine()) {
  120. // 获取配置 判断是否为新支付
  121. if ($options['pay_new_weixin_open']) {
  122. return MiniProgramService::newJsPay($options['openid'], $orderId, $totalFee, $attach, $body, $detail, $options);
  123. }
  124. return $this->instance->v3pay->miniprogPay($options['openid'], $orderId, $totalFee, $body, $attach);
  125. }
  126. return $this->instance->v3pay->jsapiPay($options['openid'], $orderId, $totalFee, $body, $attach);
  127. case 'h5':
  128. return $this->instance->v3pay->h5Pay($orderId, $totalFee, $body, $attach);
  129. default:
  130. throw new PayException('微信支付:支付类型错误');
  131. }
  132. }
  133. /**
  134. * @param string $openid
  135. * @param string $orderId
  136. * @param string $amount
  137. * @param array $options
  138. * @return mixed
  139. * @author 等风来
  140. * @email 136327134@qq.com
  141. * @date 2022/9/22
  142. */
  143. public function merchantPay(string $openid, string $orderId, string $amount, array $options = [])
  144. {
  145. return $this->instance->v3pay->setType($options['type'])->batches(
  146. $orderId,
  147. $amount,
  148. $options['batch_name'],
  149. $options['batch_remark'],
  150. [
  151. [
  152. 'out_detail_no' => $orderId,
  153. 'transfer_amount' => $amount,
  154. 'transfer_remark' => $options['batch_remark'],
  155. 'openid' => $openid
  156. ]
  157. ]
  158. );
  159. }
  160. /**
  161. * 发起退款
  162. * @param string $outTradeNo
  163. * @param array $options
  164. * @return mixed
  165. */
  166. public function refund(string $outTradeNo, array $options = [])
  167. {
  168. return $this->instance->v3pay->refund($outTradeNo, $options);
  169. }
  170. /**
  171. * 查询退款
  172. * @param string $outTradeNo
  173. * @param string|null $outRequestNo
  174. * @param array $other
  175. * @return mixed
  176. */
  177. public function queryRefund(string $outTradeNo, string $outRequestNo = null, array $other = [])
  178. {
  179. return $this->instance->v3pay->queryRefund($outTradeNo);
  180. }
  181. /**
  182. * @return mixed|\think\Response
  183. * @author 等风来
  184. * @email 136327134@qq.com
  185. * @date 2022/9/22
  186. */
  187. public function handleNotify()
  188. {
  189. return $this->instance->v3pay->handleNotify(function ($notify, $successful) {
  190. if ($successful) {
  191. $data = [
  192. 'attach' => $notify->attach,
  193. 'out_trade_no' => $notify->out_trade_no,
  194. 'transaction_id' => $notify->transaction_id
  195. ];
  196. return Event::until('NotifyListener', [$data, PayServices::WEIXIN_PAY]);
  197. }
  198. return false;
  199. });
  200. }
  201. }