WxPayPubHelper.php 26 KB

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