WatchPay.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <?php
  2. namespace app\common\server;
  3. use think\facade\Log;
  4. /**
  5. * 微信支付
  6. *
  7. * @author wj
  8. * @date 2022-12-02
  9. */
  10. /*
  11. 统一下订单回执
  12. <xml>
  13.   <return_code><![CDATA[SUCCESS]]></return_code>
  14.   <return_msg><![CDATA[OK]]></return_msg>
  15.   <result_code><![CDATA[SUCCESS]]></result_code>
  16.   <mch_id><![CDATA[10000100]]></mch_id>
  17.   <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
  18.   <sub_mch_id><![CDATA[375907253]]></sub_mch_id>
  19.   <device_info><![CDATA[123001]]></device_info>
  20.   <nonce_str><![CDATA[mb8t557HOLqv0soV]]></nonce_str>
  21.   <sign><![CDATA[A530CC111F66A1A6B040D4923E2D2726]]></sign>
  22.   <prepay_id><![CDATA[wx04025233661291269e5f7daa32c5aa0000]]></prepay_id>
  23.   <trade_type><![CDATA[APP]]></trade_type>
  24. </xml>
  25. */
  26. class WatchPay
  27. {
  28. //统一下单api路径
  29. private $unifiedorderurl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
  30. //水猫工匠商户信息
  31. /*private $config = [
  32. 'appid' => "wxcacf6eb6e7478e29",
  33. 'appidApp' => "wxe554be4a48e92d5a",
  34. 'MCHID' => '1616316171',
  35. 'KEY' => "WaterCat20211001ShuiMaoGongJiang",
  36. ];*/
  37. /**
  38. * 易益康养商户信息
  39. *
  40. * @var array
  41. * @author wj
  42. * @date 2023-02-18
  43. */
  44. private $config = [
  45. 'appid' => '',
  46. 'appidApp' => "wxea0b365a48661060",
  47. 'MCHID' => "1638159037",
  48. 'KEY' => "yOT6Rn0LfhLZoAtpDPkqkIQHBfqfNJJ4",
  49. ];
  50. public function setConfig($config)
  51. {
  52. foreach ($this->$config as $key => $value) {
  53. if (empty($value) != $config[$key]) {
  54. $this->config[$key] = $config[$key];
  55. }
  56. }
  57. }
  58. public function getConfig($field)
  59. {
  60. if (isset($this->config[$field])) {
  61. return $this->config[$field];
  62. }
  63. return false;
  64. }
  65. /**
  66. * 获取订单信息
  67. *
  68. * @return void
  69. * @author wj
  70. * @date 2022-12-02
  71. */
  72. public function getorderinfo($orderInfo)
  73. {
  74. $config = $this->config;
  75. $mchid = $config['MCHID'];
  76. $key = $config['KEY'];
  77. $body = $orderInfo['body'];
  78. $total_fee = $orderInfo['total_fee'];
  79. $notify_url = $orderInfo['notify_url'];
  80. //$appid = $config['appid'];
  81. $ordrNo = $orderInfo['orderNo'];
  82. $trade_type = $orderInfo['trade_type'];
  83. $appid = $orderInfo['appid'];
  84. $data = [
  85. "appid" => $appid, //服务商应用ID
  86. "mch_id" => $mchid, //服务商应用ID
  87. "nonce_str" => md5($mchid . time()),
  88. "body" => $body,
  89. "out_trade_no" => $ordrNo,
  90. "notify_url" => $notify_url,
  91. "total_fee" => $total_fee,
  92. //"currency" => "CNY",
  93. "spbill_create_ip" => '8.8.8.8',
  94. 'trade_type' => $trade_type,
  95. ];
  96. if (isset($orderInfo['openid'])) {
  97. $openid = $orderInfo['openid'];
  98. $data['openid'] = $openid;
  99. }
  100. ksort($data);
  101. $sign_str = $this->ToUrlParams($data);
  102. $sign_str = $sign_str . "&key=" . $key;
  103. $data['sign'] = strtoupper(md5($sign_str));
  104. return $data;
  105. }
  106. /**
  107. * 创建订单 统一下单
  108. *
  109. * @param [type] $orderinfo
  110. * @return void
  111. * @author wj
  112. * @date 2022-12-02
  113. */
  114. public function crateOrder($orderinfo)
  115. {
  116. $data = $this->getorderinfo($orderinfo);
  117. Log::info($data);
  118. $xml = arrtoxml($data, null, 'xml');
  119. //$xml = $this->arrayToXml($data);
  120. $url = $this->unifiedorderurl;
  121. Log::info($url);
  122. Log::info($xml);
  123. $resultxml = $this->postXmlCurl($xml, $url, true);
  124. $result = $this->getpayback($resultxml);
  125. return $result;
  126. }
  127. /**
  128. * 解析并记录返回的xml
  129. *
  130. * @param [type] $xml
  131. * @return void
  132. * @author wj
  133. * @date 2022-12-02
  134. */
  135. public function getpayback($xml)
  136. {
  137. Log::info($xml);
  138. $result = xmltoarr($xml);
  139. Log::info($result);
  140. return $result;
  141. }
  142. /*
  143. * 用于微信支付转换认证的信息用的
  144. * by:leoyi
  145. * date:2018-4-8
  146. */
  147. public function ToUrlParams($data)
  148. {
  149. $buff = "";
  150. foreach ($data as $k => $v) {
  151. if ($k != "sign" && $v != "" && !is_array($v)) {
  152. $buff .= $k . "=" . $v . "&";
  153. }
  154. }
  155. $buff = trim($buff, "&");
  156. return $buff;
  157. }
  158. /**
  159. * 用户post方法请求xml信息用的
  160. * @author write by leoyi 2018-04-8
  161. */
  162. public function postXmlCurl($xml, $url, $useCert = false, $second = 10)
  163. {
  164. $ch = curl_init();
  165. //设置超时
  166. curl_setopt($ch, CURLOPT_TIMEOUT, $second);
  167. curl_setopt($ch, CURLOPT_URL, $url);
  168. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  169. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //严格校验2
  170. //设置header
  171. curl_setopt($ch, CURLOPT_HEADER, false);
  172. //要求结果为字符串且输出到屏幕上
  173. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  174. curl_setopt($ch, CURLOPT_POST, true);
  175. curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
  176. //运行curl
  177. $data = curl_exec($ch);
  178. //返回结果
  179. if ($data) {
  180. curl_close($ch);
  181. return $data;
  182. } else {
  183. $error = curl_errno($ch);
  184. curl_close($ch);
  185. return $error;
  186. }
  187. }
  188. /**
  189. * 获取签名
  190. *
  191. * @return void
  192. * @author wj
  193. * @date 2022-12-02
  194. */
  195. public function getsign($data)
  196. {
  197. ksort($data);
  198. $sign_str = $this->ToUrlParams($data);
  199. $sign_str = $sign_str . "&key=" . $this->config['KEY'];
  200. $sign = strtoupper(md5($sign_str));
  201. return $sign;
  202. }
  203. public function arrayToXml($arr)
  204. {
  205. $xml = "<xml>";
  206. foreach ($arr as $key => $val) {
  207. if (is_numeric($val)) {
  208. $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
  209. } else {
  210. $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
  211. }
  212. }
  213. $xml .= "</xml>";
  214. return $xml;
  215. }
  216. }