在统一下单前需要数据签名和获取用户id详情可参看另外两篇文章
http://www.cnblogs.com/itBulls/articles/8645619.html
http://www.cnblogs.com/itBulls/articles/8646375.html
统一下单接口
index.php 文件地址
session_start(); include './Base.php'; class WeiXinPay extends Base { public function __construct() { } } $obi = new WeiXinPay(); $obi->unifiedOrder();
base.php 文件地址
<?php header("Content-type: text/html; charset=utf-8"); /** * Created by PhpStorm. * User: lsh * Date: 2099/3/25 * Time: 16:08 */ class Base { ////支付秘钥 key const KEY ='kkkkksdio87923'; //获取code 的微信服务器地址 const CODEURL = "https://open.weixin.qq.com/connect/oauth2/authorize?"; //你自己的APPID const APPID = 'ssdfqwxx'; //获取openid 的微信服务器地址 const OPENIDURL = 'https://api.weixin.qq.com/sns/oauth2/access_token?'; //开发者秘钥 const SECRET = 'b8sdjfi28379923834'; //商户id const MCHID = '243926561'; //统一下单地址 const UNURL = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; //不需要用户确认授权 const SCOPE = 'snsapi_base'; //生成签名 public function getSign($arr) { //去除数组中的空值 $arr = array_filter($arr); //如果数组中有签名删除签名 if(isset($arr['sing'])) { unset($arr['sing']); } //按照键名字典排序 ksort($arr); //生成URL格式的字符串 //http_build_query()中文自动转码需要处理下 $str = http_build_query($arr)."&key=".self::KEY; //echo $str; //appid=dkdfg&body=2347%E4%BA%AC%E4%B8%9C%E5%95%86%E5%9F%8E&mch_id=sdfgd&key=kkkkksdio87923CBEF716EF1A065E6979DE3170BE3B6B8 $str = $this->arrToUrl($str); //echo $str; //header("Content-type: text/html; charset=utf-8"); // echo strtoupper(md5($str)); return strtoupper(md5($str)); } //获取签名 待签名的数组 public function setSing($arr) { $arr['sing'] = $this->getSign($arr); return $arr; } //URL解码为中文 public function arrToUrl($str) { return urldecode($str); } //验证签名 public function checkSing($arr) { //获取签名 $sing = $this->getSign($arr); if($sing == $arr['sing']) { return true; } else { return false; } } //获取openid public function getOpenId() { //如果已经获取到用户的openId就存储在session中 if(isset($_SESSION['openid'])) { return $_SESSION['openid']; } else { //1.用户访问微信服务器地址 先获取到微信get方式传递过来的code //2.根据code获取到openID if(! isset($_GET['code'])) { //没有获取到微信返回来的code ,让用户再次访问微信服务器地址 //redirect_uri 解释 //跳转地址:你发起请求微信服务器获取code , //微信服务器返回来给你的code的接收地址(通常就是发起支付的页面地址) //组装跳转地址 $redirect_uri = self::CODEURL .'appid='.self::APPID.'&redirect_uri='.$_SERVER['REQUEST_SCHEME'].'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'&response_type=code&scope='.self::SCOPE.'&state=STATE#wechat_redirect'; // echo $redirect_uri; //跳转 让用过去获取code header("location:{$redirect_uri}"); } else { //调用接口获取openId $openidurl = self::OPENIDURL.'appid='.self::APPID.'&secret='.self::SECRET.'&code='.$_GET['code'].'&grant_type=authorization_code'; //请求获取用户的openID $data = file_get_contents($openidurl); $arr = json_decode($data,true); //获取到的openid保存到session 中 $_SESSION['openid'] = $arr['openid']; return $_SESSION; } } } //调用统一下单 api public function unifiedOrder() { /** * 1.构建原始数据 * 2.加入签名 * 3、将数据转换为XML * 4、发生XML格式的数据到接口地址 * * */ //1.构建原始数据 $params = array( 'appid'=>self::APPID, 'mch_id'=>self::MCHID, 'nonce_str'=>md5(time()), 'body'=>'商品描述信息', //存储到数据库的订单id 'out_trade_no'=>1380, 'total_fee'=>'支付的商品价格', //客户端ip 'spbill_create_ip'=>$_SERVER['REMOTE_ADDR'], //支付结果通知地址(你自己服务器的地址,修改订单状态) 'notify_url'=>'http://www.ccten123.com/notify.php', //支付类型 'trade_type'=>'JSAPI', //产品id 'product_id'=>1380, //OPENID 'openid'=>$this->getOpenId(), ); //2.加入签名 $params = $this->setSing($params); // echo '<pre>'; // print_r($params); //3.将数据转换为XML $xmlData = $this->ArrToXml($params); //记录到日志查看 $this->logs('./logs/','sendXmlData.txt',$xmlData); //4.发送数据 $resultData = $this->postXmlOrJson(self::UNURL,$xmlData); //接收下单结果 返回格式是xml的 $resultData = $this->XmlToArr($resultData); // 在resultData 中就有微信服务器返回的prepay_id return $resultData; } //获取prepay_id public function getPrePayId() { } //数组转xml public function ArrToXml($arr) { if(!is_array($arr) || count($arr) == 0) return ''; $xml = "<xml>"; foreach ($arr as $key=>$val) { if (is_numeric($val)){ $xml.="<".$key.">".$val."</".$key.">"; }else{ $xml.="<".$key."><![CDATA[".$val."]]></".$key.">"; } } $xml.="</xml>"; return $xml; } //Xml转数组 public function XmlToArr($xml) { if($xml == '') return ''; libxml_disable_entity_loader(true); $arr = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); return $arr; } //日志记录方法 public function logs($filePath,$fileName,$data) { if(is_dir($filePath)) { file_put_contents($filePath.$fileName,$data); } else { echo "当前目录下,目录".$filePath."不存在"; } } //提交XML方法 public function postXmlOrJson($url,$data) { //$data = 'XML或者JSON等字符串'; $ch = curl_init(); $params[CURLOPT_URL] = $url; //请求url地址 $params[CURLOPT_HEADER] = false; //是否返回响应头信息 $params[CURLOPT_RETURNTRANSFER] = true; //是否将结果返回 $params[CURLOPT_FOLLOWLOCATION] = true; //是否重定向 $params[CURLOPT_POST] = true; $params[CURLOPT_POSTFIELDS] = $data; //防止curl请求 https站点报错 禁用证书验证 $params[CURLOPT_SSL_VERIFYPEER] = false; $params[CURLOPT_SSL_VERIFYHOST] = false; curl_setopt_array($ch, $params); //传入curl参数 $content = curl_exec($ch); //执行 curl_close($ch); //关闭连接 return $content; } }