關于微店整合微信支付時出現的的各種問題的記錄 php版
來源:程序員人生 發布時間:2015-03-07 13:27:10 閱讀次數:5188次
由于公司項目的需要,需要在項目里整合微信支付,公司原本的項目中已有老版本的支付功能,在此不作討論。我需要作的就是加入新版本的支付功能
讓項目里可以支持新老兩種版本的功能。在微信官方下載到了新版支付的php版sdk,看到 WxPay.ub.config.php,SDKRuntimeException.php, WxPayPubHelper.php
3個文件。我需要改造的就是WxPayPubHelper.php這個文件,由于這個文件現在是單用戶配置的,所以我要讓它變成多用戶的,在改造的進程中遇到了幾點問題,也是大家
可能會常常遇到的,在這分享出來,希望能給他人1些幫助。
q1:redirect_uri 參數毛病的問題 !
這個問題出現的比例比較大,在sdk包里有1個demo的文件夾,里面有1個js_api_call.php文件,在他的13行里有以下代碼:
//使用jsapi接口
$jsApi = new JsApi_pub();
//=========步驟1:網頁授權獲得用戶openid============
//通過code取得openid
if (!isset($_GET['code']))
{
//觸發微信返回code碼
$url = $jsApi->createOauthUrlForCode(WxPayConf_pub::JS_API_CALL_URL);
Header("Location: $url");
}else
{
//獲得code碼,以獲得openid
$code = $_GET['code'];
$jsApi->setCode($code);
$openid = $jsApi->getOpenId();
}
$url = $jsApi->createOauthUrlForCode(WxPayConf_pub::JS_API_CALL_URL);
這1句就是設置redirect_uri參數的地方,我把它改造成了自己的地址,代碼以下:
$url = $jsApi->createOauthUrlForCode( $site_domain.base64_decode($_GET['uri']));
為何要用base64編碼呢,由于我的url是像這樣的 :
index.php?g=Wap&m=Wxpay&a=newpay&token=$1&wecha_id=$2&orderid=$3
這個url又臭又長,而且很多&符,沒法辨認出哪部份是自己的url了,還有最重要的部份 WxPayHubHelper.php在大概822行的部份,有1個方法叫createOauthUrlForCode($redirectUrl),這個里面的$url這個變量沒有進行url編碼,請自己加1下,否則你的url里有參數將不能正常被辨認,代碼很簡單:
$url = urlencode($redirectUrl); 這樣就行。
進行了以上的設置后如果還出現redirect_uri的毛病的話就要斟酌你的支付路徑權限的問題了,進入微信公眾號的后臺,請確保你的是服務號,并且已認證,查看方法是頁面右上角。在確認了以后 點左邊菜單的 “開發者中心”,然后如圖:

點擊修改,填入“授權回調頁面域名”,請確保這個域名和你的利用域名1致,這樣應當就解決了這個問題。
q2:沒法獲得prepay_id的問題
首選請確保你 WxPayPubHelper.php這個文件里 UnifiedOrder_pub 這個類的getPrepayId這個方法能正常使用。
此方法代碼以下:
/**
* 獲得prepay_id
*/
function getPrepayId()
{
$this->postXml();
$this->result = $this->xmlToArray($this->response);
$prepay_id = $this->result["prepay_id"];
return $prepay_id;
}
查看posXml這個方法后發現調用了自己的createXml這個方法
postXml方法以下:
/**
* 作用:post要求xml
*/
function postXml()
{
$xml = $this->createXml();
$this->response = $this->postXmlCurl($xml,$this->url,$this->curl_timeout);
return $this->response;
}
這時候需要確認你的$xml這個變量情勢以下:
<xml><openid><![CDATA[o-aubjtEkotIj_GNXXXXqV8_XXXXX]]></openid>
<body>201501201705551389</body>
<out_trade_no><![CDATA[wx7143c4a87a86c8ac142174XXX]]></out_trade_no>
<total_fee>1</total_fee>
<notify_url><![CDATA[http://demo.com/paydemo/demo/notify_url.php]]></notify_url>
<trade_type><![CDATA[JSAPI]]></trade_type>
<appid><![CDATA[wx7143c4axxxxxxxx]]></appid>
<mch_id>10020230</mch_id>
<spbill_create_ip><![CDATA[192.168.1.110]]></spbill_create_ip>
<nonce_str><![CDATA[imfgrg1g2odbl6mbiacmlkxxxxxxx]]></nonce_str>
<sign><![CDATA[CBE62F36806A3E1D98CB2311XXXXXX]]></sign></xml>
特別注意 openid的情勢1定要類似這樣的,全是數字或全是字母的1定是毛病
然后postXmlCurl才能正確提交,提交后就可以得到正確的prepay_id了
q3:在取到了prepay_id后,在進行付款的時候提示:公眾號支付使用了無效的商戶號
這個問題大部份是出現在2次簽名的時候,由于第2次簽名和第1次簽名不1致致使的
這時候我們需要看WxPayPubHelper.php這個文件里的JsApi_pub這個類,這個類中的getParameters這個方法是進行第2次簽名的關鍵,代碼以下:
/**
* 作用:設置jsapi的參數
*/
public function getParameters()
{
$jsApiObj["appId"] = WxPayConf_pub::APPID;
$timeStamp = time();
$jsApiObj["timeStamp"] = "$timeStamp";
$jsApiObj["nonceStr"] = $this->createNoncestr();
$jsApiObj["package"] = "prepay_id=$this->prepay_id";
$jsApiObj["signType"] = "MD5";
$jsApiObj["paySign"] = $this->getSign($jsApiObj);
$this->parameters = json_encode($jsApiObj);
return $this->parameters;
}
由于我需要根據數據表里的設置來動態的調用key,所以我的這個簽名要符合多個商家的,代碼改動以下:
/**
* 作用:設置jsapi的參數
*/
public function getParameters()
{
$jsApiObj["appId"] = $this->config['appid'];
$timeStamp = time();
$jsApiObj["timeStamp"] = "$timeStamp";
$jsApiObj["nonceStr"] = $this->createNoncestr();
$jsApiObj["package"] = "prepay_id=$this->prepay_id";
$jsApiObj["signType"] = "MD5";
$jsApiObj["paySign"] = $this->getSign($jsApiObj, $this->config['key']);
$this->parameters = json_encode($jsApiObj);
return $this->parameters;
}
getSign這個方法原型不帖了,改動后以下:
/**
* 作用:生成簽名
*/
public function getSign($Obj, $key ='')
{
foreach ($Obj as $k => $v)
{
$Parameters[$k] = $v;
}
//簽名步驟1:按字典序排序參數
ksort($Parameters);
$String = $this->formatBizQueryParaMap($Parameters, false);
//echo '【string1】'.$String.'</br>';
//簽名步驟2:在string后加入KEY
if ($key!='') {
$String = $String."&key=".$key;
}else{
$String = $String."&key=".WxPayConf_pub::KEY;
}
//echo "【string2】".$String."</br>";
//簽名步驟3:MD5加密
$String = md5($String);
//echo "【string3】 ".$String."</br>";
//簽名步驟4:所有字符轉為大寫
$result_ = strtoupper($String);
//echo "【result】 ".$result_."</br>";
return $result_;
}
可以看到,我只是多加了1個參數,加了1個判斷,由于我不想過量的破壞原來的代碼,所以這樣加了。
在這樣的改造完成后,我遇到的問題都解決了。希望對正在看的你能有所幫助,如果還有問題可以給我留言!
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈