手机微信内支付
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport"> <script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script> <?php //微信内支付,需要从c.html页面跳转至此; $appid = "#"; $secret = "#"; $code = $_GET["code"]; $state = $_GET["state"]; if(!isset($_COOKIE['openid'])){ //获取用户openid地址 $geturl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=$appid&secret=$secret&code=$code&grant_type=authorization_code"; $openid = json_decode(file_get_contents($geturl))->openid; setcookie("openid","$openid",time()+3600); }else{ $openid = $_COOKIE['openid']; } ?> <?php include_once "jssdk.php"; //生成随机字符串 function getNonceNum($numLen=16){ $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; $str = ""; for ($i = 0; $i < $numLen; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } //获取用户ip地址 function get_client_ip(){ $cip = "unknown"; if($_SERVER['REMOTE_ADDR']){ $cip = $_SERVER['REMOTE_ADDR']; }elseif(getenv("REMOTE_ADDR")){ $cip = getenv("REMOTE_ADDR"); } return $cip; } $getNonceNumstring = getNonceNum(); $out_trade_no = date("Ymd").getNonceNum(); $ip = get_client_ip(); $param['appid'] = "$appid"; $param['mch_id'] = "#"; $param['nonce_str'] = $getNonceNumstring; $param['body'] = "支付"; $param['out_trade_no'] = $out_trade_no; $param['total_fee'] = 1; $param['spbill_create_ip'] = $ip; $param['notify_url'] = "http://www.#"; $param['trade_type'] = "JSAPI"; $param['openid'] = "$openid"; //字典排序 ksort($param); $sign_raw = ""; foreach($param as $k => $v){ $sign_raw .= $k."=".$v."&"; } $sign_raw .= "key=#"; //生成签名 $sign = strtoupper(md5($sign_raw)); $xml = <<<EOF <xml> <appid>$appid</appid> <body>支付</body> <mch_id>#</mch_id> <nonce_str>$getNonceNumstring</nonce_str> <notify_url>http://www.#</notify_url> <out_trade_no>$out_trade_no</out_trade_no> <spbill_create_ip>$ip</spbill_create_ip> <total_fee>1</total_fee> <trade_type>JSAPI</trade_type> <openid>$openid</openid> <sign>$sign</sign> </xml> EOF; $url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; //调用接口,返回xml数据包含跳转url; $result = postXmlCurl($xml, $url); //解析xml $xml = simplexml_load_string($result); $bigarr = array(); //循环生成数组 foreach($xml->children() as $child){ $key = $child->getName(); $bigarr["$key"] = "$child";//必须加引号 } print_r($bigarr); $p = new Jssdk; $singlepage = $p->getSignPackge(); print_r($singlepage); $noncestr123 = $singlepage["nonceStr"]; $prepay_id = $bigarr["prepay_id"]; //页面计算签名 $pagearr = array( "appId" => "$appid", "timeStamp" => time(), "nonceStr" => "$noncestr123", "package" => "prepay_id=$prepay_id", "signType" => "MD5" ); //字典排序 ksort($pagearr); $sign_raw1 = ""; foreach($pagearr as $k => $v){ $sign_raw1 .= $k."=".$v."&"; } $sign_raw1 .= "key=#"; //生成签名 $signs = strtoupper(md5($sign_raw1)); print_r($pagearr); echo $signs; ?> <script type="text/javascript"> wx.config({ debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId: '#', // 必填,公众号的唯一标识 timestamp: <?php echo $singlepage["timestamp"] ?>, // 必填,生成签名的时间戳 nonceStr: '<?php echo $singlepage["nonceStr"] ?>', // 必填,生成签名的随机串 signature: '<?php echo $singlepage["signature"] ?>',// 必填,签名 jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表 }); wx.ready(function(){ // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。 }); function pay(){ wx.chooseWXPay({ timestamp: <?php echo time() ?>, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符 nonceStr: '<?php echo $singlepage["nonceStr"]?>', // 支付签名随机串,不长于 32 位 package: 'prepay_id=<?php echo $bigarr["prepay_id"]?>', // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*) signType: 'MD5', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5' paySign: '<?php echo $signs?>', // 支付签名 success: function (res) { // 支付成功后的回调函数 alert(res); } }); } </script> <h1 onclick="pay()">点我支付</h1> <?php function postXmlCurl($xml, $url, $useCert = false, $second = 30){ $ch = curl_init(); //设置超时 curl_setopt($ch, CURLOPT_TIMEOUT, $second); curl_setopt($ch,CURLOPT_URL, $url); if(stripos($url,"https://")!==FALSE){ curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); }else{ curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验 } //设置header curl_setopt($ch, CURLOPT_HEADER, FALSE); //要求结果为字符串且输出到屏幕上 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); if($useCert == true){ //设置证书 //使用证书:cert 与 key 分别属于两个.pem文件 curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLCERT, "###.pem"); curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLKEY, "###.pem"); curl_setopt($ch, CURLOPT_CAINFO, "###.pem"); } //post提交方式 curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); //运行curl $data = curl_exec($ch); //返回结果 if($data){ curl_close($ch); return $data; } else { $error = curl_errno($ch); curl_close($ch); echo "error"; } }