You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

959 lines
25 KiB

7 years ago
  1. <?php
  2. /**
  3. * 微信支付帮助库
  4. * ====================================================
  5. * 接口分三种类型:
  6. * 【请求型接口】--Wxpay_client_
  7. * 统一支付接口类--UnifiedOrder
  8. * 订单查询接口--OrderQuery
  9. * 退款申请接口--Refund
  10. * 退款查询接口--RefundQuery
  11. * 对账单接口--DownloadBill
  12. * 短链接转换接口--ShortUrl
  13. * 【响应型接口】--Wxpay_server_
  14. * 通用通知接口--Notify
  15. * Native支付——请求商家获取商品信息接口--NativeCall
  16. * 【其他】
  17. * 静态链接二维码--NativeLink
  18. * JSAPI支付--JsApi
  19. * =====================================================
  20. * 【CommonUtil】常用工具:
  21. * trimString(),设置参数时需要用到的字符处理函数
  22. * createNoncestr(),产生随机字符串,不长于32位
  23. * formatBizQueryParaMap(),格式化参数,签名过程需要用到
  24. * getSign(),生成签名
  25. * arrayToXml(),array转xml
  26. * xmlToArray(),xml转 array
  27. * postXmlCurl(),以post方式提交xml到对应的接口url
  28. * postXmlSSLCurl(),使用证书,以post方式提交xml到对应的接口url
  29. */
  30. include_once("SDKRuntimeException.class.php");
  31. /**
  32. * 所有接口的基类
  33. */
  34. class Common_util_pub
  35. {
  36. public $wxconfig;
  37. public function __construct($wxconfig)
  38. {
  39. $this->wxconfig=$wxconfig;
  40. }
  41. function trimString($value)
  42. {
  43. $ret = null;
  44. if (null != $value)
  45. {
  46. $ret = $value;
  47. if (strlen($ret) == 0)
  48. {
  49. $ret = null;
  50. }
  51. }
  52. return $ret;
  53. }
  54. /**
  55. * 作用:产生随机字符串,不长于32位
  56. */
  57. public function createNoncestr( $length = 32 )
  58. {
  59. $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
  60. $str ="";
  61. for ( $i = 0; $i < $length; $i++ )
  62. {
  63. $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
  64. }
  65. return $str;
  66. }
  67. /**
  68. * 作用:格式化参数,签名过程需要使用
  69. */
  70. function formatBizQueryParaMap($paraMap, $urlencode)
  71. {
  72. $buff = "";
  73. ksort($paraMap);
  74. foreach ($paraMap as $k => $v)
  75. {
  76. if($urlencode)
  77. {
  78. $v = urlencode($v);
  79. }
  80. //$buff .= strtolower($k) . "=" . $v . "&";
  81. $buff .= $k . "=" . $v . "&";
  82. }
  83. $reqPar = "";
  84. if (strlen($buff) > 0)
  85. {
  86. $reqPar = substr($buff, 0, strlen($buff)-1);
  87. }
  88. return $reqPar;
  89. }
  90. /**
  91. * 作用:生成签名
  92. */
  93. public function getSign($Obj)
  94. {
  95. foreach ($Obj as $k => $v)
  96. {
  97. $Parameters[$k] = $v;
  98. }
  99. //签名步骤一:按字典序排序参数
  100. ksort($Parameters);
  101. $String = $this->formatBizQueryParaMap($Parameters, false);
  102. //echo '【string1】'.$String.'</br>';
  103. //签名步骤二:在string后加入KEY
  104. $String = $String."&key=".$this->wxconfig['KEY'];
  105. //echo "【string2】".$String."</br>";
  106. //签名步骤三:MD5加密
  107. $String = md5($String);
  108. //echo "【string3】 ".$String."</br>";
  109. //签名步骤四:所有字符转为大写
  110. $result_ = strtoupper($String);
  111. //echo "【result】 ".$result_."</br>";
  112. return $result_;
  113. }
  114. /**
  115. * 作用:array转xml
  116. */
  117. function arrayToXml($arr)
  118. {
  119. $xml = "<xml>";
  120. foreach ($arr as $key=>$val)
  121. {
  122. if (is_numeric($val))
  123. {
  124. $xml.="<".$key.">".$val."</".$key.">";
  125. }
  126. else
  127. $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
  128. }
  129. $xml.="</xml>";
  130. return $xml;
  131. }
  132. /**
  133. * 作用:将xml转为array
  134. */
  135. public function xmlToArray($xml)
  136. {
  137. //将XML转为array
  138. $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
  139. return $array_data;
  140. }
  141. /**
  142. * 作用:以post方式提交xml到对应的接口url
  143. */
  144. public function postXmlCurl($xml,$url,$second=30)
  145. {
  146. //初始化curl
  147. $ch = curl_init();
  148. //设置超时
  149. curl_setopt($ch, CURLOP_TIMEOUT, $second);
  150. //这里设置代理,如果有的话
  151. //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
  152. //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
  153. curl_setopt($ch,CURLOPT_URL, $url);
  154. curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
  155. curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
  156. //设置header
  157. curl_setopt($ch, CURLOPT_HEADER, FALSE);
  158. //要求结果为字符串且输出到屏幕上
  159. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  160. //post提交方式
  161. curl_setopt($ch, CURLOPT_POST, TRUE);
  162. curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
  163. //运行curl
  164. $data = curl_exec($ch);
  165. curl_close($ch);
  166. //返回结果
  167. if($data)
  168. {
  169. curl_close($ch);
  170. return $data;
  171. }
  172. else
  173. {
  174. $error = curl_errno($ch);
  175. echo "curl出错,错误码:$error"."<br>";
  176. echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";
  177. curl_close($ch);
  178. return false;
  179. }
  180. }
  181. /**
  182. * 作用:使用证书,以post方式提交xml到对应的接口url
  183. */
  184. function postXmlSSLCurl($xml,$url,$second=30)
  185. {
  186. $ch = curl_init();
  187. //超时时间
  188. curl_setopt($ch,CURLOPT_TIMEOUT,$second);
  189. //这里设置代理,如果有的话
  190. //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
  191. //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
  192. curl_setopt($ch,CURLOPT_URL, $url);
  193. curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
  194. curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
  195. //设置header
  196. curl_setopt($ch,CURLOPT_HEADER,FALSE);
  197. //要求结果为字符串且输出到屏幕上
  198. curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
  199. //设置证书
  200. //使用证书:cert 与 key 分别属于两个.pem文件
  201. //默认格式为PEM,可以注释
  202. curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
  203. curl_setopt($ch,CURLOPT_SSLCERT, $this->wxconfig['SSLCERT_PATH']);
  204. //默认格式为PEM,可以注释
  205. curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
  206. curl_setopt($ch,CURLOPT_SSLKEY, $this->wxconfig['SSLKEY_PATH']);
  207. //post提交方式
  208. curl_setopt($ch,CURLOPT_POST, true);
  209. curl_setopt($ch,CURLOPT_POSTFIELDS,$xml);
  210. $data = curl_exec($ch);
  211. //返回结果
  212. if($data){
  213. curl_close($ch);
  214. return $data;
  215. }
  216. else {
  217. $error = curl_errno($ch);
  218. echo "curl出错,错误码:$error"."<br>";
  219. echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";
  220. curl_close($ch);
  221. return false;
  222. }
  223. }
  224. /**
  225. * 作用:打印数组
  226. */
  227. function printErr($wording='',$err='')
  228. {
  229. print_r('<pre>');
  230. echo $wording."</br>";
  231. var_dump($err);
  232. print_r('</pre>');
  233. }
  234. }
  235. /**
  236. * 请求型接口的基类
  237. */
  238. class Wxpay_client_pub extends Common_util_pub
  239. {
  240. var $parameters;//请求参数,类型为关联数组
  241. public $response;//微信返回的响应
  242. public $result;//返回参数,类型为关联数组
  243. var $url;//接口链接
  244. var $curl_timeout;//curl超时时间
  245. /**
  246. * 作用:设置请求参数
  247. */
  248. function setParameter($parameter, $parameterValue)
  249. {
  250. $this->parameters[$this->trimString($parameter)] = $this->trimString($parameterValue);
  251. }
  252. /**
  253. * 作用:设置标配的请求参数,生成签名,生成接口参数xml
  254. */
  255. function createXml()
  256. {
  257. $this->parameters["appid"] = $this->wxconfig['APPID'];//公众账号ID
  258. $this->parameters["mch_id"] = $this->wxconfig['MCHID'];//商户号
  259. $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
  260. $this->parameters["sign"] = $this->getSign($this->parameters);//签名
  261. return $this->arrayToXml($this->parameters);
  262. }
  263. /**
  264. * 作用:post请求xml
  265. */
  266. function postXml()
  267. {
  268. $xml = $this->createXml();
  269. $this->response = $this->postXmlCurl($xml,$this->url,$this->curl_timeout);
  270. return $this->response;
  271. }
  272. /**
  273. * 作用:使用证书post请求xml
  274. */
  275. function postXmlSSL()
  276. {
  277. $xml = $this->createXml();
  278. $this->response = $this->postXmlSSLCurl($xml,$this->url,$this->curl_timeout);
  279. return $this->response;
  280. }
  281. /**
  282. * 作用:获取结果,默认不使用证书
  283. */
  284. function getResult()
  285. {
  286. $this->postXml();
  287. $this->result = $this->xmlToArray($this->response);
  288. return $this->result;
  289. }
  290. }
  291. /**
  292. * 统一支付接口类
  293. */
  294. class UnifiedOrder_pub extends Wxpay_client_pub
  295. {
  296. function __construct($appconfig)
  297. {
  298. Common_util_pub::__construct($appconfig);
  299. //设置接口链接
  300. $this->url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
  301. //设置curl超时时间
  302. $this->curl_timeout = $this->wxconfig['CURL_TIMEOUT'];
  303. }
  304. /**
  305. * 生成接口参数xml
  306. */
  307. function createXml()
  308. {
  309. try
  310. {
  311. //检测必填参数
  312. if($this->parameters["out_trade_no"] == null)
  313. {
  314. throw new SDKRuntimeException("缺少统一支付接口必填参数out_trade_no!"."<br>");
  315. }elseif($this->parameters["body"] == null){
  316. throw new SDKRuntimeException("缺少统一支付接口必填参数body!"."<br>");
  317. }elseif ($this->parameters["total_fee"] == null ) {
  318. throw new SDKRuntimeException("缺少统一支付接口必填参数total_fee!"."<br>");
  319. }elseif ($this->parameters["notify_url"] == null) {
  320. throw new SDKRuntimeException("缺少统一支付接口必填参数notify_url!"."<br>");
  321. }elseif ($this->parameters["trade_type"] == null) {
  322. throw new SDKRuntimeException("缺少统一支付接口必填参数trade_type!"."<br>");
  323. }elseif ($this->parameters["trade_type"] == "JSAPI" &&
  324. $this->parameters["openid"] == NULL){
  325. throw new SDKRuntimeException("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!"."<br>");
  326. }
  327. $this->parameters["appid"] = $this->wxconfig['APPID'];//公众账号ID
  328. $this->parameters["mch_id"] = $this->wxconfig['MCHID'];//商户号
  329. $this->parameters["spbill_create_ip"] = $_SERVER['REMOTE_ADDR'];//终端ip
  330. $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
  331. $this->parameters["sign"] = $this->getSign($this->parameters);//签名
  332. return $this->arrayToXml($this->parameters);
  333. }
  334. catch (SDKRuntimeException $e)
  335. {
  336. die($e->errorMessage());
  337. }
  338. }
  339. /**
  340. * 获取prepay_id
  341. */
  342. function getPrepayId()
  343. {
  344. $this->postXml();
  345. $this->result = $this->xmlToArray($this->response);
  346. $prepay_id = $this->result["prepay_id"];
  347. return $prepay_id;
  348. }
  349. }
  350. /**
  351. * 订单查询接口
  352. */
  353. class OrderQuery_pub extends Wxpay_client_pub
  354. {
  355. function __construct()
  356. {
  357. //设置接口链接
  358. $this->url = "https://api.mch.weixin.qq.com/pay/orderquery";
  359. //设置curl超时时间
  360. $this->curl_timeout = $this->wxconfig['CURL_TIMEOUT'];
  361. }
  362. /**
  363. * 生成接口参数xml
  364. */
  365. function createXml()
  366. {
  367. try
  368. {
  369. //检测必填参数
  370. if($this->parameters["out_trade_no"] == null &&
  371. $this->parameters["transaction_id"] == null)
  372. {
  373. throw new SDKRuntimeException("订单查询接口中,out_trade_no、transaction_id至少填一个!"."<br>");
  374. }
  375. $this->parameters["appid"] = $this->wxconfig['APPID'];//公众账号ID
  376. $this->parameters["mch_id"] = $this->wxconfig['MCHID'];//商户号
  377. $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
  378. $this->parameters["sign"] = $this->getSign($this->parameters);//签名
  379. return $this->arrayToXml($this->parameters);
  380. }catch (SDKRuntimeException $e)
  381. {
  382. die($e->errorMessage());
  383. }
  384. }
  385. }
  386. /**
  387. * 退款申请接口
  388. */
  389. class Refund_pub extends Wxpay_client_pub
  390. {
  391. function __construct()
  392. {
  393. //设置接口链接
  394. $this->url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
  395. //设置curl超时时间
  396. $this->curl_timeout = $this->wxconfig['CURL_TIMEOUT'];
  397. }
  398. /**
  399. * 生成接口参数xml
  400. */
  401. function createXml()
  402. {
  403. try
  404. {
  405. //检测必填参数
  406. if($this->parameters["out_trade_no"] == null && $this->parameters["transaction_id"] == null) {
  407. throw new SDKRuntimeException("退款申请接口中,out_trade_no、transaction_id至少填一个!"."<br>");
  408. }elseif($this->parameters["out_refund_no"] == null){
  409. throw new SDKRuntimeException("退款申请接口中,缺少必填参数out_refund_no!"."<br>");
  410. }elseif($this->parameters["total_fee"] == null){
  411. throw new SDKRuntimeException("退款申请接口中,缺少必填参数total_fee!"."<br>");
  412. }elseif($this->parameters["refund_fee"] == null){
  413. throw new SDKRuntimeException("退款申请接口中,缺少必填参数refund_fee!"."<br>");
  414. }elseif($this->parameters["op_user_id"] == null){
  415. throw new SDKRuntimeException("退款申请接口中,缺少必填参数op_user_id!"."<br>");
  416. }
  417. $this->parameters["appid"] = $this->wxconfig['APPID'];//公众账号ID
  418. $this->parameters["mch_id"] = $this->wxconfig['MCHID'];//商户号
  419. $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
  420. $this->parameters["sign"] = $this->getSign($this->parameters);//签名
  421. return $this->arrayToXml($this->parameters);
  422. }catch (SDKRuntimeException $e)
  423. {
  424. die($e->errorMessage());
  425. }
  426. }
  427. /**
  428. * 作用:获取结果,使用证书通信
  429. */
  430. function getResult()
  431. {
  432. $this->postXmlSSL();
  433. $this->result = $this->xmlToArray($this->response);
  434. return $this->result;
  435. }
  436. }
  437. /**
  438. * 退款查询接口
  439. */
  440. class RefundQuery_pub extends Wxpay_client_pub
  441. {
  442. function __construct()
  443. {
  444. //设置接口链接
  445. $this->url = "https://api.mch.weixin.qq.com/pay/refundquery";
  446. //设置curl超时时间
  447. $this->curl_timeout = $this->wxconfig['CURL_TIMEOUT'];
  448. }
  449. /**
  450. * 生成接口参数xml
  451. */
  452. function createXml()
  453. {
  454. try
  455. {
  456. if($this->parameters["out_refund_no"] == null &&
  457. $this->parameters["out_trade_no"] == null &&
  458. $this->parameters["transaction_id"] == null &&
  459. $this->parameters["refund_id "] == null)
  460. {
  461. throw new SDKRuntimeException("退款查询接口中,out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个!"."<br>");
  462. }
  463. $this->parameters["appid"] = $this->wxconfig['APPID'];//公众账号ID
  464. $this->parameters["mch_id"] = $this->wxconfig['MCHID'];//商户号
  465. $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
  466. $this->parameters["sign"] = $this->getSign($this->parameters);//签名
  467. return $this->arrayToXml($this->parameters);
  468. }
  469. catch (SDKRuntimeException $e)
  470. {
  471. die($e->errorMessage());
  472. }
  473. }
  474. /**
  475. * 作用:获取结果,使用证书通信
  476. */
  477. function getResult()
  478. {
  479. $this->postXmlSSL();
  480. $this->result = $this->xmlToArray($this->response);
  481. return $this->result;
  482. }
  483. }
  484. /**
  485. * 对账单接口
  486. */
  487. class DownloadBill_pub extends Wxpay_client_pub
  488. {
  489. function __construct()
  490. {
  491. //设置接口链接
  492. $this->url = "https://api.mch.weixin.qq.com/pay/downloadbill";
  493. //设置curl超时时间
  494. $this->curl_timeout = $this->wxconfig['CURL_TIMEOUT'];
  495. }
  496. /**
  497. * 生成接口参数xml
  498. */
  499. function createXml()
  500. {
  501. try
  502. {
  503. if($this->parameters["bill_date"] == null )
  504. {
  505. throw new SDKRuntimeException("对账单接口中,缺少必填参数bill_date!"."<br>");
  506. }
  507. $this->parameters["appid"] = $this->wxconfig['APPID'];//公众账号ID
  508. $this->parameters["mch_id"] = $this->wxconfig['MCHID'];//商户号
  509. $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
  510. $this->parameters["sign"] = $this->getSign($this->parameters);//签名
  511. return $this->arrayToXml($this->parameters);
  512. }
  513. catch (SDKRuntimeException $e)
  514. {
  515. die($e->errorMessage());
  516. }
  517. }
  518. /**
  519. * 作用:获取结果,默认不使用证书
  520. */
  521. function getResult()
  522. {
  523. $this->postXml();
  524. $this->result = $this->xmlToArray($this->result_xml);
  525. return $this->result;
  526. }
  527. }
  528. /**
  529. * 短链接转换接口
  530. */
  531. class ShortUrl_pub extends Wxpay_client_pub
  532. {
  533. function __construct()
  534. {
  535. //设置接口链接
  536. $this->url = "https://api.mch.weixin.qq.com/tools/shorturl";
  537. //设置curl超时时间
  538. $this->curl_timeout = $this->wxconfig['CURL_TIMEOUT'];
  539. }
  540. /**
  541. * 生成接口参数xml
  542. */
  543. function createXml()
  544. {
  545. try
  546. {
  547. if($this->parameters["long_url"] == null )
  548. {
  549. throw new SDKRuntimeException("短链接转换接口中,缺少必填参数long_url!"."<br>");
  550. }
  551. $this->parameters["appid"] = $this->wxconfig['APPID'];//公众账号ID
  552. $this->parameters["mch_id"] = $this->wxconfig['MCHID'];//商户号
  553. $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
  554. $this->parameters["sign"] = $this->getSign($this->parameters);//签名
  555. return $this->arrayToXml($this->parameters);
  556. }catch (SDKRuntimeException $e)
  557. {
  558. die($e->errorMessage());
  559. }
  560. }
  561. /**
  562. * 获取prepay_id
  563. */
  564. function getShortUrl()
  565. {
  566. $this->postXml();
  567. $prepay_id = $this->result["short_url"];
  568. return $prepay_id;
  569. }
  570. }
  571. /**
  572. * 响应型接口基类
  573. */
  574. class Wxpay_server_pub extends Common_util_pub
  575. {
  576. public $data;//接收到的数据,类型为关联数组
  577. var $returnParameters;//返回参数,类型为关联数组
  578. /**
  579. * 将微信的请求xml转换成关联数组,以方便数据处理
  580. */
  581. function saveData($xml)
  582. {
  583. $this->data = $this->xmlToArray($xml);
  584. }
  585. function checkSign()
  586. {
  587. $tmpData = $this->data;
  588. unset($tmpData['sign']);
  589. $sign = $this->getSign($tmpData);//本地签名
  590. if ($this->data['sign'] == $sign) {
  591. return TRUE;
  592. }
  593. return FALSE;
  594. }
  595. /**
  596. * 获取微信的请求数据
  597. */
  598. function getData()
  599. {
  600. return $this->data;
  601. }
  602. /**
  603. * 设置返回微信的xml数据
  604. */
  605. function setReturnParameter($parameter, $parameterValue)
  606. {
  607. $this->returnParameters[$this->trimString($parameter)] = $this->trimString($parameterValue);
  608. }
  609. /**
  610. * 生成接口参数xml
  611. */
  612. function createXml()
  613. {
  614. return $this->arrayToXml($this->returnParameters);
  615. }
  616. /**
  617. * 将xml数据返回微信
  618. */
  619. function returnXml()
  620. {
  621. $returnXml = $this->createXml();
  622. return $returnXml;
  623. }
  624. }
  625. /**
  626. * 通用通知接口
  627. */
  628. class Notify_pub extends Wxpay_server_pub
  629. {
  630. }
  631. /**
  632. * 请求商家获取商品信息接口
  633. */
  634. class NativeCall_pub extends Wxpay_server_pub
  635. {
  636. /**
  637. * 生成接口参数xml
  638. */
  639. function createXml()
  640. {
  641. if($this->returnParameters["return_code"] == "SUCCESS"){
  642. $this->returnParameters["appid"] = $this->wxconfig['APPID'];//公众账号ID
  643. $this->returnParameters["mch_id"] = $this->wxconfig['MCHID'];//商户号
  644. $this->returnParameters["nonce_str"] = $this->createNoncestr();//随机字符串
  645. $this->returnParameters["sign"] = $this->getSign($this->returnParameters);//签名
  646. }
  647. return $this->arrayToXml($this->returnParameters);
  648. }
  649. /**
  650. * 获取product_id
  651. */
  652. function getProductId()
  653. {
  654. $product_id = $this->data["product_id"];
  655. return $product_id;
  656. }
  657. }
  658. /**
  659. * 静态链接二维码
  660. */
  661. class NativeLink_pub extends Common_util_pub
  662. {
  663. var $parameters;//静态链接参数
  664. var $url;//静态链接
  665. function __construct()
  666. {
  667. }
  668. /**
  669. * 设置参数
  670. */
  671. function setParameter($parameter, $parameterValue)
  672. {
  673. $this->parameters[$this->trimString($parameter)] = $this->trimString($parameterValue);
  674. }
  675. /**
  676. * 生成Native支付链接二维码
  677. */
  678. function createLink()
  679. {
  680. try
  681. {
  682. if($this->parameters["product_id"] == null)
  683. {
  684. throw new SDKRuntimeException("缺少Native支付二维码链接必填参数product_id!"."<br>");
  685. }
  686. $this->parameters["appid"] = $this->wxconfig['APPID'];//公众账号ID
  687. $this->parameters["mch_id"] = $this->wxconfig['MCHID'];//商户号
  688. $time_stamp = time();
  689. $this->parameters["time_stamp"] = "$time_stamp";//时间戳
  690. $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
  691. $this->parameters["sign"] = $this->getSign($this->parameters);//签名
  692. $bizString = $this->formatBizQueryParaMap($this->parameters, false);
  693. $this->url = "weixin://wxpay/bizpayurl?".$bizString;
  694. }catch (SDKRuntimeException $e)
  695. {
  696. die($e->errorMessage());
  697. }
  698. }
  699. /**
  700. * 返回链接
  701. */
  702. function getUrl()
  703. {
  704. $this->createLink();
  705. return $this->url;
  706. }
  707. }
  708. /**
  709. * JSAPI支付——H5网页端调起支付接口
  710. */
  711. class JsApi_pub extends Common_util_pub
  712. {
  713. var $code;//code码,用以获取openid
  714. var $openid;//用户的openid
  715. var $parameters;//jsapi参数,格式为json
  716. var $prepay_id;//使用统一支付接口得到的预支付id
  717. var $curl_timeout;//curl超时时间
  718. function __construct($appconfig)
  719. {
  720. Common_util_pub::__construct($appconfig);
  721. //设置curl超时时间
  722. $this->curl_timeout = $this->wxconfig['CURL_TIMEOUT'];
  723. }
  724. /**
  725. * 作用:生成可以获得code的url
  726. */
  727. function createOauthUrlForCode($redirectUrl)
  728. {
  729. $urlObj["appid"] = $this->wxconfig['APPID'];
  730. $urlObj["redirect_uri"] = "$redirectUrl";
  731. $urlObj["response_type"] = "code";
  732. $urlObj["scope"] = "snsapi_base";
  733. $urlObj["state"] = "STATE"."#wechat_redirect";
  734. $bizString = $this->formatBizQueryParaMap($urlObj, false);
  735. return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString;
  736. }
  737. /**
  738. * 作用:生成可以获得openid的url
  739. */
  740. function createOauthUrlForOpenid()
  741. {
  742. $urlObj["appid"] = $this->wxconfig['APPID'];
  743. $urlObj["secret"] = $this->wxconfig['APPSECRET'];
  744. $urlObj["code"] = $this->code;
  745. $urlObj["grant_type"] = "authorization_code";
  746. $bizString = $this->formatBizQueryParaMap($urlObj, false);
  747. return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString;
  748. }
  749. /**
  750. * 作用:通过curl向微信提交code,以获取openid
  751. */
  752. function getOpenid()
  753. {
  754. $url = $this->createOauthUrlForOpenid();
  755. //初始化curl
  756. $ch = curl_init();
  757. //设置超时
  758. curl_setopt($ch, CURLOP_TIMEOUT, $this->curl_timeout);
  759. curl_setopt($ch, CURLOPT_URL, $url);
  760. curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
  761. curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
  762. curl_setopt($ch, CURLOPT_HEADER, FALSE);
  763. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  764. //运行curl,结果以jason形式返回
  765. $res = curl_exec($ch);
  766. curl_close($ch);
  767. //取出openid
  768. $data = json_decode($res,true);
  769. $this->openid = $data['openid'];
  770. return $this->openid;
  771. }
  772. /**
  773. * 作用:设置prepay_id
  774. */
  775. function setPrepayId($prepayId)
  776. {
  777. $this->prepay_id = $prepayId;
  778. }
  779. /**
  780. * 作用:设置code
  781. */
  782. function setCode($code_)
  783. {
  784. $this->code = $code_;
  785. }
  786. /**
  787. * 作用:设置jsapi的参数
  788. */
  789. public function getParameters()
  790. {
  791. $jsApiObj["appId"] = $this->wxconfig['APPID'];
  792. $timeStamp = time();
  793. $jsApiObj["timeStamp"] = "$timeStamp";
  794. $jsApiObj["nonceStr"] = $this->createNoncestr();
  795. $jsApiObj["package"] = "prepay_id=$this->prepay_id";
  796. $jsApiObj["signType"] = "MD5";
  797. $jsApiObj["paySign"] = $this->getSign($jsApiObj);
  798. $this->parameters = json_encode($jsApiObj);
  799. return $this->parameters;
  800. }
  801. }
  802. /**
  803. * 发送红包
  804. */
  805. class Sendredpack extends Common_util_pub
  806. {
  807. function __construct($appconfig)
  808. {
  809. Common_util_pub::__construct($appconfig);
  810. //设置接口链接
  811. $this->url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";
  812. //设置curl超时时间
  813. $this->curl_timeout = $this->wxconfig['CURL_TIMEOUT'];
  814. }
  815. /**
  816. * 作用:设置请求参数
  817. */
  818. function setParameter($parameter, $parameterValue)
  819. {
  820. $this->parameters[$this->trimString($parameter)] = $this->trimString($parameterValue);
  821. }
  822. function check_sign_parameters()
  823. {
  824. if($this->parameters["nonce_str"] == null ||
  825. $this->parameters["mch_billno"] == null ||
  826. $this->parameters["mch_id"] == null ||
  827. $this->parameters["wxappid"] == null ||
  828. $this->parameters["send_name"] == null ||
  829. $this->parameters["re_openid"] == null ||
  830. $this->parameters["total_amount"] == null ||
  831. $this->parameters["total_num"] == null ||
  832. $this->parameters["wishing"] == null ||
  833. $this->parameters["client_ip"] == null ||
  834. $this->parameters["act_name"] == null ||
  835. $this->parameters["remark"] == null
  836. )
  837. {
  838. return false;
  839. }
  840. return true;
  841. }
  842. //生成红包接口XML信息
  843. /*
  844. <xml>
  845. <sign>![CDATA[E1EE61A9]]</sign>
  846. <mch_billno>![CDATA[00100]]</mch_billno>
  847. <mch_id>![CDATA[888]]</mch_id>
  848. <wxappid>![CDATA[wxcbda96de0b165486]]</wxappid>
  849. <send_name>![CDATA[send_name]]</send_name>
  850. <re_openid>![CDATA[onqOjjXXXXXXXXX]]</re_openid>
  851. <total_amount>![CDATA[100]]</total_amount>
  852. <total_num>![CDATA[1]]</total_num>
  853. <wishing>![CDATA[恭喜发财]]</wishing>
  854. <client_ip>![CDATA[127.0.0.1]]</client_ip>
  855. <act_name>![CDATA[新年红包]]</act_name>
  856. <remark>![CDATA[新年红包]]</remark>
  857. </xml>
  858. */
  859. function createXml()
  860. {
  861. $this->parameters["wxappid"] = $this->wxconfig['APPID'];//公众账号ID
  862. $this->parameters["mch_id"] = $this->wxconfig['MCHID'];//商户号
  863. $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
  864. $this->parameters["sign"] = $this->getSign($this->parameters);//签名
  865. return $this->arrayToXml($this->parameters);
  866. }
  867. /**
  868. * 作用:使用证书post请求xml
  869. */
  870. function postXmlSSL()
  871. {
  872. $xml = $this->createXml();
  873. $this->response = $this->postXmlSSLCurl($xml,$this->url,$this->curl_timeout);
  874. return $this->response;
  875. }
  876. }
  877. ?>