WxPayPubHelper.php 29 KB

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