【坑爹微信】微信支付相关问题解决
目錄
1. 那一抹淡淡的憂傷—–微信開發基礎
2. 用純js是不可能用純js了,這輩子都不用純js了 —– 微信JSSDK開發以及問題解答
3. 要你命3000 —— 微信支付開發系列問題解決
導語
為什么要開發微信和微信開發的優勢我就不用多說了吧。微信支付的方式分好幾種:
1.掃碼支付
2.公眾號支付
3.APP支付
不管是那種支付方式,都要用到統一下單這個接口,而一般大多數人都會卡在預支付id沒有拿到這一步,今天就主要分析預支付id的獲取和問題解決
開發前準備
- 一個開通了微信支付的公眾號
- 確保將安全授權目錄配置好了
- 支付回調地址配置好了
如果不知道怎么配置,請看這里
步驟一:發起支付準備
生成商戶訂單
先要根據自己的業務邏輯生成自己可讀的商戶訂單號,一般推薦年月日+隨機數+用戶uid
使用微信統一下單接口,獲得微信的預支付信息,對于統一下單接口的詳細信息可以看這里
第一步:
我們先實例化微信統一下單接口的類,這個類在微信支付V3demo里有,當然在這里我將微信demo類庫再次封裝加入命名空間更好的適應Thinkphp。
UnifiedOrder_pub類:
<?phpnamespace Org\Weixinpay; use Org\Weixinpay\Wxpay_client_pub; use Org\Weixinpay\WxPayConf_pub; use Org\Weixinpay\SDKRuntimeException; /*** 統一支付接口類*/class UnifiedOrder_pub extends Wxpay_client_pub{function __construct($appid,$mchid,$key,$appsecret){Common_util_pub::__construct($appid,$mchid,$key,$appsecret);//設置接口鏈接$this->url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//設置curl超時時間$this->curl_timeout = 60;}/*** 生成接口參數xml*/function createXml(){try{//檢測必填參數if($this->parameters["out_trade_no"] == null){throw new SDKRuntimeException("缺少統一支付接口必填參數out_trade_no!"."<br>");}elseif($this->parameters["body"] == null){throw new SDKRuntimeException("缺少統一支付接口必填參數body!"."<br>");}elseif ($this->parameters["total_fee"] == null ) {throw new SDKRuntimeException("缺少統一支付接口必填參數total_fee!"."<br>");}elseif ($this->parameters["notify_url"] == null) {throw new SDKRuntimeException("缺少統一支付接口必填參數notify_url!"."<br>");}elseif ($this->parameters["trade_type"] == null) {throw new SDKRuntimeException("缺少統一支付接口必填參數trade_type!"."<br>");}elseif ($this->parameters["trade_type"] == "JSAPI" &&$this->parameters["openid"] == NULL){throw new SDKRuntimeException("統一支付接口中,缺少必填參數openid!trade_type為JSAPI時,openid為必填參數!"."<br>");}$this->parameters["appid"] = $this->appid;//公眾賬號ID$this->parameters["mch_id"] = $this->mchid;//商戶號//$this->parameters["sub_mch_id"] = "1xxxxxxx2";//子商戶號 $this->parameters["spbill_create_ip"] = get_client_ip();//終端ip$this->parameters["nonce_str"] = $this->createNoncestr();//隨機字符串$this->parameters["sign"] = $this->getSign($this->parameters);//簽名return $this->arrayToXml($this->parameters);}catch (SDKRuntimeException $e){return array('return_code'=>'FAIL','return_msg'=>$e->errorMessage());}}/*** 獲取prepay_id*/function getPrepayId(){$this->postXml();$this->result = $this->xmlToArray($this->response);return $this->result;}}我們實例化UnifiedOrder_pub,并依此傳入參數,$appid,$mchid,$key,$appsecret
//appid 商家appid //mchid 商家商戶號 //key 商家支付秘鑰 //appsecret JSAPI獲準碼//調用統一下單$unifiedOrder = new UnifiedOrder_pub($this->config['pay_weixin_appid'],$this->config['pay_weixin_mchid'],$this->config['pay_weixin_key'],$this->config['pay_weixin_appsecret']);waring:在第一步里面會出的錯誤就是你的四個參數沒有按順序給對,記住這里面的參數一定要按順序給,并且你要檢查你的四個參數是否是有效的沒有過期
在第一步出錯的同學都不能吊起微信支付的樣式,即下圖:
但是如果你寫入了調試js的話可以看見具體錯誤,這里就不提調試js了。
第二步:向統一下單接口中添加所需參數
$unifiedOrder->setParameter("openid",$this->user_info['openid']);//用戶微信唯一標識$unifiedOrder->setParameter("body",$this->order_info['order_name']);//商品描述$unifiedOrder->setParameter("out_trade_no",$order_no);//商戶訂單號$unifiedOrder->setParameter("total_fee",floatval($pay_money*100));//總金額$unifiedOrder->setParameter("notify_url",$notice_url);//通知地址$unifiedOrder->setParameter("trade_type","JSAPI");//交易類型warning: 在第二步中,尤其要注意的就這個通知地址的格式,通知地址一定不能帶任何參數的地址,包括你是pathinfo模式也好,只能以www.xxxxx.com/index.php這種模式結尾。
www.xxx.com/index.php?a=index,www.xxx.com/index.php/admin/index 這樣的寫法全部是錯的。
第三步:獲取預支付信息
將上述內容提交給接口,正確可返回預支付ID
$prepay_result = $unifiedOrder->getPrepayId();如果錯誤,我們可以打印來查看是什么錯誤
var_dump($prepay_result); $prepay_result['return_code'] == 'FAIL'//標志支付失敗 $prepay_result['return_msg']//這個角標中有具體錯誤信息打印看看! //缺少統一支付接口必填參數out_trade_no! //缺少統一支付接口必填參數body //缺少統一支付接口必填參數total_fee! //缺少統一支付接口必填參數notify_url! //...等等一些的錯誤提示,大家可以打印出來看看,然后對照著修改當我們已經拿到預支付ID的時候,那么支付準備已經完成
調起JSAPI支付
第一步:在前臺文件中我們使用注冊支付JSAPI
//調起支付必備參數準備 function onBridgeReady(msg_json){WeixinJSBridge.invoke('getBrandWCPayRequest', {"appId":msg_json.appId, //公眾號名稱,由商戶傳入"timeStamp":msg_json.timeStamp, //時間戳,自1970年以來的秒數"nonceStr":msg_json.nonceStr, //隨機串"package":msg_json.package,"signType":msg_json.signType, //微信簽名方式:"paySign":msg_json.paySign //微信簽名},function(res){// 使用以上方式判斷前端返回,微信團隊鄭重提示:res.err_msg將在用戶支付成功后返回 ok,但并不保證它絕對可靠。if(res.err_msg == "get_brand_wcpay_request:ok" ) {check_pay_is_ture_ok(); //檢測微信支付狀態}else{}});}第二步:支付js準備綁定事件(這里就舉例按鈕)
$('#button_pay_now').on('click',function(){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(msg_json);}});到這里我們就可以看到調起微信支付的JS效果了
報錯信息分析
微信坑就在你很好的完成以上步驟也不能支付,總會報錯,在這里我就把我曾經遇到的錯誤寫下來,與大家一起探討
1.缺少統一支付接口必填參數total_fee!
這個錯造成的原因:
q:你沒有傳遞參數total_fee a:檢查是否傳遞參數,最好一步步打印到日志中查看
q:total_fee 參數格式錯誤 a:參數的單位是分,也就是一元錢的話就是100,所以建議最后處理的時候都要處理為分,建議最后用floatval處理下
2.缺少統一支付接口必填參數notify_url!
這個錯造成的原因:
q:你沒有傳遞參數notify_url a:檢查是否傳遞參數,最好一步步打印到日志中查看
q:notify_url 參數格式錯誤 a:通知地址一定不能帶任何參數的地址,包括你是pathinfo模式也好,只能以www.xxxxx.com/index.php這種模式結尾
3.簽名錯誤
這個錯造成的原因:
1.你的四個參數的錯誤,尤其注意key這個參數,如果你的key是大小寫混合的話,一定要在簽名前把其轉化為統一的大寫形式
2.簽名中的APPID 和appsecret
appid和商戶號
不匹配
3.過期的key,可以支付的公眾號可是要一年過期一次,相應的key每年都會有變化。
總結
以上是生活随笔為你收集整理的【坑爹微信】微信支付相关问题解决的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【坑爹微信】微信JSSDK图片上传问题和
- 下一篇: 【学无止境】关于通过PHP链接FTP或S