WechatFacePayService.php 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. <?php
  2. /**
  3. * Author: 芸众商城 www.yunzshop.com
  4. * Date: 2019/6/3
  5. * Time: 下午3:10
  6. */
  7. namespace app\common\services\wechat;
  8. use app\common\exceptions\AppException;
  9. use app\common\helpers\Url;
  10. use app\common\models\McMappingFans;
  11. use app\common\services\Pay;
  12. use app\common\models\OrderPay;
  13. use app\common\models\PayType;
  14. use app\common\services\wechat\lib\WxPayApi;
  15. use app\common\services\wechat\lib\WxPayConfig;
  16. use app\common\services\wechat\lib\WxPayFacePay;
  17. use app\common\services\wechat\lib\WxPayMicroPay;
  18. class WechatFacePayService extends Pay
  19. {
  20. public $set = null;
  21. public $config = null;
  22. public function __construct()
  23. {
  24. $this->config = new WxPayConfig();
  25. $this->set = $set = \Setting::get('shop.wechat_set');
  26. }
  27. /**
  28. * 支付
  29. * @param array $data
  30. * @return mixed|string
  31. * @throws AppException
  32. * @throws \app\common\services\wechat\lib\WxPayException
  33. */
  34. public function doPay($data = [])
  35. {
  36. // if (\YunShop::request()->type != 9) {
  37. // throw new AppException('不是商家APP 微信扫码支付不可用');
  38. // }
  39. $op = '微信扫码支付 订单号:' . $data['order_no'];
  40. $pay_order_model = $this->log(1, '微信扫码支付', $data['amount'], $op, $data['order_no'], Pay::ORDER_STATUS_NON, $this->getMemberId());
  41. /* 支付请求对象 */
  42. $wxPay = new WxPayFacePay();
  43. //设置商品或支付单简要描述
  44. $wxPay->SetBody($data['body']);
  45. //设置商家数据包,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
  46. $wxPay->SetAttach($data['extra']);
  47. //设置商户系统内部的订单号
  48. $wxPay->SetOut_trade_no($data['pay_sn']);
  49. //设置订单总金额
  50. $wxPay->SetTotal_fee($data['amount']);
  51. //设置扫码支付授权码
  52. $wxPay->SetFace_code($data['face_code']);
  53. $wxPay->SetOpenid($data['openid']);
  54. $wxPay->SetDevice_info($data['device_info']);
  55. $response = WxPayApi::facepay(new WxPayConfig(), $wxPay);
  56. //设置支付参数
  57. if ($response['result_code'] != 'SUCCESS') {
  58. // todo 订单取消
  59. throw new AppException('微信支付失败:'.$response['return_msg']);
  60. }
  61. //请求数据日志
  62. self::payRequestDataLog($data['order_no'], $pay_order_model->type,
  63. $pay_order_model->third_type, json_encode($response));
  64. return $response;
  65. }
  66. /**
  67. * 汇聚支付-单笔提现
  68. *
  69. * @param \app\common\services\提现者用户ID $member_id
  70. * @param \app\common\services\提现批次单号 $out_trade_no
  71. * @param \app\common\services\提现金额 $money
  72. * @param \app\common\services\提现说明 $desc
  73. * @param \app\common\services\只针对微信 $type
  74. * @return mixed
  75. * @throws AppException
  76. */
  77. public function doWithdraw($member_id, $out_trade_no, $money, $desc, $type)
  78. {
  79. $bank = \Setting::getNotUniacid('plugin.convergePay_set_bankcard');
  80. $op = '汇聚支付提现 订单号:' . $out_trade_no . '提现金额:' . $money;
  81. $pay_order_model = $this->withdrawlog(Pay::PAY_TYPE_WITHDRAW, '汇聚提现', $money, $op, $out_trade_no, Pay::ORDER_STATUS_NON, $member_id);
  82. /* 支付请求对象 */
  83. $this->setKey($this->set['hmacVal']);
  84. $this->setGateUrl('https://www.joinpay.com/payment/pay/singlePay');
  85. //设置支付参数
  86. $this->setParameter("userNo", $this->set['MerchantNo']);
  87. $this->setParameter("productCode", $this->set['payment']['productCode']);
  88. $this->setParameter("requestTime", date('Y-m-d h:i:s'));
  89. $this->setParameter("merchantOrderNo", $out_trade_no . 'H' . \YunShop::app()->uniacid);
  90. $this->setParameter("receiverAccountNoEnc", $bank['receiverAccountNoEnc']);
  91. $this->setParameter("receiverNameEnc", $bank['receiverNameEnc']);
  92. $this->setParameter("receiverAccountType", $bank['receiverAccountType']);
  93. $bank['receiverAccountType'] == 204 ? $this->setParameter("receiverBankChannelNo", $bank['receiverBankChannelNo']) : null;
  94. $this->setParameter("paidAmount", sprintf("%.2f", $money));
  95. $this->setParameter("currency", $this->set['payment']['currency']);
  96. //todo 不需要复核
  97. $this->setParameter("isChecked", 202);
  98. $this->setParameter("paidDesc", mb_substr($desc, 0, 24));
  99. $this->setParameter("paidUse", $this->set['payment']['paidUse']);
  100. $this->setParameter("callbackUrl", $this->notifyWithdrawUrl);
  101. $this->set['payment']['productCode'] == 'BANK_PAY_COMPOSE_ORDER' ? $this->setParameter("firstProductCode", "") : null;
  102. $this->setParameter("hmac", md5($this->parameters['userNo'] . $this->parameters['productCode']
  103. . $this->parameters['requestTime'] . $this->parameters['merchantOrderNo'] . $this->parameters['receiverAccountNoEnc']
  104. . $this->parameters['receiverNameEnc'] . $this->parameters['receiverAccountType'] . $this->parameters['receiverBankChannelNo']
  105. . $this->parameters['paidAmount'] . $this->parameters['currency'] . $this->parameters['isChecked'] . $this->parameters['paidDesc']
  106. . $this->parameters['paidUse'] . $this->parameters['callbackUrl'] . $this->parameters['firstProductCode']
  107. . $this->getKey()));
  108. //请求数据日志
  109. self::payRequestDataLog($out_trade_no, $pay_order_model->type,
  110. $pay_order_model->type, json_encode($this->parameters));
  111. return $this->getWithdrawRequestURL($pay_order_model, $out_trade_no);
  112. }
  113. /**
  114. * 获取微信用户 OpenId
  115. *
  116. * @return mixed
  117. */
  118. public function getOpenId()
  119. {
  120. return McMappingFans::getFansById($this->getMemberId())['openid'];
  121. }
  122. /**
  123. * 获取前台会员登录 ID
  124. *
  125. * @return int
  126. */
  127. public function getMemberId()
  128. {
  129. return \YunShop::app()->getMemberId() ? : 0;
  130. }
  131. /**
  132. * 汇聚-微信或支付宝退款
  133. *
  134. * @param \app\common\services\订单号 $out_trade_no
  135. * @param \app\common\services\订单总金额 $totalmoney
  136. * @param \app\common\services\退款金额和退款原因 $refundmoney
  137. * @return bool|mixed
  138. * @throws AppException
  139. */
  140. public function doRefund($out_trade_no, $totalmoney, $refundmoney)
  141. {
  142. $this->setKey($this->set['hmacVal']);
  143. $out_refund_no = $this->setUniacidNo(\YunShop::app()->uniacid);
  144. $op = '汇聚-微信或支付宝退款 订单号:' . $out_trade_no . '退款单号:' . $out_refund_no . '退款总金额:' . $refundmoney['price'];
  145. $pay_type_id = OrderPay::get_paysn_by_pay_type_id($out_trade_no);
  146. $pay_type_name = PayType::get_pay_type_name($pay_type_id);
  147. $pay_order_model = $this->refundlog(Pay::PAY_TYPE_REFUND, $pay_type_name, $refundmoney['price'], $op, $out_trade_no, Pay::ORDER_STATUS_NON, 0);
  148. //设置支付参数
  149. //head
  150. $this->setParameter("p1_MerchantNo", $this->set['MerchantNo']);
  151. $this->setParameter("p2_OrderNo", $out_trade_no. ':' . \YunShop::app()->uniacid);
  152. $this->setParameter("p3_RefundOrderNo", $out_trade_no. ':' . \YunShop::app()->uniacid);
  153. $this->setParameter("p4_RefundAmount", sprintf("%.2f", $refundmoney['price']));
  154. $this->setParameter("p5_RefundReason", $refundmoney['reason']);
  155. $this->setParameter("p6_NotifyUrl", $this->refundUrlWechat);
  156. $this->setParameter("hmac", md5($this->parameters['p1_MerchantNo'] . $this->parameters['p2_OrderNo']
  157. . $this->parameters['p3_RefundOrderNo'] . $this->parameters['p4_RefundAmount'] . $this->parameters['p5_RefundReason']
  158. . $this->parameters['p6_NotifyUrl'] . $this->getKey()));
  159. $this->setGateUrl('https://www.joinpay.com/trade/refund.action');
  160. //请求数据日志
  161. self::payRequestDataLog($out_trade_no, $pay_order_model->type,
  162. $pay_order_model->type, json_encode($this->parameters));
  163. return $this->getRefundRequestUrl($pay_order_model, $out_trade_no);
  164. }
  165. /**
  166. * 构造签名
  167. *
  168. * @return mixed
  169. */
  170. function buildRequestSign()
  171. {
  172. // TODO: Implement buildRequestSign() method.
  173. }
  174. /**
  175. *获取带参数的请求URL
  176. */
  177. function getRequestURL() {
  178. $this->buildRequestSign();
  179. $reqPar =json_encode($this->parameters);
  180. \Log::debug('-----请求参数----', $reqPar);
  181. $requestURL = $this->getGateURL() . "?data=".base64_encode($reqPar);
  182. return $requestURL;
  183. }
  184. }