首先微信支付需注冊 微信公從平台開發 和 微信支付商戶平台
關於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" onclick="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);
//設置header
curl_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>
