首先微信支付需注册 微信公从平台开发 和 微信支付商户平台
关于4个密钥,如何获得:有图
AppID(应用ID) :wx000000000 (来自微信公众平台-》开发者中心-》配置项-》开发者ID-》AppID(应用ID))AppSecret(应用密钥) :62d0000000000000000000ae (来自微信公众平台-》开发者中心-》配置项-》开发者ID-》AppSecret(应用密钥))商户号 :0000000 (来自微信支付商户平台-》帐号设置 -》帐号信息-》基本帐号信息-》微信支付商户号:00000000 (小知:纯数字))商户密钥: :0c8300000000000000000b (来自您申请微信支付商户平台时发送到你邮件里的一串码,若丢失,可重新申请,步骤:商户平台-》帐户设置-》API安全-》API密钥-》右下角有“设置密钥”)
关于代码,我将整理为一个页面:wxpay.php
header("Content-type: text/html; charset=utf-8");
$wx = new wxpay();
$payment = array('wxpay_AppSecret' => '0c830a000000000f12b0b',//(来自您申请微信支付商户平台时发送到你邮件里的一串码,若丢失,可重新申请,步骤:商户平台-》帐户设置-》API安全-》API密钥-》右下角有“设置密钥”)'wxpay_AppID' => 'wx00000000b30',//(来自微信公众平台-》开发者中心-》配置项-》开发者ID-》AppID(应用ID))'wxpay_shanghuID' => '120000102',//(来自微信支付商户平台-》帐号设置 -》帐号信息-》基本帐号信息-》微信支付商户号:00000000 (小知:纯数字))
);
$order = array('order_sn' => '201505191450',//这是订单SN'order_amount' => 0.01, //金额
);
$openid = 'oT0000000000000000GNkNM3s';//此OPENID是微信的唯一标识,需用API获得,此贴按下不表,择日发贴
$notify_url = "http://m.sgfoot.com/auth/respond.php";//必须是授权目录http://m.sgfoot.com/auth/
echo $wx->get_code($openid, $order, $payment);
/*** 微信支付类*/
class wxpay
{var $parameters; // cft 参数var $payment; // 配置信息/*** 生成支付代码** @param array $order* 订单信息* @param array $payment* 支付方式信息*/function get_code($openid, $order, $payment, $notify_url){ // 配置参数$this->payment = $payment; //设置必填参数//根目录url$out_trade_no = $order['order_sn'] . 'o' . rand(1, 100); $this->setParameter('body', $order['order_sn']);$this->setParameter("openid", "{$openid}");//用户唯一标识 $this->setParameter("out_trade_no", $out_trade_no);//商户订单号 $this->setParameter("total_fee", $order['order_amount'] * 100);//总金额$this->setParameter("notify_url", "{$notify_url}");//通知地址 $this->setParameter("trade_type", "JSAPI");//交易类型$prepay_id = $this->getPrepayId();$jsApiParameters = $this->getParameters($prepay_id);// wxjsbridge$js = '<script type="text/javascript">function jsApiCall(){WeixinJSBridge.invoke("getBrandWCPayRequest",'.$jsApiParameters.',function(res){if(res.err_msg == "get_brand_wcpay_request:ok"){location.href="/respond.php?code=wxpay&status=1&subject='.$out_trade_no.'"}else{window.location.href="respond.php?code=wxpay&status=0&subject="}});}function callpay(){if (typeof WeixinJSBridge == "undefined"){if( document.addEventListener ){document.addEventListener("WeixinJSBridgeReady", jsApiCall, false);}else if (document.attachEvent){document.attachEvent("WeixinJSBridgeReady", jsApiCall);document.attachEvent("onWeixinJSBridgeReady", jsApiCall);}}else{jsApiCall();}}</script>'; $button = '<div style="text-align:center"><button class="c-btn3" type="button" οnclick="callpay()" style="background:#f16681;display:inline-block;padding:5px 10px;border-radius:3px;font-size:14px;color:#fff;border:1px solid #fff;" >微信安全支付</button></div>' . $js;return $button;}function trimString($value){$ret = null;if (null != $value) {$ret = $value;if (strlen($ret) == 0) {$ret = null;}}return $ret;}/*** 作用:产生随机字符串,不长于32位*/public function createNoncestr( $length = 32 ) {$chars = "abcdefghijklmnopqrstuvwxyz0123456789"; $str ="";for ( $i = 0; $i < $length; $i++ ) { $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1); } return $str;}/*** 作用:设置请求参数*/function setParameter($parameter, $parameterValue){$this->parameters[$this->trimString($parameter)] = $this->trimString($parameterValue);}/*** 作用:生成签名*/public function getSign($Obj){foreach ($Obj as $k => $v){$Parameters[$k] = $v;}//签名步骤一:按字典序排序参数ksort($Parameters);$buff = "";foreach ($Parameters as $k => $v){$buff .= $k . "=" . $v . "&";}$String;if (strlen($buff) > 0) {$String = substr($buff, 0, strlen($buff)-1);}//echo '【string1】'.$String.'</br>';//签名步骤二:在string后加入KEY$String = $String."&key=".$this->payment['wxpay_AppSecret'];//echo "【string2】".$String."</br>";//签名步骤三:MD5加密$String = md5($String);//echo "【string3】 ".$String."</br>";//签名步骤四:所有字符转为大写$result_ = strtoupper($String);//echo "【result】 ".$result_."</br>";return $result_;}/*** 作用:以post方式提交xml到对应的接口url*/public function postXmlCurl($xml,$url,$second=30){ //初始化curl $ch = curl_init();//设置超时curl_setopt($ch, CURLOP_TIMEOUT, $second);//这里设置代理,如果有的话//curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');//curl_setopt($ch,CURLOPT_PROXYPORT, 8080);curl_setopt($ch,CURLOPT_URL, $url);curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);//设置headercurl_setopt($ch, CURLOPT_HEADER, FALSE);//要求结果为字符串且输出到屏幕上curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);//post提交方式curl_setopt($ch, CURLOPT_POST, TRUE);curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);//运行curl$data = curl_exec($ch);curl_close($ch);//返回结果if($data){curl_close($ch);return $data;}else { $error = curl_errno($ch);echo "curl出错,错误码:$error"."<br>"; echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>";curl_close($ch);return false;}}/*** 获取prepay_id*/function getPrepayId(){//设置接口链接$url = "https://api.mch.weixin.qq.com/pay/unifiedorder";try{//检测必填参数if($this->parameters["out_trade_no"] == null){throw new Exception("缺少统一支付接口必填参数out_trade_no!"."<br>");}elseif($this->parameters["body"] == null){throw new Exception("缺少统一支付接口必填参数body!"."<br>");}elseif ($this->parameters["total_fee"] == null ) {throw new Exception("缺少统一支付接口必填参数total_fee!"."<br>");}elseif ($this->parameters["notify_url"] == null) {throw new Exception("缺少统一支付接口必填参数notify_url!"."<br>");}elseif ($this->parameters["trade_type"] == null) {throw new Exception("缺少统一支付接口必填参数trade_type!"."<br>");}elseif ($this->parameters["trade_type"] == "JSAPI" && $this->parameters["openid"] == NULL){throw new Exception("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!"."<br>");}$this->parameters["appid"] = $this->payment['wxpay_AppID'];//公众账号ID$this->parameters["mch_id"] = $this->payment['wxpay_shanghuID'];//商户号$this->parameters["spbill_create_ip"] = $_SERVER['REMOTE_ADDR'];//终端ip$this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串$this->parameters["sign"] = $this->getSign($this->parameters);//签名$xml = "<xml>";foreach ($this->parameters as $key=>$val){if (is_numeric($val)){$xml.="<".$key.">".$val."</".$key.">"; }else{$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";} }$xml.="</xml>";}catch (Exception $e){die($e->getMessage());}$response = $this->postXmlCurl($xml, $url, 30);$result = json_decode(json_encode(simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA)), true);$prepay_id = $result["prepay_id"];return $prepay_id;}/*** 作用:设置jsapi的参数*/public function getParameters($prepay_id){$timeStamp = time();$jsApiObj["appId"] = $this->payment['wxpay_AppID']; $jsApiObj["timeStamp"] = "$timeStamp";$jsApiObj["nonceStr"] = $this->createNoncestr();$jsApiObj["package"] = "prepay_id=$prepay_id";$jsApiObj["signType"] = "MD5";$jsApiObj["paySign"] = $this->getSign($jsApiObj);$this->parameters = json_encode($jsApiObj);return $this->parameters;}
}
关于报 getRrandWCPayRequest:fail_invalid appid 错误。
我的代码是基于ecshop开发的。一直报错。后来单狂拿出来,整理一个文件。将代码放在根目录的auth目录下。
支付目录是 http://m.sgfoot.com/auth/wxpay.php (wxpay.php则是上面的代码)
授权目录则是 http://m.sgfoot.com/auth/
(重点说明:授权目录填写是你支付的页面在哪个目录下就填当前目录下的目录。否则出错,不会弹出支付窗口。)
(经多次测试,如果在网站的根目录下,即使授权了,也报 getRrandWCPayRequest:fail_invalid appid 错误,解决方法则是:放在某目录下,再授权此目录,如果是根目录下,无法完成支付,必须要二级目录或三级等,不知这是微信硬性规定还是BUG)
关于返回页面,如下。放在当前支付目录下。respond.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<?php
/* * To change this license header, choose License Headers in Project Properties.* To change this template file, choose Tools | Templates* and open the template in the editor.*/
if($_REQUEST['status'] == 1 && isset($_REQUEST['subject'])) {echo '支付成功';
}else {echo "支付失败";
}
?>
</body>
</html>