PayService.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. <?php
  2. namespace app\common\library\xmwechat\payment;
  3. use app\common\library\xmwechat\SingletonTrait;
  4. use app\common\library\xmwechat\WechatService;
  5. use EasyWeChat\Pay\Application;
  6. use Symfony\Component\HttpClient\Exception\ClientException;
  7. use Symfony\Component\HttpClient\Exception\ServerException;
  8. use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
  9. use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
  10. use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
  11. use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
  12. use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
  13. /**
  14. * 微信支付
  15. */
  16. class PayService extends WechatService
  17. {
  18. protected ?Application $app = null;
  19. use SingletonTrait;
  20. public function __construct()
  21. {
  22. parent::__construct();
  23. if (empty($this->wechatPayConfig['mch_id']) || empty($this->wechatPayConfig['secret_key'])) {
  24. $this->result('请配置商户号或商户密钥Key');
  25. }
  26. $payConfig = [
  27. 'mch_id' => $this->wechatPayConfig['mch_id'],
  28. 'secret_key' => $this->wechatPayConfig['secret_key'],
  29. 'certificate' => root_path() . $this->wechatPayConfig['certificate'],
  30. 'private_key' => root_path() . $this->wechatPayConfig['private_key'],
  31. 'notify_url' => $this->wechatPayConfig['notify_url'],
  32. 'http' => [
  33. 'throw' => true, // 状态码非 200、300 时是否抛出异常,默认为开启
  34. 'timeout' => 5.0,
  35. ],
  36. ];
  37. $this->app = new Application($payConfig);
  38. }
  39. /**
  40. * 微信公众号、小程序发起支付
  41. * @return bool|array
  42. * @throws ClientExceptionInterface
  43. * @throws DecodingExceptionInterface
  44. * @throws RedirectionExceptionInterface
  45. * @throws ServerExceptionInterface
  46. * @throws TransportExceptionInterface
  47. * @throws \Exception
  48. * @author jsjxsz
  49. */
  50. public function pay($params): bool|array
  51. {
  52. try {
  53. // order_no:订单号,body:描述,pay_price:支付金额, openid:当前用户openid
  54. $order_no = $params['order_no'];
  55. $response = $this->app->getClient()->postJson("/v3/pay/transactions/jsapi", [
  56. "mchid" => $this->wechatPayConfig['mch_id'],
  57. "out_trade_no" => $params['transaction_no'],// 交易号
  58. "appid" => $this->miniProgramConfig['app_id'],
  59. "description" => $params['body'],
  60. "notify_url" => $this->wechatPayConfig['notify_url'],
  61. "amount" => [
  62. "total" => intval($params['pay_price'] * 100),
  63. "currency" => "CNY"
  64. ],
  65. "payer" => [
  66. "openid" => $params['openid']
  67. ]
  68. ]);
  69. $result = $response->toArray();
  70. if (!empty($result['prepay_id'])) {
  71. $prepayId = $result['prepay_id'];
  72. $utils = $this->app->getUtils();
  73. //微信小程序appid; 公众号支付需用公众号appid
  74. $appId = $params['pay_type'] == 'miniProgram' ? $this->miniProgramConfig['app_id'] : $this->offiAccountConfig['app_id'];
  75. // 默认RSA,v2要传MD5
  76. $signType = 'RSA';
  77. $payResult = $utils->buildBridgeConfig($prepayId, $appId, $signType);
  78. if (isset($payResult['paySign']) && !empty($payResult['paySign'])) {
  79. // 若有逻辑 这里写你自己的逻辑
  80. // 此接口不代表支付成功,只是给客户端提供参数,调起支付
  81. // 支付成功逻辑处理请在支付回调接口处理
  82. // 此参数返回客户端,客户端拿到参数调起支付
  83. return $payResult;
  84. }
  85. }
  86. return false;
  87. } catch (ServerException|ClientException $err) {
  88. $this->result($err->getResponse()->getContent(false));
  89. } catch (\Exception $exception) {
  90. $this->result($exception->getMessage());
  91. }
  92. }
  93. }