qrcode_wxpay.inc.php 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. <?php
  2. //调用核心类
  3. include 'source/plugin/xj_event/include/core.class.php';
  4. $eventcore = new xj_eventcore();
  5. if(file_exists($xj_event_wxset = DISCUZ_ROOT.'./data/sysdata/cache_xj_event_wxset.php')) {
  6. @include $xj_event_wxset;
  7. }
  8. require_once libfile('function/cache');
  9. $appid = $wxset['appid'];
  10. $appsecret = $wxset['appsecret'];
  11. $apikey = $wxset['apikey']; //APIKEY
  12. $mch_id = $wxset['mch_id']; //商户号
  13. $tid = intval($_GET['tid']);
  14. $siteid = $_G['wechat']['setting']['wsq_siteid'];
  15. if(!$_G['uid']) {
  16. exit('Access Denied');
  17. }
  18. if(!isset($appid) && !isset($appsecret) && !isset($apikey) && !isset($mch_id)){
  19. exit('Access Denied');
  20. }
  21. //获取活动内容和报名内容
  22. $applyid = intval($_GET['applyid']);
  23. $apply = DB::fetch_first("SELECT tid,applyid,applynumber FROM ".DB::table('xj_eventapply')." WHERE applyid = $applyid and uid=".$_G['uid']);
  24. $tid = $apply['tid'];
  25. $items = DB::fetch_first("SELECT A.*,B.subject FROM ".DB::table('xj_event')." A,".DB::table('forum_thread')." B WHERE A.tid = $tid and A.tid=B.tid");
  26. $setting = unserialize($items['setting']);
  27. $pay_subject = $items['subject'];
  28. $pay_price = $items['use_cost'];
  29. if($setting['nodaibaoming']){
  30. $pay_number = $apply['applynumber'];
  31. }else{
  32. $pay_number = DB::result_first("SELECT count(*) FROM ".DB::table('xj_eventapply')." WHERE tid = '$tid' and uid=".$_G['uid']);
  33. }
  34. $pay_totalprice = $pay_price * $pay_number;
  35. //如果是多种报名
  36. if($setting['cost']){
  37. if($setting['nodaibaoming']){
  38. $capply = DB::fetch_first("SELECT * FROM ".DB::table('xj_eventapply')." WHERE tid = '$tid' and uid=".$_G['uid']);
  39. $capply['ufielddata'] = unserialize($capply['ufielddata']);
  40. $price = 0;
  41. foreach($setting['cost'] as $value){
  42. $price = $price+$capply['ufielddata']['cost'.$value['id']]*$value['cost_price'];
  43. }
  44. }else{
  45. $capply = DB::fetch_all("SELECT * FROM ".DB::table('xj_eventapply')." WHERE tid = '$tid' and uid=".$_G['uid']);
  46. $price = 0;
  47. foreach($capply as $value){
  48. $value['ufielddata'] = unserialize($value['ufielddata']);
  49. $price = $price + $setting['cost'][$value['ufielddata']['costclass']]['cost_price'];
  50. }
  51. }
  52. $pay_totalprice = $price;
  53. }
  54. //VIP折扣
  55. if(file_exists(DISCUZ_ROOT.'./source/plugin/xj_event/module/vip/qrcode_wxpay.php')) {
  56. @include 'module/vip/qrcode_wxpay.php';
  57. }
  58. if($_G['charset']=='gbk'){
  59. $pay_subject = cutstr($pay_subject,20,'');
  60. $pay_subject = iconv('GBK','UTF-8',$pay_subject);
  61. }
  62. //prepay_id 获取,微信支付统一下单
  63. $parameters = array();
  64. $parameters["out_trade_no"] = getRandChar(20); //生成订单号
  65. $parameters["body"] = $pay_subject; //商品描述
  66. $parameters["total_fee"] = $pay_totalprice*100; //总金额单位是分,不可以是小数
  67. $parameters["notify_url"] = $_G['siteurl'].'source/plugin/xj_event/event_pay_wx_notify.php'; //异步回调地址
  68. $parameters["trade_type"] = 'NATIVE';
  69. $parameters["appid"] = $appid;
  70. $parameters["mch_id"] = $mch_id; //商户号
  71. $parameters["spbill_create_ip"] = $_G['clientip']; //客户端的IP地址
  72. $parameters["nonce_str"] = createNoncestr(); //随机字符串
  73. $parameters["sign"] = getSign($parameters);
  74. $xmldata = arrayToXml($parameters);
  75. $prepaystr = postXmlCurl($xmldata,"https://api.mch.weixin.qq.com/pay/unifiedorder");
  76. $postObj = xmlToArray($prepaystr);
  77. if($postObj['return_code'] == 'FAIL'){
  78. echo iconv('UTF-8','GBK',$postObj['return_msg']);
  79. exit();
  80. }
  81. $validationurl = $postObj['code_url'];
  82. //数据库生成支付记录
  83. $paylog = array();
  84. $paylog['applyid'] = $apply['applyid'];
  85. $paylog['uid'] = $_G['uid'];
  86. $paylog['tid'] = $tid;
  87. $paylog['tradeno'] = $parameters["out_trade_no"];
  88. $paylog['paytype'] = 'wxpay';
  89. $paylog['subject'] = $items['subject'];
  90. $paylog['price'] = $pay_price;
  91. $paylog['buyer_email'] = $openid;
  92. $paylog['total_fee'] = $pay_totalprice;
  93. $paylog['create_time'] = $_G['timestamp'];
  94. $paylog['paystate'] = 1;
  95. DB::insert("xj_eventpay_log",$paylog);
  96. require_once DISCUZ_ROOT.'source/plugin/mobile/qrcode.class.php';
  97. ob_clean();//这个一定要加上,清除缓冲区
  98. QRcode::png($validationurl, false, QR_ECLEVEL_Q, 8);
  99. /*
  100. dheader('Content-Disposition: inline; filename=qrcode_index.jpg');
  101. dheader('Content-Type: image/pjpeg');
  102. @readfile($file);
  103. */
  104. function std_class_object_to_array($stdclassobject)
  105. {
  106. $_array = is_object($stdclassobject) ? get_object_vars($stdclassobject) : $stdclassobject;
  107. foreach ($_array as $key => $value) {
  108. $value = (is_array($value) || is_object($value)) ? std_class_object_to_array($value) : $value;
  109. $array[$key] = $value;
  110. }
  111. return $array;
  112. }
  113. function postxml($url,$data){
  114. $ch = curl_init($url);
  115. curl_setopt($ch, CURLOPT_MUTE, 1);
  116. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
  117. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
  118. curl_setopt($ch, CURLOPT_POST, 1);
  119. curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: text/xml'));
  120. curl_setopt($ch, CURLOPT_POSTFIELDS, "$data");
  121. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  122. $output = curl_exec($ch);
  123. curl_close($ch);
  124. return $output;
  125. }
  126. function postXmlCurl($xml,$url,$second=30)
  127. {
  128. //初始化curl
  129. $ch = curl_init();
  130. //设置超时
  131. curl_setopt($ch, CURLOP_TIMEOUT, $second);
  132. //这里设置代理,如果有的话
  133. //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
  134. //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
  135. curl_setopt($ch,CURLOPT_URL, $url);
  136. curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
  137. curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
  138. //设置header
  139. curl_setopt($ch, CURLOPT_HEADER, FALSE);
  140. //要求结果为字符串且输出到屏幕上
  141. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  142. //post提交方式
  143. curl_setopt($ch, CURLOPT_POST, TRUE);
  144. curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
  145. //运行curl
  146. $data = curl_exec($ch);
  147. curl_close($ch);
  148. //返回结果
  149. if($data)
  150. {
  151. curl_close($ch);
  152. return $data;
  153. }
  154. else
  155. {
  156. $error = curl_errno($ch);
  157. echo "curl error:$error"."<br>";
  158. echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>error view</a></br>";
  159. curl_close($ch);
  160. return false;
  161. }
  162. }
  163. function get($url) {
  164. $ch = curl_init();
  165. curl_setopt($ch, CURLOPT_URL, $url);
  166. # curl_setopt($ch, CURLOPT_HEADER, 1);
  167. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  168. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  169. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  170. if (!curl_exec($ch)) {
  171. error_log(curl_error($ch));
  172. $data = '';
  173. } else {
  174. $data = curl_multi_getcontent($ch);
  175. }
  176. curl_close($ch);
  177. return $data;
  178. }
  179. function getRandChar($length){
  180. $str = null;
  181. $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
  182. $max = strlen($strPol)-1;
  183. for($i=0;$i<$length;$i++){
  184. $str.=$strPol[rand(0,$max)];//rand($min,$max)生成介于min和max两个数之间的一个随机整数
  185. }
  186. return $str;
  187. }
  188. //生成指定大小的字符串
  189. function createNoncestr( $length = 32 ){
  190. $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
  191. $str ="";
  192. for ( $i = 0; $i < $length; $i++ ) {
  193. $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
  194. }
  195. return $str;
  196. }
  197. /**
  198. * 作用:格式化参数,签名过程需要使用
  199. */
  200. function formatBizQueryParaMap($paraMap, $urlencode)
  201. {
  202. $buff = "";
  203. ksort($paraMap);
  204. foreach ($paraMap as $k => $v)
  205. {
  206. if($urlencode)
  207. {
  208. $v = urlencode($v);
  209. }
  210. //$buff .= strtolower($k) . "=" . $v . "&";
  211. $buff .= $k . "=" . $v . "&";
  212. }
  213. $reqPar;
  214. if (strlen($buff) > 0)
  215. {
  216. $reqPar = substr($buff, 0, strlen($buff)-1);
  217. }
  218. return $reqPar;
  219. }
  220. //生成签名
  221. function getSign($Obj){
  222. global $apikey;
  223. foreach ($Obj as $k => $v)
  224. {
  225. $Parameters[$k] = $v;
  226. }
  227. //签名步骤一:按字典序排序参数
  228. ksort($Parameters);
  229. $String = formatBizQueryParaMap($Parameters, false);
  230. //echo '【string1】'.$String.'</br>';
  231. //签名步骤二:在string后加入KEY
  232. $String = $String."&key=$apikey";
  233. //echo "【string2】".$String."</br>";
  234. //签名步骤三:MD5加密
  235. $String = md5($String);
  236. //echo "【string3】 ".$String."</br>";
  237. //签名步骤四:所有字符转为大写
  238. $result_ = strtoupper($String);
  239. //echo "【result】 ".$result_."</br>";
  240. return $result_;
  241. }
  242. /**
  243. * 作用:array转xml
  244. */
  245. function arrayToXml($arr)
  246. {
  247. $xml = "<xml>";
  248. foreach ($arr as $key=>$val)
  249. {
  250. if (is_numeric($val))
  251. {
  252. $xml.="<".$key.">".$val."</".$key.">";
  253. }
  254. else
  255. $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
  256. }
  257. $xml.="</xml>";
  258. return $xml;
  259. }
  260. /**
  261. * 作用:将xml转为array
  262. */
  263. function xmlToArray($xml)
  264. {
  265. //将XML转为array
  266. $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
  267. return $array_data;
  268. }
  269. /**
  270. * 作用:生成可以获得code的url
  271. */
  272. function createOauthUrlForCode($redirectUrl)
  273. {
  274. global $appid;
  275. $urlObj["appid"] = $appid;
  276. $urlObj["redirect_uri"] = urlencode($redirectUrl);
  277. $urlObj["response_type"] = "code";
  278. $urlObj["scope"] = "snsapi_base";
  279. $urlObj["state"] = "STATE"."#wechat_redirect";
  280. $bizString = formatBizQueryParaMap($urlObj, false);
  281. return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString;
  282. }
  283. /**
  284. * 作用:生成可以获得openid的url
  285. */
  286. function createOauthUrlForOpenid()
  287. {
  288. global $appid,$appsecret,$code;
  289. $urlObj["appid"] = $appid;
  290. $urlObj["secret"] = $appsecret;
  291. $urlObj["code"] = $code;
  292. $urlObj["grant_type"] = "authorization_code";
  293. $bizString = formatBizQueryParaMap($urlObj, false);
  294. return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString;
  295. }
  296. /**
  297. * 作用:通过curl向微信提交code,以获取openid
  298. */
  299. function getOpenid()
  300. {
  301. $url = createOauthUrlForOpenid();
  302. //初始化curl
  303. $ch = curl_init();
  304. //设置超时
  305. curl_setopt($ch, CURLOP_TIMEOUT, 30); //超时时间
  306. curl_setopt($ch, CURLOPT_URL, $url);
  307. curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
  308. curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
  309. curl_setopt($ch, CURLOPT_HEADER, FALSE);
  310. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  311. //运行curl,结果以jason形式返回
  312. $res = curl_exec($ch);
  313. curl_close($ch);
  314. //取出openid
  315. $data = json_decode($res,true);
  316. $return = $data['openid'];
  317. return $return;
  318. }
  319. //删除微社区嵌入点
  320. /*
  321. $pluginid = 'xj_event';
  322. require_once DISCUZ_ROOT.'./source/plugin/wechat/wechat.lib.class.php';
  323. WeChatHook::delAPIHook($pluginid);
  324. exit('fff');
  325. */
  326. ?>