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.

987 lines
26 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
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, CURLOPT_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. return $data;
  170. }
  171. else
  172. {
  173. $error = curl_errno($ch);
  174. echo "curl出错,错误码:$error"."<br>";
  175. echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";
  176. return false;
  177. }
  178. }
  179. /**
  180. * 作用:使用证书,以post方式提交xml到对应的接口url
  181. */
  182. function postXmlSSLCurl($xml,$url,$second=30)
  183. {
  184. $ch = curl_init();
  185. //超时时间
  186. curl_setopt($ch,CURLOPT_TIMEOUT,$second);
  187. //这里设置代理,如果有的话
  188. //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
  189. //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
  190. curl_setopt($ch,CURLOPT_URL, $url);
  191. curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
  192. curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
  193. //设置header
  194. curl_setopt($ch,CURLOPT_HEADER,FALSE);
  195. //要求结果为字符串且输出到屏幕上
  196. curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
  197. //设置证书
  198. //使用证书:cert 与 key 分别属于两个.pem文件
  199. //默认格式为PEM,可以注释
  200. curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
  201. curl_setopt($ch,CURLOPT_SSLCERT, $this->wxconfig['SSLCERT_PATH']);
  202. //默认格式为PEM,可以注释
  203. curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
  204. curl_setopt($ch,CURLOPT_SSLKEY, $this->wxconfig['SSLKEY_PATH']);
  205. //post提交方式
  206. curl_setopt($ch,CURLOPT_POST, true);
  207. curl_setopt($ch,CURLOPT_POSTFIELDS,$xml);
  208. $data = curl_exec($ch);
  209. //返回结果
  210. if($data){
  211. curl_close($ch);
  212. return $data;
  213. }
  214. else {
  215. $error = curl_errno($ch);
  216. echo "curl出错,错误码:$error"."<br>";
  217. echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";
  218. curl_close($ch);
  219. return false;
  220. }
  221. }
  222. /**
  223. * 作用:打印数组
  224. */
  225. function printErr($wording='',$err='')
  226. {
  227. print_r('<pre>');
  228. echo $wording."</br>";
  229. var_dump($err);
  230. print_r('</pre>');
  231. }
  232. }
  233. /**
  234. * 请求型接口的基类
  235. */
  236. class Wxpay_client_pub extends Common_util_pub
  237. {
  238. var $parameters;//请求参数,类型为关联数组
  239. public $response;//微信返回的响应
  240. public $result;//返回参数,类型为关联数组
  241. var $url;//接口链接
  242. var $curl_timeout;//curl超时时间
  243. /**
  244. * 作用:设置请求参数
  245. */
  246. function setParameter($parameter, $parameterValue)
  247. {
  248. $this->parameters[$this->trimString($parameter)] = $this->trimString($parameterValue);
  249. }
  250. /**
  251. * 作用:设置标配的请求参数,生成签名,生成接口参数xml
  252. */
  253. function createXml()
  254. {
  255. $this->parameters["appid"] = $this->wxconfig['APPID'];//公众账号ID
  256. $this->parameters["mch_id"] = $this->wxconfig['MCHID'];//商户号
  257. $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
  258. $this->parameters["sign"] = $this->getSign($this->parameters);//签名
  259. return $this->arrayToXml($this->parameters);
  260. }
  261. /**
  262. * 作用:post请求xml
  263. */
  264. function postXml()
  265. {
  266. $xml = $this->createXml();
  267. $this->response = $this->postXmlCurl($xml,$this->url,$this->curl_timeout);
  268. return $this->response;
  269. }
  270. /**
  271. * 作用:使用证书post请求xml
  272. */
  273. function postXmlSSL()
  274. {
  275. $xml = $this->createXml();
  276. $this->response = $this->postXmlSSLCurl($xml,$this->url,$this->curl_timeout);
  277. return $this->response;
  278. }
  279. /**
  280. * 作用:获取结果,默认不使用证书
  281. */
  282. function getResult()
  283. {
  284. $this->postXml();
  285. $this->result = $this->xmlToArray($this->response);
  286. return $this->result;
  287. }
  288. }
  289. /**
  290. * 统一支付接口类
  291. */
  292. class UnifiedOrder_pub extends Wxpay_client_pub
  293. {
  294. function __construct($appconfig)
  295. {
  296. Common_util_pub::__construct($appconfig);
  297. //设置接口链接
  298. $this->url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
  299. //设置curl超时时间
  300. $this->curl_timeout = $this->wxconfig['CURL_TIMEOUT'];
  301. }
  302. /**
  303. * 生成接口参数xml
  304. */
  305. function createXml()
  306. {
  307. try
  308. {
  309. //检测必填参数
  310. if($this->parameters["out_trade_no"] == null)
  311. {
  312. throw new SDKRuntimeException("缺少统一支付接口必填参数out_trade_no!"."<br>");
  313. }elseif($this->parameters["body"] == null){
  314. throw new SDKRuntimeException("缺少统一支付接口必填参数body!"."<br>");
  315. }elseif ($this->parameters["total_fee"] == null ) {
  316. throw new SDKRuntimeException("缺少统一支付接口必填参数total_fee!"."<br>");
  317. }elseif ($this->parameters["notify_url"] == null) {
  318. throw new SDKRuntimeException("缺少统一支付接口必填参数notify_url!"."<br>");
  319. }elseif ($this->parameters["trade_type"] == null) {
  320. throw new SDKRuntimeException("缺少统一支付接口必填参数trade_type!"."<br>");
  321. }elseif ($this->parameters["trade_type"] == "JSAPI" &&
  322. $this->parameters["openid"] == NULL){
  323. throw new SDKRuntimeException("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!"."<br>");
  324. }
  325. $this->parameters["appid"] = $this->wxconfig['APPID'];//公众账号ID
  326. $this->parameters["mch_id"] = $this->wxconfig['MCHID'];//商户号
  327. $this->parameters["spbill_create_ip"] = $_SERVER['REMOTE_ADDR'];//终端ip
  328. $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
  329. $this->parameters["sign"] = $this->getSign($this->parameters);//签名
  330. return $this->arrayToXml($this->parameters);
  331. }
  332. catch (SDKRuntimeException $e)
  333. {
  334. die($e->errorMessage());
  335. }
  336. }
  337. /**
  338. * 获取prepay_id
  339. */
  340. function getPrepayId()
  341. {
  342. $this->postXml();
  343. $this->result = $this->xmlToArray($this->response);
  344. $prepay_id = $this->result["prepay_id"];
  345. return $prepay_id;
  346. }
  347. }
  348. /**
  349. * 订单查询接口
  350. */
  351. class OrderQuery_pub extends Wxpay_client_pub
  352. {
  353. function __construct()
  354. {
  355. //设置接口链接
  356. $this->url = "https://api.mch.weixin.qq.com/pay/orderquery";
  357. //设置curl超时时间
  358. $this->curl_timeout = $this->wxconfig['CURL_TIMEOUT'];
  359. }
  360. /**
  361. * 生成接口参数xml
  362. */
  363. function createXml()
  364. {
  365. try
  366. {
  367. //检测必填参数
  368. if($this->parameters["out_trade_no"] == null &&
  369. $this->parameters["transaction_id"] == null)
  370. {
  371. throw new SDKRuntimeException("订单查询接口中,out_trade_no、transaction_id至少填一个!"."<br>");
  372. }
  373. $this->parameters["appid"] = $this->wxconfig['APPID'];//公众账号ID
  374. $this->parameters["mch_id"] = $this->wxconfig['MCHID'];//商户号
  375. $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
  376. $this->parameters["sign"] = $this->getSign($this->parameters);//签名
  377. return $this->arrayToXml($this->parameters);
  378. }catch (SDKRuntimeException $e)
  379. {
  380. die($e->errorMessage());
  381. }
  382. }
  383. }
  384. /**
  385. * 退款申请接口
  386. */
  387. class Refund_pub extends Wxpay_client_pub
  388. {
  389. function __construct()
  390. {
  391. //设置接口链接
  392. $this->url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
  393. //设置curl超时时间
  394. $this->curl_timeout = $this->wxconfig['CURL_TIMEOUT'];
  395. }
  396. /**
  397. * 生成接口参数xml
  398. */
  399. function createXml()
  400. {
  401. try
  402. {
  403. //检测必填参数
  404. if($this->parameters["out_trade_no"] == null && $this->parameters["transaction_id"] == null) {
  405. throw new SDKRuntimeException("退款申请接口中,out_trade_no、transaction_id至少填一个!"."<br>");
  406. }elseif($this->parameters["out_refund_no"] == null){
  407. throw new SDKRuntimeException("退款申请接口中,缺少必填参数out_refund_no!"."<br>");
  408. }elseif($this->parameters["total_fee"] == null){
  409. throw new SDKRuntimeException("退款申请接口中,缺少必填参数total_fee!"."<br>");
  410. }elseif($this->parameters["refund_fee"] == null){
  411. throw new SDKRuntimeException("退款申请接口中,缺少必填参数refund_fee!"."<br>");
  412. }elseif($this->parameters["op_user_id"] == null){
  413. throw new SDKRuntimeException("退款申请接口中,缺少必填参数op_user_id!"."<br>");
  414. }
  415. $this->parameters["appid"] = $this->wxconfig['APPID'];//公众账号ID
  416. $this->parameters["mch_id"] = $this->wxconfig['MCHID'];//商户号
  417. $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
  418. $this->parameters["sign"] = $this->getSign($this->parameters);//签名
  419. return $this->arrayToXml($this->parameters);
  420. }catch (SDKRuntimeException $e)
  421. {
  422. die($e->errorMessage());
  423. }
  424. }
  425. /**
  426. * 作用:获取结果,使用证书通信
  427. */
  428. function getResult()
  429. {
  430. $this->postXmlSSL();
  431. $this->result = $this->xmlToArray($this->response);
  432. return $this->result;
  433. }
  434. }
  435. /**
  436. * 退款查询接口
  437. */
  438. class RefundQuery_pub extends Wxpay_client_pub
  439. {
  440. function __construct()
  441. {
  442. //设置接口链接
  443. $this->url = "https://api.mch.weixin.qq.com/pay/refundquery";
  444. //设置curl超时时间
  445. $this->curl_timeout = $this->wxconfig['CURL_TIMEOUT'];
  446. }
  447. /**
  448. * 生成接口参数xml
  449. */
  450. function createXml()
  451. {
  452. try
  453. {
  454. if($this->parameters["out_refund_no"] == null &&
  455. $this->parameters["out_trade_no"] == null &&
  456. $this->parameters["transaction_id"] == null &&
  457. $this->parameters["refund_id "] == null)
  458. {
  459. throw new SDKRuntimeException("退款查询接口中,out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个!"."<br>");
  460. }
  461. $this->parameters["appid"] = $this->wxconfig['APPID'];//公众账号ID
  462. $this->parameters["mch_id"] = $this->wxconfig['MCHID'];//商户号
  463. $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
  464. $this->parameters["sign"] = $this->getSign($this->parameters);//签名
  465. return $this->arrayToXml($this->parameters);
  466. }
  467. catch (SDKRuntimeException $e)
  468. {
  469. die($e->errorMessage());
  470. }
  471. }
  472. /**
  473. * 作用:获取结果,使用证书通信
  474. */
  475. function getResult()
  476. {
  477. $this->postXmlSSL();
  478. $this->result = $this->xmlToArray($this->response);
  479. return $this->result;
  480. }
  481. }
  482. /**
  483. * 对账单接口
  484. */
  485. class DownloadBill_pub extends Wxpay_client_pub
  486. {
  487. function __construct()
  488. {
  489. //设置接口链接
  490. $this->url = "https://api.mch.weixin.qq.com/pay/downloadbill";
  491. //设置curl超时时间
  492. $this->curl_timeout = $this->wxconfig['CURL_TIMEOUT'];
  493. }
  494. /**
  495. * 生成接口参数xml
  496. */
  497. function createXml()
  498. {
  499. try
  500. {
  501. if($this->parameters["bill_date"] == null )
  502. {
  503. throw new SDKRuntimeException("对账单接口中,缺少必填参数bill_date!"."<br>");
  504. }
  505. $this->parameters["appid"] = $this->wxconfig['APPID'];//公众账号ID
  506. $this->parameters["mch_id"] = $this->wxconfig['MCHID'];//商户号
  507. $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
  508. $this->parameters["sign"] = $this->getSign($this->parameters);//签名
  509. return $this->arrayToXml($this->parameters);
  510. }
  511. catch (SDKRuntimeException $e)
  512. {
  513. die($e->errorMessage());
  514. }
  515. }
  516. /**
  517. * 作用:获取结果,默认不使用证书
  518. */
  519. function getResult()
  520. {
  521. $this->postXml();
  522. $this->result = $this->xmlToArray($this->result_xml);
  523. return $this->result;
  524. }
  525. }
  526. /**
  527. * 短链接转换接口
  528. */
  529. class ShortUrl_pub extends Wxpay_client_pub
  530. {
  531. function __construct()
  532. {
  533. //设置接口链接
  534. $this->url = "https://api.mch.weixin.qq.com/tools/shorturl";
  535. //设置curl超时时间
  536. $this->curl_timeout = $this->wxconfig['CURL_TIMEOUT'];
  537. }
  538. /**
  539. * 生成接口参数xml
  540. */
  541. function createXml()
  542. {
  543. try
  544. {
  545. if($this->parameters["long_url"] == null )
  546. {
  547. throw new SDKRuntimeException("短链接转换接口中,缺少必填参数long_url!"."<br>");
  548. }
  549. $this->parameters["appid"] = $this->wxconfig['APPID'];//公众账号ID
  550. $this->parameters["mch_id"] = $this->wxconfig['MCHID'];//商户号
  551. $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
  552. $this->parameters["sign"] = $this->getSign($this->parameters);//签名
  553. return $this->arrayToXml($this->parameters);
  554. }catch (SDKRuntimeException $e)
  555. {
  556. die($e->errorMessage());
  557. }
  558. }
  559. /**
  560. * 获取prepay_id
  561. */
  562. function getShortUrl()
  563. {
  564. $this->postXml();
  565. $prepay_id = $this->result["short_url"];
  566. return $prepay_id;
  567. }
  568. }
  569. /**
  570. * 响应型接口基类
  571. */
  572. class Wxpay_server_pub extends Common_util_pub
  573. {
  574. public $data;//接收到的数据,类型为关联数组
  575. var $returnParameters;//返回参数,类型为关联数组
  576. /**
  577. * 将微信的请求xml转换成关联数组,以方便数据处理
  578. */
  579. function saveData($xml)
  580. {
  581. $this->data = $this->xmlToArray($xml);
  582. }
  583. function checkSign()
  584. {
  585. $tmpData = $this->data;
  586. unset($tmpData['sign']);
  587. $sign = $this->getSign($tmpData);//本地签名
  588. if ($this->data['sign'] == $sign) {
  589. return TRUE;
  590. }
  591. return FALSE;
  592. }
  593. /**
  594. * 获取微信的请求数据
  595. */
  596. function getData()
  597. {
  598. return $this->data;
  599. }
  600. /**
  601. * 设置返回微信的xml数据
  602. */
  603. function setReturnParameter($parameter, $parameterValue)
  604. {
  605. $this->returnParameters[$this->trimString($parameter)] = $this->trimString($parameterValue);
  606. }
  607. /**
  608. * 生成接口参数xml
  609. */
  610. function createXml()
  611. {
  612. return $this->arrayToXml($this->returnParameters);
  613. }
  614. /**
  615. * 将xml数据返回微信
  616. */
  617. function returnXml()
  618. {
  619. $returnXml = $this->createXml();
  620. return $returnXml;
  621. }
  622. }
  623. /**
  624. * 通用通知接口
  625. */
  626. class Notify_pub extends Wxpay_server_pub
  627. {
  628. }
  629. /**
  630. * 请求商家获取商品信息接口
  631. */
  632. class NativeCall_pub extends Wxpay_server_pub
  633. {
  634. /**
  635. * 生成接口参数xml
  636. */
  637. function createXml()
  638. {
  639. if($this->returnParameters["return_code"] == "SUCCESS"){
  640. $this->returnParameters["appid"] = $this->wxconfig['APPID'];//公众账号ID
  641. $this->returnParameters["mch_id"] = $this->wxconfig['MCHID'];//商户号
  642. $this->returnParameters["nonce_str"] = $this->createNoncestr();//随机字符串
  643. $this->returnParameters["sign"] = $this->getSign($this->returnParameters);//签名
  644. }
  645. return $this->arrayToXml($this->returnParameters);
  646. }
  647. /**
  648. * 获取product_id
  649. */
  650. function getProductId()
  651. {
  652. $product_id = $this->data["product_id"];
  653. return $product_id;
  654. }
  655. }
  656. /**
  657. * 静态链接二维码
  658. */
  659. class NativeLink_pub extends Common_util_pub
  660. {
  661. var $parameters;//静态链接参数
  662. var $url;//静态链接
  663. function __construct()
  664. {
  665. }
  666. /**
  667. * 设置参数
  668. */
  669. function setParameter($parameter, $parameterValue)
  670. {
  671. $this->parameters[$this->trimString($parameter)] = $this->trimString($parameterValue);
  672. }
  673. /**
  674. * 生成Native支付链接二维码
  675. */
  676. function createLink()
  677. {
  678. try
  679. {
  680. if($this->parameters["product_id"] == null)
  681. {
  682. throw new SDKRuntimeException("缺少Native支付二维码链接必填参数product_id!"."<br>");
  683. }
  684. $this->parameters["appid"] = $this->wxconfig['APPID'];//公众账号ID
  685. $this->parameters["mch_id"] = $this->wxconfig['MCHID'];//商户号
  686. $time_stamp = time();
  687. $this->parameters["time_stamp"] = "$time_stamp";//时间戳
  688. $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
  689. $this->parameters["sign"] = $this->getSign($this->parameters);//签名
  690. $bizString = $this->formatBizQueryParaMap($this->parameters, false);
  691. $this->url = "weixin://wxpay/bizpayurl?".$bizString;
  692. }catch (SDKRuntimeException $e)
  693. {
  694. die($e->errorMessage());
  695. }
  696. }
  697. /**
  698. * 返回链接
  699. */
  700. function getUrl()
  701. {
  702. $this->createLink();
  703. return $this->url;
  704. }
  705. }
  706. /**
  707. * JSAPI支付——H5网页端调起支付接口
  708. */
  709. class JsApi_pub extends Common_util_pub
  710. {
  711. var $code;//code码,用以获取openid
  712. var $openid;//用户的openid
  713. var $parameters;//jsapi参数,格式为json
  714. var $prepay_id;//使用统一支付接口得到的预支付id
  715. var $curl_timeout;//curl超时时间
  716. function __construct($appconfig)
  717. {
  718. Common_util_pub::__construct($appconfig);
  719. //设置curl超时时间
  720. $this->curl_timeout = $this->wxconfig['CURL_TIMEOUT'];
  721. }
  722. /**
  723. * 作用:生成可以获得code的url
  724. */
  725. function createOauthUrlForCode($redirectUrl)
  726. {
  727. $urlObj["appid"] = $this->wxconfig['APPID'];
  728. $urlObj["redirect_uri"] = "$redirectUrl";
  729. $urlObj["response_type"] = "code";
  730. $urlObj["scope"] = "snsapi_base";
  731. $urlObj["state"] = "STATE"."#wechat_redirect";
  732. $bizString = $this->formatBizQueryParaMap($urlObj, false);
  733. return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString;
  734. }
  735. /**
  736. * 作用:生成可以获得openid的url
  737. */
  738. function createOauthUrlForOpenid()
  739. {
  740. $urlObj["appid"] = $this->wxconfig['APPID'];
  741. $urlObj["secret"] = $this->wxconfig['APPSECRET'];
  742. $urlObj["code"] = $this->code;
  743. $urlObj["grant_type"] = "authorization_code";
  744. $bizString = $this->formatBizQueryParaMap($urlObj, false);
  745. return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString;
  746. }
  747. /**
  748. * 作用:通过curl向微信提交code,以获取openid
  749. */
  750. function GetOpenidFromMp()
  751. {
  752. $url = $this->createOauthUrlForOpenid();
  753. //初始化curl
  754. $ch = curl_init();
  755. //设置超时
  756. curl_setopt($ch, CURLOPT_TIMEOUT, $this->curl_timeout);
  757. curl_setopt($ch, CURLOPT_URL, $url);
  758. curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
  759. curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
  760. curl_setopt($ch, CURLOPT_HEADER, FALSE);
  761. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  762. //运行curl,结果以jason形式返回
  763. $res = curl_exec($ch);
  764. curl_close($ch);
  765. //取出openid
  766. $data = json_decode($res,true);
  767. $this->openid = $data['openid'];
  768. return $this->openid;
  769. }
  770. /**
  771. *
  772. * 通过跳转获取用户的openid,跳转流程如下:
  773. * 1、设置自己需要调回的url及其其他参数,跳转到微信服务器https://open.weixin.qq.com/connect/oauth2/authorize
  774. * 2、微信服务处理完成之后会跳转回用户redirect_uri地址,此时会带上一些参数,如:code
  775. *
  776. * @return 用户的openid
  777. */
  778. function getOpenid()
  779. {
  780. //通过code获得openid
  781. if (!isset($_GET['code']))
  782. {
  783. //触发微信返回code码
  784. $baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING']);
  785. $url = $this->createOauthUrlForCode($baseUrl);
  786. Header("Location: $url");
  787. exit();
  788. }
  789. else
  790. {
  791. //获取code码,以获取openid
  792. $code = $_GET['code'];
  793. $this->setCode($code);
  794. $openid = $this->GetOpenidFromMp();
  795. return $openid;
  796. }
  797. }
  798. /**
  799. * 作用:设置prepay_id
  800. */
  801. function setPrepayId($prepayId)
  802. {
  803. $this->prepay_id = $prepayId;
  804. }
  805. /**
  806. * 作用:设置code
  807. */
  808. function setCode($code_)
  809. {
  810. $this->code = $code_;
  811. }
  812. /**
  813. * 作用:设置jsapi的参数
  814. */
  815. public function getParameters()
  816. {
  817. $jsApiObj["appId"] = $this->wxconfig['APPID'];
  818. $timeStamp = time();
  819. $jsApiObj["timeStamp"] = "$timeStamp";
  820. $jsApiObj["nonceStr"] = $this->createNoncestr();
  821. $jsApiObj["package"] = "prepay_id=$this->prepay_id";
  822. $jsApiObj["signType"] = "MD5";
  823. $jsApiObj["paySign"] = $this->getSign($jsApiObj);
  824. $this->parameters = json_encode($jsApiObj);
  825. return $this->parameters;
  826. }
  827. }
  828. /**
  829. * 发送红包
  830. */
  831. class Sendredpack extends Common_util_pub
  832. {
  833. function __construct($appconfig)
  834. {
  835. Common_util_pub::__construct($appconfig);
  836. //设置接口链接
  837. $this->url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack";
  838. //设置curl超时时间
  839. $this->curl_timeout = $this->wxconfig['CURL_TIMEOUT'];
  840. }
  841. /**
  842. * 作用:设置请求参数
  843. */
  844. function setParameter($parameter, $parameterValue)
  845. {
  846. $this->parameters[$this->trimString($parameter)] = $this->trimString($parameterValue);
  847. }
  848. function check_sign_parameters()
  849. {
  850. if($this->parameters["nonce_str"] == null ||
  851. $this->parameters["mch_billno"] == null ||
  852. $this->parameters["mch_id"] == null ||
  853. $this->parameters["wxappid"] == null ||
  854. $this->parameters["send_name"] == null ||
  855. $this->parameters["re_openid"] == null ||
  856. $this->parameters["total_amount"] == null ||
  857. $this->parameters["total_num"] == null ||
  858. $this->parameters["wishing"] == null ||
  859. $this->parameters["client_ip"] == null ||
  860. $this->parameters["act_name"] == null ||
  861. $this->parameters["remark"] == null
  862. )
  863. {
  864. return false;
  865. }
  866. return true;
  867. }
  868. //生成红包接口XML信息
  869. /*
  870. <xml>
  871. <sign>![CDATA[E1EE61A9]]</sign>
  872. <mch_billno>![CDATA[00100]]</mch_billno>
  873. <mch_id>![CDATA[888]]</mch_id>
  874. <wxappid>![CDATA[wxcbda96de0b165486]]</wxappid>
  875. <send_name>![CDATA[send_name]]</send_name>
  876. <re_openid>![CDATA[onqOjjXXXXXXXXX]]</re_openid>
  877. <total_amount>![CDATA[100]]</total_amount>
  878. <total_num>![CDATA[1]]</total_num>
  879. <wishing>![CDATA[恭喜发财]]</wishing>
  880. <client_ip>![CDATA[127.0.0.1]]</client_ip>
  881. <act_name>![CDATA[新年红包]]</act_name>
  882. <remark>![CDATA[新年红包]]</remark>
  883. </xml>
  884. */
  885. function createXml()
  886. {
  887. $this->parameters["wxappid"] = $this->wxconfig['APPID'];//公众账号ID
  888. $this->parameters["mch_id"] = $this->wxconfig['MCHID'];//商户号
  889. $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串
  890. $this->parameters["sign"] = $this->getSign($this->parameters);//签名
  891. return $this->arrayToXml($this->parameters);
  892. }
  893. /**
  894. * 作用:使用证书post请求xml
  895. */
  896. function postXmlSSL()
  897. {
  898. $xml = $this->createXml();
  899. $this->response = $this->postXmlSSLCurl($xml,$this->url,$this->curl_timeout);
  900. return $this->response;
  901. }
  902. }
  903. ?>