WechatPayCodePay.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * Name: 芸众商城系统
  5. * Author: 广州市芸众信息科技有限公司
  6. * Profile: 广州市芸众信息科技有限公司位于国际商贸中心的广州,专注于移动电子商务生态系统打造,拥有芸众社交电商系统、区块链数字资产管理系统、供应链管理系统、电子合同等产品/服务。官网 :www.yunzmall.com www.yunzshop.com
  7. * Date: 2022/6/28
  8. * Time: 13:53
  9. */
  10. namespace app\common\services\payment;
  11. use app\common\exceptions\AppException;
  12. use app\common\facades\EasyWeChat;
  13. use app\common\helpers\Client;
  14. use app\common\helpers\Url;
  15. use app\common\services\Pay;
  16. use app\common\services\PayFactory;
  17. use app\common\services\WechatPay;
  18. use app\frontend\modules\order\services\OrderPaySuccessService;
  19. class WechatPayCodePay extends Pay
  20. {
  21. /**
  22. * 创建支付对象
  23. */
  24. public function getEasyWeChatApp($pay, $notify_url)
  25. {
  26. $options = [
  27. 'app_id' => $pay['weixin_appid'],
  28. 'secret' => $pay['weixin_secret'],
  29. 'mch_id' => $pay['weixin_mchid'],
  30. 'key' => $pay['weixin_apisecret'],
  31. 'cert_path' => $pay['weixin_cert'],
  32. 'key_path' => $pay['weixin_key'],
  33. 'notify_url' => $notify_url
  34. ];
  35. $app = EasyWeChat::payment($options);
  36. return $app;
  37. }
  38. public function doPay($data)
  39. {
  40. $pay = \Setting::get('shop.pay');
  41. if (empty($pay['weixin_mchid']) || empty($pay['weixin_apisecret'])
  42. || empty($pay['weixin_appid']) || empty($pay['weixin_secret'])) {
  43. throw new AppException('没有设定支付参数');
  44. }
  45. $data['auth_code'] = request()->auth_code;
  46. if (empty($data['auth_code'])) {
  47. throw new AppException('无法获取用户条码或者二维码信息');
  48. }
  49. $op = '微信付款码支付-订单号:' . $data['order_no'];
  50. $pay_order_model = $this->log($data['extra']['type'], '微信付款码支付', $data['amount'], $op, $data['order_no'], Pay::ORDER_STATUS_NON, \YunShop::app()->getMemberId());
  51. $this->setParameter('auth_code', $data['auth_code']); //设备读取用户微信中的条码或者二维码信息
  52. $this->setParameter('sign_type', 'MD5');
  53. $this->setParameter('trade_type', 'MICROPAY'); //微信付款码支付的交易类型为MICROPAY
  54. $this->setParameter('nonce_str', str_random(16));
  55. $this->setParameter('body', mb_substr($data['subject'], 0, 120));
  56. $this->setParameter('attach', \YunShop::app()->uniacid);
  57. $this->setParameter('out_trade_no', $data['order_no']);
  58. $this->setParameter('total_fee', $data['amount'] * 100); // 单位:分
  59. $this->setParameter('spbill_create_ip', self::getClientIP());
  60. //请求数据日志
  61. self::payRequestDataLog($data['order_no'], $pay_order_model->type,
  62. $pay_order_model->third_type, $this->getAllParameters());
  63. $notify_url = Url::shopSchemeUrl('payment/wechat/notifyUrl.php');
  64. $payment = $this->getEasyWeChatApp($pay, $notify_url);
  65. $result = $payment->order->microPay($this->getAllParameters());
  66. \Log::debug('--微信付款码支付--',$result);
  67. if(!empty($result) && ("SUCCESS" == $result['return_code']) && ("USERPAYING" == $result['err_code'])) {
  68. $max_time = time() + 30;
  69. $is_success = false;
  70. $return_msg = '';
  71. while (time() < $max_time && !$is_success){
  72. sleep(3);
  73. $check_result = $payment->order->queryByOutTradeNumber($this->getParameter('out_trade_no'));
  74. if(in_array($check_result['trade_state'],['REFUND','CLOSED','REVOKED','PAYERROR'])){
  75. $msg = '支付失败';
  76. if ($result['return_code']) $msg .= ",code:{$result['return_code']}";
  77. if ($result['return_msg']) $msg .= ",msg:{$result['return_msg']}";
  78. throw new AppException($msg);
  79. }
  80. if ($check_result['return_code'] == 'SUCCESS' && $check_result['result_code'] == 'SUCCESS'
  81. && $check_result['trade_state'] == 'SUCCESS' && $check_result['trade_type'] == 'MICROPAY'){
  82. $result = $check_result;
  83. $is_success = true;
  84. }else{
  85. $return_msg = $check_result['$return_msg'] ? : '';
  86. }
  87. }
  88. if (!$is_success){
  89. throw new AppException($return_msg ? : '支付失败');
  90. }
  91. }
  92. $this->payResponseDataLog($result['out_trade_no'], '微信付款码支付', json_encode($result));
  93. if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS' && $result['trade_type'] == 'MICROPAY') {
  94. $data = [
  95. 'total_fee' => $result['total_fee'] ,
  96. 'out_trade_no' => $result['out_trade_no'],
  97. 'trade_no' => $result['transaction_id'],
  98. 'unit' => 'fen',
  99. 'pay_type' => '微信支付(付款码)',
  100. 'pay_type_id' => PayFactory::WECHAT_MICRO_PAY,
  101. ];
  102. $res = (new OrderPaySuccessService())->payResutl($data);
  103. if (!$res['result']){
  104. throw new AppException($res['msg']);
  105. }
  106. return true;
  107. } else{
  108. $msg = '支付失败';
  109. if ($result['return_code']) $msg .= ",code:{$result['return_code']}";
  110. if ($result['return_msg']) $msg .= ",msg:{$result['return_msg']}";
  111. throw new AppException($msg);
  112. }
  113. }
  114. /**
  115. * @param \app\common\services\订单号 $out_trade_no
  116. * @param \app\common\services\订单总金额 $totalmoney
  117. * @param \app\common\services\退款金额 $refundmoney
  118. * @return array|mixed
  119. * @throws AppException
  120. */
  121. public function doRefund($out_trade_no, $totalmoney, $refundmoney)
  122. {
  123. return (new WechatPay)->doRefund($out_trade_no, $totalmoney, $refundmoney);
  124. }
  125. public function doWithdraw($member_id, $out_trade_no, $money, $desc, $type)
  126. {
  127. // TODO: Implement doWithdraw() method.
  128. }
  129. public function buildRequestSign()
  130. {
  131. // TODO: Implement buildRequestSign() method.
  132. }
  133. }