一、Model層,Wxpay.php
<?php
namespace appcommonmodel;
class Wxpay
{
private $appid = `wxe8*****d4`; //微信公眾號appid
private $secret = `37c4*******5f0`; //微信公眾號appsecret
private $mchid = `13******02`; //商家號
private $key = `5363e******49e8`; //支付金鑰
private $sslcert_path = `apiclient_cert.pem`; //證照所在絕對路徑
private $sslkey_path = `apiclient_key.pem`; //證照所在絕對路徑
public function __construct($appid = ``, $secret = ``, $mchid = ``, $key = ``)
{
if(!empty($appid)) $this->appid = $appid;
if(!empty($secret)) $this->secret = $secret;
if(!empty($mchid)) $this->mchid = $mchid;
if(!empty($key)) $this->key= $key;
}
/*
* 微信內H5調起支付
* @params string $openid : 微信使用者openid
* @params string $out_trade_no : 商家生成的訂單號(唯一性)
* @params int $total_fee : 支付金額,單位分
* return array $ret : 返回支付時所需要的資料
* */
public function payForWeixin($openid,$out_trade_no,$total_fee,$attach=`微信支付`,$body=`微信支付`)
{
//支付資料
$data[`openid`] = $openid;
$data[`out_trade_no`] = $out_trade_no;
$data[`total_fee`] = $total_fee*100;
$data[`spbill_create_ip`] = $_SERVER["REMOTE_ADDR"];
$data[`attach`] = $attach;
$data[`body`] = $body;
$data[`appid`] = $this->appid;
$data[`mch_id`] = $this->mchid;
$data[`nonce_str`] = random(12);
$data[`trade_type`] = "JSAPI";
$data[`notify_url`] = "http://****.com/home/wxpaynofiy/notify.html";
$sign = $this->getParam($data);
$dataXML = "<xml>
<appid>".$data[`appid`]."</appid>
<attach>".$data[`attach`]."</attach>
<body>".$data[`body`]."</body>
<mch_id>".$data[`mch_id`]."</mch_id>
<nonce_str>".$data[`nonce_str`]."</nonce_str>
<notify_url>".$data[`notify_url`]."</notify_url>
<openid>".$data[`openid`]."</openid>
<out_trade_no>".$data[`out_trade_no`]."</out_trade_no>
<spbill_create_ip>".$data[`spbill_create_ip`]."</spbill_create_ip>
<total_fee>".$data[`total_fee`]."</total_fee>
<trade_type>".$data[`trade_type`]."</trade_type>
<sign>".$sign."</sign>
</xml>";
$url = `https://api.mch.weixin.qq.com/pay/unifiedorder`;
$result = $this->https_post($url,$dataXML);
$ret = $this->xmlToArray($result);
if($ret[`return_code`] == `SUCCESS` && $ret[`return_msg`] == `OK`) {
return array(
`appId` => $this->appid,
`timeStamp` => time(),
`nonceStr` => $data[`nonce_str`],
`package` => `prepay_id=`.$ret[`prepay_id`],
`signType` => `MD5`,
`paySign` => $sign
);
} else {
$this->errorLog("微信支付失敗,",$ret);
return null;
}
}
/*
* 微信二維碼支付
* @params string $openid : 使用者的openid
* @params string $out_trade_no : 商戶訂單號
* @params number $total_fee : 訂單金額,單位分
* return string $code_url : 二維碼URL連結
*/
public function payForQrcode($out_trade_no,$total_fee,$body="魔盒CMS",$attach="微信支付")
{
//支付資料
$data[`out_trade_no`] = $out_trade_no;
$data[`total_fee`] = $total_fee*100;
$data[`spbill_create_ip`] = $_SERVER["REMOTE_ADDR"];
$data[`attach`] = $attach;
$data[`body`] = $body;
$data[`appid`] = $this->appid;
$data[`mch_id`] = $this->mchid;
$data[`nonce_str`] = random(12);
$data[`trade_type`] = "NATIVE";
$data[`notify_url`] = "http://****.com/home/wxpaynofiy/notify.html";
$sign = $this->getParam($data);
$dataXML = "<xml>
<appid>".$data[`appid`]."</appid>
<attach>".$data[`attach`]."</attach>
<body>".$data[`body`]."</body>
<mch_id>".$data[`mch_id`]."</mch_id>
<nonce_str>".$data[`nonce_str`]."</nonce_str>
<notify_url>".$data[`notify_url`]."</notify_url>
<out_trade_no>".$data[`out_trade_no`]."</out_trade_no>
<spbill_create_ip>".$data[`spbill_create_ip`]."</spbill_create_ip>
<total_fee>".$data[`total_fee`]."</total_fee>
<trade_type>".$data[`trade_type`]."</trade_type>
<sign>".$sign."</sign>
</xml>";
$url = `https://api.mch.weixin.qq.com/pay/unifiedorder`;
$result = $this->https_post($url,$dataXML);
$ret = $this->xmlToArray($result);
if($ret[`return_code`] == `SUCCESS` && $ret[`return_msg`] == `OK`) {
return $ret[`code_url`];
} else {
$this->errorLog("獲取微信支付二維碼失敗,",$ret);
return null;
}
}
/*
* 訂單查詢
* @params string $transaction_id : 微信訂單號
* @params string $out_trade_no : 商家訂單號(與微信訂單號二選一)
* */
public function findOrder($out_trade_no)
{
$data[`appid`] = $this->appid;
$data[`mch_id`] = $this->mchid;
$data[`nonce_str`] = random(12);
$data[`out_trade_no`] = $out_trade_no;
$sign = $this->getParam($data);
$dataXML = "<xml>
<appid>".$data[`appid`]."</appid>
<mch_id>".$data[`mch_id`]."</mch_id>
<nonce_str>".$data[`nonce_str`]."</nonce_str>
<out_trade_no>".$data[`out_trade_no`]."</out_trade_no>
<sign>".$sign."</sign>
</xml>";
$url = `https://api.mch.weixin.qq.com/pay/orderquery`;
$result = $this->https_post($url,$dataXML);
$ret = $this->xmlToArray($result);
if($ret[`return_code`] == `SUCCESS` && $ret[`return_msg`] == `OK`) {
return $ret;
} else {
$this->errorLog("查詢微信支付訂單失敗,",$ret);
return null;
}
}
/*
* 退款訂單查詢
* @params string $transaction_id : 微信訂單號
* @params string $out_trade_no : 商家訂單號(與微信訂單號二選一)
* */
public function findRefundOrder($out_trade_no)
{
$data[`appid`] = $this->appid;
$data[`mch_id`] = $this->mchid;
$data[`nonce_str`] = random(12);
$data[`out_trade_no`] = $out_trade_no;
$sign = $this->getParam($data);
$dataXML = "<xml>
<appid>".$data[`appid`]."</appid>
<mch_id>".$data[`mch_id`]."</mch_id>
<nonce_str>".$data[`nonce_str`]."</nonce_str>
<out_trade_no>".$data[`out_trade_no`]."</out_trade_no>
<sign>".$sign."</sign>
</xml>";
$url = `https://api.mch.weixin.qq.com/pay/refundquery`;
$result = $this->https_post($url,$dataXML);
$ret = $this->xmlToArray($result);
if($ret[`return_code`] == `SUCCESS` && $ret[`return_msg`] == `OK`) {
return $ret;
} else {
$this->errorLog("查詢微信支付退款訂單失敗,",$ret);
return $ret[`err_code_des`];
}
}
/*
* 申請退款
* @params string $out_trade_no : 商戶訂單號
* @params string $out_refund_no : 商戶退款單號
* @params int $total_fee : 訂單金額
* @params int $refund_fee : 退款金額
* @params string $refund_desc : 退款原因
* */
public function refund($out_trade_no,$out_refund_no,$total_fee,$refund_fee,$refund_desc=`退款`)
{
$data[`appid`] = $this->appid;
$data[`mch_id`] = $this->mchid;
$data[`nonce_str`] = random(12);
$data[`out_trade_no`] = $out_trade_no;
$data[`out_refund_no`] = $out_refund_no;
$data[`total_fee`] = $total_fee*100;
$data[`refund_fee`] = $refund_fee*100;
$data[`refund_desc`] = $refund_desc;
$data[`notify_url`] = "http://*****.com/home/wxpaynofiy/refund.html";
$sign = $this->getParam($data);
$dataXML = "<xml>
<appid>".$data[`appid`]."</appid>
<mch_id>".$data[`mch_id`]."</mch_id>
<nonce_str>".$data[`nonce_str`]."</nonce_str>
<out_trade_no>".$data[`out_trade_no`]."</out_trade_no>
<out_refund_no>".$data[`out_refund_no`]."</out_refund_no>
<total_fee>".$data[`total_fee`]."</total_fee>
<refund_fee>".$data[`refund_fee`]."</refund_fee>
<refund_desc>".$data[`refund_desc`]."</refund_desc>
<notify_url>".$data[`notify_url`]."</notify_url>
<sign>".$sign."</sign>
</xml>";
$url = `https://api.mch.weixin.qq.com/secapi/pay/refund`;
$result = $this->https_post($url,$dataXML,true);
$ret = $this->xmlToArray($result);
if($ret[`return_code`] == `SUCCESS` && $ret[`return_msg`] == `OK`) {
return $ret;
} else {
$this->errorLog("微信退款失敗,",$ret);
return null;
}
}
/*
* 企業付款至使用者零錢
* @params string $openid : 使用者openid
* @params int $total_fee : 付款金額,單位分
* @params string $out_trade_no : 商家訂單號
* @params string $username : 微信使用者名稱稱(注意微信暱稱若為空時支付會出錯)
* @params string $desc : 付款描述
* @params string $check_name : 是否檢測使用者名稱
* */
public function payForUser($openid,$total_fee,$out_trade_no,$username=`魔盒CMS`,$desc=`魔盒CMS付款給使用者`,$check_name=`NO_CHECK`)
{
$data[`amount`] = $total_fee*100;
$data[`check_name`] = $check_name;
$data[`desc`] = $desc;
$data[`mch_appid`] = $this->appid;
$data[`mchid`] = $this->mchid;
$data[`nonce_str`] = random(12);
$data[`openid`] = $openid;
$data[`partner_trade_no`] = $out_trade_no;
$data[`re_user_name`] = $username;
$data[`spbill_create_ip`] = $_SERVER["REMOTE_ADDR"];
$sign = $this->getParam($data);
$dataXML="<xml>
<mch_appid>".$data[`mch_appid`]."</mch_appid>
<mchid>".$data[`mchid`]."</mchid>
<nonce_str>".$data[`nonce_str`]."</nonce_str>
<partner_trade_no>".$data[`partner_trade_no`]."</partner_trade_no>
<openid>".$data[`openid`]."</openid>
<check_name>".$data[`check_name`]."</check_name>
<re_user_name>".$data[`re_user_name`]."</re_user_name>
<amount>".$data[`amount`]."</amount>
<desc>".$data[`desc`]."</desc>
<spbill_create_ip>".$data[`spbill_create_ip`]."</spbill_create_ip>
<sign>".$sign."</sign>
</xml>";
$url = `https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers`;
$result = $this->https_post($url,$dataXML,true);
$ret = $this->xmlToArray($result);
if($ret[`return_code`]==`SUCCESS` && $ret[`result_code`] == `SUCCESS`)
{
//支付成功返回商戶訂單號、微信訂單號、微信支付成功時間
$result[`partner_trade_no`] = $ret[`partner_trade_no`];
$result[`payment_no`] = $ret[`payment_no`];
$result[`payment_time`] = $ret[`payment_time`];
return $ret;
} else {
$this->errorLog(`付款給使用者失敗`,$ret);
return null;
}
}
/*
* 普通紅包
* @params string $out_trade_no : 商家訂單號
* @params string $openid : 接收紅包使用者的openid
* @params int $total_fee : 紅包金額,單位分
* @params int $total_num : 紅包發放總人數
* @params string $wishing : 紅包祝福語
* @params string $act_name : 活動名稱
* @params string $remark : 備註
* @params string $scene_id :場景值ID。發放紅包使用場景,紅包金額大於200或者小於1元時必傳。PRODUCT_1:商品促銷、PRODUCT_2:抽獎、PRODUCT_3:虛擬物品兌獎 、PRODUCT_4:企業內部福利、PRODUCT_5:渠道分潤、PRODUCT_6:保險回饋、PRODUCT_7:彩票派獎、PRODUCT_8:稅務刮獎
* */
public function redPack($openid,$total_fee,$out_trade_no,$total_num = 1,$wishing = `感謝您光臨***平臺進行購物`,$act_name=`***購物發紅包`,$remark = `購物領紅包`)
{
$data[`mch_billno`] = $out_trade_no;
$data[`mch_id`] = $this->mchid;
$data[`wxappid`] = $this->appid;
$data[`send_name`] = `傳送紅包者的名稱`;
$data[`re_openid`] = $openid;
$data[`total_amount`] = $total_fee;
$data[`total_num`] = $total_num;
$data[`wishing`] = $wishing;
$data[`client_ip`] = $_SERVER["REMOTE_ADDR"];
$data[`act_name`] = $act_name;
$data[`remark`] = $remark;
$data[`nonce_str`] = random(12);
$sign = $this->getParam($data);
$dataXML="<xml>
<sign>".$sign."</sign>
<mch_billno>".$data[`mch_billno`]."</mch_billno>
<mch_id>".$data[`mch_id`]."</mch_id>
<wxappid>".$data[`wxappid`]."</wxappid>
<send_name>".$data[`send_name`]."</send_name>
<re_openid>".$data[`re_openid`]."</re_openid>
<total_amount>".$data[`total_amount`]."</total_amount>
<total_num>".$data[`total_num`]."</total_num>
<wishing>".$data[`wishing`]."</wishing>
<client_ip>".$data[`client_ip`]."</client_ip>
<act_name>".$data[`act_name`]."</act_name>
<remark>".$data[`remark`]."</remark>
<nonce_str>".$data[`nonce_str`]."</nonce_str>
</xml>";
$url = `https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack`;
$result = $this->https_post($url,$dataXML,true);
$ret = $this->xmlToArray($result);
if($ret[`return_code`]==`SUCCESS` && $ret[`result_code`] == `SUCCESS`)
{
return $ret;
} else {
$this->errorLog(`發放普通紅包失敗`,$ret);
return $ret[`err_code_des`];
}
}
/*
* 裂變紅包:一次可以發放一組紅包。首先領取的使用者為種子使用者,種子使用者領取一組紅包當中的一個,並可以通過社交分享將剩下的紅包給其他使用者。
* 裂變紅包充分利用了人際傳播的優勢。
* @params string $out_trade_no : 商家訂單號
* @params string $openid : 接收紅包使用者的openid
* @params int $total_fee : 紅包金額,單位分
* @params int $total_num : 紅包發放總人數
* @params string $wishing : 紅包祝福語
* @params string $act_name : 活動名稱
* @params string $remark : 備註
* @params string $scene_id :場景值ID。發放紅包使用場景,紅包金額大於200或者小於1元時必傳。PRODUCT_1:商品促銷、PRODUCT_2:抽獎、PRODUCT_3:虛擬物品兌獎 、PRODUCT_4:企業內部福利、PRODUCT_5:渠道分潤、PRODUCT_6:保險回饋、PRODUCT_7:彩票派獎、PRODUCT_8:稅務刮獎
* */
public function redPackGroup($openid,$total_fee,$out_trade_no,$total_num,$wishing = `感謝您光臨***進行購物`,$act_name=`**購物發紅包`,$remark = `購物領紅包`)
{
$data[`mch_billno`] = $out_trade_no;
$data[`mch_id`] = $this->mchid;
$data[`wxappid`] = $this->appid;
$data[`send_name`] = `傳送紅包者的名稱`;
$data[`re_openid`] = $openid;
$data[`total_amount`] = $total_fee;
$data[`amt_type`] = `ALL_RAND`; //ALL_RAND—全部隨機,商戶指定總金額和紅包發放總人數,由微信支付隨機計算出各紅包金額
$data[`total_num`] = $total_num;
$data[`wishing`] = $wishing;
$data[`client_ip`] = $_SERVER["REMOTE_ADDR"];
$data[`act_name`] = $act_name;
$data[`remark`] = $remark;
$data[`nonce_str`] = random(12);
$sign = $this->getParam($data);
$dataXML="<xml>
<sign>".$sign."</sign>
<mch_billno>".$data[`mch_billno`]."</mch_billno>
<mch_id>".$data[`mch_id`]."</mch_id>
<wxappid>".$data[`wxappid`]."</wxappid>
<send_name>".$data[`send_name`]."</send_name>
<re_openid>".$data[`re_openid`]."</re_openid>
<total_amount>".$data[`total_amount`]."</total_amount>
<amt_type>".$data[`amt_type`]."</amt_type>
<total_num>".$data[`total_num`]."</total_num>
<wishing>".$data[`wishing`]."</wishing>
<client_ip>".$data[`client_ip`]."</client_ip>
<act_name>".$data[`act_name`]."</act_name>
<remark>".$data[`remark`]."</remark>
<nonce_str>".$data[`nonce_str`]."</nonce_str>
</xml>";
$url = `https://api.mch.weixin.qq.com/mmpaymkttransfers/sendgroupredpack`;
$result = $this->https_post($url,$dataXML,true);
$ret = $this->xmlToArray($result);
if($ret[`return_code`]==`SUCCESS` && $ret[`result_code`] == `SUCCESS`)
{
return $ret;
} else {
$this->errorLog(`發放裂變紅包失敗`,$ret);
return $ret[`err_code_des`];
}
}
/*
* 查詢紅包記錄
* @params string $out_trade_no : 商家訂單號
* */
public function findRedPack($out_trade_no)
{
$data[`mch_billno`] = $out_trade_no;
$data[`mch_id`] = $this->mchid;
$data[`appid`] = $this->appid;
$data[`bill_type`] = `MCHT`; //MCHT:通過商戶訂單號獲取紅包資訊。
$data[`nonce_str`] = random(12);
$sign = $this->getParam($data);
$dataXML="<xml>
<sign>".$sign."</sign>
<mch_billno>".$data[`mch_billno`]."</mch_billno>
<mch_id>".$data[`mch_id`]."</mch_id>
<appid>".$data[`appid`]."</appid>
<bill_type>".$data[`bill_type`]."</bill_type>
<nonce_str>".$data[`nonce_str`]."</nonce_str>
</xml>";
$url = `https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo`;
$result = $this->https_post($url,$dataXML,true);
$ret = $this->xmlToArray($result);
if($ret[`return_code`]==`SUCCESS` && $ret[`result_code`] == `SUCCESS`)
{
return $ret;
} else {
$this->errorLog(`查詢紅包記錄失敗`,$ret);
return $ret[`err_code_des`];
}
}
/*
* 獲取使用者微信的OPENID
* */
public function openid($c=false)
{
if($_GET[`state`]!="zgm"){
$t = $c ? "snsapi_userinfo" : "snsapi_base";
$url=urlencode(get_url());
$url="https://open.weixin.qq.com/connect/oauth2/authorize?appid=".$this->appid."&redirect_uri=".$url."&response_type=code&scope=".$t."&state=zgm#wechat_redirect";
echo "<html><script>window.location.href=`$url`;</script></html>";
exit;
}
if($_GET[`code`]){
$url="https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$this->appid."&secret=".$this->secret."&code=".$_GET[`code`]."&grant_type=authorization_code";
$wx_db=json_decode($this->https_get($url));
if($c){
$url_2="https://api.weixin.qq.com/sns/userinfo?access_token=".$wx_db->access_token."&openid=".$wx_db->openid."&lang=zh_CN";
$db=json_decode($this->https_get($url_2));
return $db;
}else{
return $wx_db->openid;
}
}
}
/*
* 發起網路GET請求
* @params string $url : URL連結
*/
private function https_get($url)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLOPT_HEADER, FALSE) ;
curl_setopt($curl, CURLOPT_TIMEOUT,60);
if (curl_errno($curl)) {
return `Errno`.curl_error($curl);
}
else{$result=curl_exec($curl);}
curl_close($curl);
return $result;
}
//對引數排序,生成MD5加密簽名
private function getParam($paramArray, $isencode=false)
{
$paramStr = ``;
ksort($paramArray);
$i = 0;
foreach ($paramArray as $key => $value)
{
if ($key == `Signature`){
continue;
}
if ($i == 0){
$paramStr .= ``;
}else{
$paramStr .= `&`;
}
$paramStr .= $key . `=` . ($isencode?urlencode($value):$value);
++$i;
}
$stringSignTemp=$paramStr."&key=".$this->key;
$sign=strtoupper(md5($stringSignTemp));
return $sign;
}
//POST提交資料
private function https_post($url,$data,$ssl = false)
{
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, $url );
curl_setopt ( $ch, CURLOPT_CUSTOMREQUEST, "POST" );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, FALSE );
if($ssl) {
curl_setopt ( $ch,CURLOPT_SSLCERT,$this->sslcert_path);
curl_setopt ( $ch,CURLOPT_SSLKEY,$this->sslkey_path);
}
curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, 1 );
curl_setopt ( $ch, CURLOPT_AUTOREFERER, 1 );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $data );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
$result = curl_exec($ch);
if (curl_errno($ch)) {
return `Errno: `.curl_error($ch);
}
curl_close($ch);
return $result;
}
/*
* XML轉array
* @params xml $xml : xml 資料
* return array $data : 轉義後的array陣列
*/
private function xmlToArray($xml)
{
libxml_disable_entity_loader(true);
$xmlstring = simplexml_load_string($xml, `SimpleXMLElement`, LIBXML_NOCDATA);
$val = json_decode(json_encode($xmlstring),true);
return $val;
}
/*
* 記錄日誌
* @params string $msg : 提示語句
* @params array $ret : 錯誤結果
*/
private function errorLog($msg,$ret)
{
file_put_contents(ROOT_PATH . `runtime/error/wxpay.log`, "[" . date(`Y-m-d H:i:s`) . "] ".$msg."," .json_encode($ret).PHP_EOL, FILE_APPEND);
}
}
二、Controller層,Test.php
<?php
namespace appgoodscontroller;
use appcommonmodelWxpay;
class Test
{
/*
* 呼叫微信支付
* 一、獲取微信使用者的openid;
* 二、呼叫微信支付介面
* 三、生成H5中使用的簽名內容
*/
public function wx()
{
$wxpay = new Wxpay();
$openid = $wxpay->openid();
$pay = $wxpay->payForWeixin($openid,date(`YmdHis`).rand(1,5),`0.1`);
$paySign =strtoupper(MD5(`appId=`.$pay[`appId`].`&nonceStr=`.$pay[`nonceStr`].`&package=`.$pay[`package`].`&signType=MD5&timeStamp=`.$pay[`timeStamp`].`&key=536*****9e8`));
$h5 = array(
`appId` => $pay[`appId`],
`timeStamp` => $pay[`timeStamp`],
`nonceStr` => $pay[`nonceStr`],
`package` => $pay[`package`],
`signType` => $pay[`signType`],
`paySign` => $paySign
);
$this->assign(`wxpay`,$h5);
return view();
}
}
三、HTML中呼叫微信支付,wx.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>訂單示例</title>
</head>
<body>
<script type="text/javascript">
function onBridgeReady(){
WeixinJSBridge.invoke(
`getBrandWCPayRequest`, {
"appId":"{$wxpay[`appId`]}",
"timeStamp":"{$wxpay[`timeStamp`]}",
"nonceStr":"{$wxpay[`nonceStr`]}",
"package":"{$wxpay[`package`]}",
"signType":"MD5",
"paySign":"{$wxpay[`paySign`]}"
},
function(res){
if(res.err_msg == "get_brand_wcpay_request:ok" ){
// 使用以上方式判斷前端返回,微信團隊鄭重提示:
//res.err_msg將在使用者支付成功後返回ok,但並不保證它絕對可靠。
}
});
}
if (typeof WeixinJSBridge == "undefined"){
if( document.addEventListener ){
document.addEventListener(`WeixinJSBridgeReady`, onBridgeReady, false);
}else if (document.attachEvent){
document.attachEvent(`WeixinJSBridgeReady`, onBridgeReady);
document.attachEvent(`onWeixinJSBridgeReady`, onBridgeReady);
}
}else{
onBridgeReady();
}
</script>
</body>
</html>
四、接收微信支付返回結果,支付時設定的notify_url值,確保此連結外網能訪問。wxpaynofiy.php
<?php
namespace apphomecontroller;
class Wxpaynofiy
{
public function notify()
{
$xml = isset($GLOBALS["HTTP_RAW_POST_DATA"]) ? $GLOBALS[`HTTP_RAW_POST_DATA`] : file_get_contents("php://input");
$data = xmlToArray($xml);
if($data[`return_code`] == `SUCCESS` && $data[`result_code`] == `SUCCESS`){
if($this->checkSign($data)) {
$transaction_id = $data[`transaction_id`]; //微信支付訂單號
$out_trade_no = $data[`out_trade_no`]; //商家訂單號
$this->errorLog(`微信支付返回結果,微信支付訂單號:`.$transaction_id.`,商家訂單號:`.$out_trade_no,[]);
} else {
$this->errorLog(`微信支付返回結果簽名驗證失敗`,$data);
}
} else {
$this->errorLog(`微信支付返回結果`,$data);
}
echo `<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>`;
}
/*
* 驗證簽名
* @params array $result : 微信支付成功返回的結果陣列
* return bool $ret : 成功true,失敗false
* */
private function checkSign(array $data)
{
$str = ``;
ksort($data);
foreach ($data as $k => $v) {
if($k != `sign`) $str .= $k.`=`.$v.`&`;
}
$temp = $str . `key=5363******49e8`; //key:商戶支付金鑰
$sign = strtoupper(md5($temp));
return $sign == $data[`sign`] ? true : false;
}
private function errorLog($msg,$ret)
{
file_put_contents(ROOT_PATH . `runtime/error/wxpaynofiy.log`, "[" . date(`Y-m-d H:i:s`) . "] ".$msg."," .json_encode($ret).PHP_EOL, FILE_APPEND);
}
}
五、常見問題
1、H5支付時出現“簽名錯誤”,需要注意的呼叫微信“統一下單”介面後返回pre_pay_id後,需要使用者再次進行簽名返回給HTML;
2、“支付目錄沒有授權”,進入微信商家管理後臺設定即可;