搜尋
首頁微信小程式微信開發微信公眾號支付開發全過程

微信公眾號支付開發全過程

Feb 24, 2017 pm 04:38 PM
微信公眾號

業務流程

這個微信官網說的還是很詳細的,還配了圖。我還要再說一次。

用戶點擊一個支付按鈕-->{後台一大推處理}-->用戶看到了一個輸入密碼的介面,包含金額等一些資訊-->用戶輸入密碼後出來一個支付成功的頁面(這部分流程都是微信自己完成的,我們什麼都不用做)-->返回系統自己的頁面(總不能讓用戶一直看著一個支付完成的頁面吧。花了錢,正心疼的,趕緊跳轉~一會兒後悔了,申請退款怎麼整。做不做沒有啥關係,反正我還沒做呢)

2)調用統一下單接口獲取預付id

#3)H5調起微信支付的內建JS

4)支付完成後,微信回呼URL的處理

 

#看著大段的文字,是不是很不爽。忘記了在哪裡看到的一句話。 One picture instead  thousands of words. (圖中紅色部分是我們需要做的。好像也沒有多少

本文最主要的部分開始了(想直接看程式碼,貼上程式碼,你也不一定能看懂,不是說程式碼難,各種分離,各種類,不直接。 key0 還是得回來乖乖的對參數。笑話。的詳細說明。 ##appid ==應用ID==登陸微信公眾號後台-開發-基本配置

微信公眾號支付開發全過程mch_id == 微信支付商家號碼==登陸微信支付後台,即可看到

#device_info ==設備號碼==終端設備號碼(門市號碼或收銀設備ID),注意:PC網頁或公眾號碼內支付請傳"WEB"

body==商品描述==商品或支付單簡要描述(不知道是什麼鬼,沒關係,先隨便傳個字符串,隨便的傳個英文的字符串。你會為你這個時候的英明決定打個滿分。如果是中文,可能會遇到毫無頭緒的簽章錯誤,嚴重者開始懷疑人生)

trade_type==交易類型==取值如下:JSAPI,NATIVE,APP。

      ps:JSAPI--公眾號支付、NATIVE--原生掃碼支付、APP--app支付,統一下單接口trade_type的傳參可參考這裡。單獨的支付接口,不呼叫統一下單接口

nonce_str==隨機字串==隨機字串,不長於32位

       ps:小夥伴們可能會對nonce這個命名,很詔異,微信team的人,都是逗必嗎~。在我不懈的努力下,

      發現了這個。 nonce ==number used once.恍然大悟的趕腳。

 

notify_url==通知位址==接收微信支付非同步通知回呼位址,通知url必須為直接可存取的url,不能攜帶參數。 (這,取個什麼名字好呢。隨便起吧,反正一時半會也用不到)

out_trade_no==商家訂單號==商家系統內部的訂單號碼,32個字元內、可包含字母(每次看完微信的官方解釋就更迷茫了,有木有。沒關係,我就傳個1咋了。)

total_fee==總金額==訂單總金額,單位為分(為了公司的專案測試,還得自己掏銀子,1分錢也是錢啊。ps:這時候總會想起,一個同學說過,蒼蠅腿也是肉啊)

openid ==使用者識別==trade_type=JSAPI,此參數必傳,使用者在商家appid下的唯一識別。

還有最重要的一個,重要的角色總是會在最後登場。

sign==簽名==官方給的簽章演算法。 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3。沒看懂,看不太懂,你覺得你看懂了,沒關係,不遇到幾次簽名錯誤,好意思說自己做過微信支付開發嗎。

說這個sign還有一個更重要的參數。參與簽名的參數。反正我找了好久才找到。 (公司營運申請的微信支付,當我找她要的時候,他的表情是這樣子的。


key==key設定路徑:微信商家平台(pay.weixin.qq.com)- ->帳戶設定-->API安全-->金鑰設定

在這裡:微信公眾號支付開發全過程

網路上有說怎麼找得。我也懶得去找。直接自己想了一個字串,然後用MD5加密成32位元的字串,重新設定的。

產生sign簽章的時候,要用到這個key值,所以,要保存好。

我看別人生成簽名(sign)用了很多,反正我就用了上面給出的那些參數生成的sign.(這個上面指的是我的博客上面,不是微信上面。為了減少誤解,貼出我產生sign簽章的參數)

我產生sign簽章的參數

微信公眾號支付開發全過程

##準備好以上參數之後,封裝成XML

格式如下:

<?xml  version="1.0" encoding="UTF-8" standalone="yes"?><xml>
    <appid>wxb1427ebebexxxxxx</appid>
    XXX费用
    <device_info>WEB</device_info>
    <mch_id>132186xxxx</mch_id>
    <nonce_str>6AED000AF86A084F9CB0264161E29DD3</nonce_str>
    <notify_url>https://一个域名/api/wechatPay/jsapiPayNotify</notify_url>
    <openid>oo8WUt0taCqjt552htW1vw-xxxxx</openid>
    <out_trade_no>1</out_trade_no>
    <sign>各种排序+key生成的那个sign</sign>
    <total_fee>1</total_fee>
    <trade_type>JSAPI</trade_type></xml>
呼叫微信的統一下單一位址:https://api.mch.weixin.qq.com/pay/unifiedorder

#見證奇蹟的時刻。如果以上參數都神奇的對了,那麼會收到微信回傳的XML字串,格式如下

<xml>
  <return_code></return_code>
  <return_msg></return_msg>
  <appid></appid>
  <mch_id></mch_id>
  <device_info></device_info>
  <nonce_str></nonce_str>
  <sign></sign>
  <result_code></result_code>
  <prepay_id></prepay_id>
  <trade_type></trade_type></xml>


我們需要的,就是這貨

prepay_id

获取到这货之后,第一步骤已经结束了,可以去喝个茶,吃个冰棍,小庆祝一下。

2、H5调起微信支付的内置JS
 後台傳回前台的參數中,應包含以下幾項:

appId==這個是不變的==永遠不變

timeStamp==時間戳==規則: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_2。看完仍是一臉迷茫的,沒關係,我們有工具類。誰知道呢,直接呼叫就好了 

nonceStr ==反正我用的跟剛才簽章是同一個隨機字串。理論上不用應該也沒有關係的,勤快的小夥伴可以試試

package==訂單詳情擴展字符串==統一下單接口返回的prepay_id參數值,提交格式如:prepay_id=** *(你猜對了。剛才我們費那麼大力氣,得到到的prepay_id就是在這裡用的。第一次使用的時候,一直拿訂單ID去請求,然後微信給我的信息就是請求參數錯誤,缺少參數$key0$.不要告訴我,只有我一個人。重新生成,在後台。使用如上4個參數+一個key(永遠不變)。 (我產生簽章的時間戳記和傳回給前台的時間戳記是timeStamp是同一個。不一樣行不行,木有驗證)

產生paySign的程式碼

##NB:產生prepay_id時appid是小寫的i,產生paySign時,appId是大寫的I

到此為止如果一切順利,你會看到這樣子的一個頁面。

微信公眾號支付開發全過程但是如果,你沒有看到這個。而是提示,目錄未授權,或測試帳號未在白名單中,我覺得,這才是這篇部落格的正確開啟方式呢。

微信公眾號後台,微信支付,開發配置中有一個支付授權目錄,測試授權目錄,

 支付授權目錄:開發時,先放一放。 (鄧小平爺爺在對待中日關係時曾經說過,我們解決不了的問題,先放一放。)

測試授權目錄:我們要填寫的就是這個了。要一個外網能存取到的位址。 ip也可以(親測可以的)。如果你的ip,外網不能訪問,找維運同學解決。建議,配置一個測試用的外網可存取的網域名稱。

測試白名單:這個不解釋

輸入密碼,然後,就會看到這樣子的結果。 (這也不需要我們做什麼了)

微信公眾號支付開發全過程

 

#好激動啊,趕快去吃點東西,抑制一下,內心的激動。

微信公眾號支付開發全過程剩下的,我們還有兩件事情要做。先說簡單的。

3、支付成功之後跳轉回自己的系統的某個頁面

function onBridgeReady(){
   WeixinJSBridge.invoke
   (       'getBrandWCPayRequest', 
   {           "appId" : appId,       
   //公众号名称,由商户传入
           "timeStamp":timeStamp, //时间戳,自1970年以来的秒数     
           "nonceStr" : nonceStr, //随机串     
           "package" : Package,     
           "signType" :signType,  //微信签名方式:     
           "paySign" : paySign     //微信签名 
       },       function(res){ 
           if(res.err_msg == "get_brand_wcpay_request:ok" ) {
               window.location.replace("index.html");
           }
       }
   ); 
}

上述程式碼中的,紅色部分,修改成你想去的頁面即可。是不是好奇replace是什麼鬼。移步這裡,看一下:http://www.php.cn/

4,最後一部分啦。 fighting

此部分有以下3小步驟

    1)解析傳過來的流信息,透過重新簽章的方式驗證流中所包含的資訊的正確性。就是判斷這個訊息到底是不是微信發的

    2)return_code和result_code都是SUCCESS的話,處理商家自己的業務邏輯。就是訂單的支付狀態啊等一些資訊。

    3)告诉微信,我收到你的返回值了。不用在发了。

关于以上三点的解释。微信官方是这么说的


//支付完成后,微信会把相关支付和用户信息发送到商户设定的通知URL,
//验证签名,并回应微信。
//对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败,
//微信会通过一定的策略(如30分钟共8次)定期重新发起通知,
//尽可能提高通知的成功率,但微信不保证通知最终能成功。

//商户自行增加处理流程,
//例如:更新订单状态
//例如:数据库操作
//例如:推送支付完成信息


还记得我们在第一步生成预支付id(prepay_id时的那个notify_url吗。如果不记得了,请往上翻。如果当时只是随便写了一个,那么这会需要去改一改了。)

一个能访问的到的action.同样地址需要外网能访问的到。没有试ip好不好使。开发这部分功能的时候,运维同学已经配置了测试域名。好开心啊,终于不用在纠结于一些交互配置了。

和支付宝不同,微信返回的是流。和支付宝不同,微信返回的是流。和支付宝不同,微信返回的是流。重要的事情说三遍

解析之后,得到的格式是这样子的

<xml><appid><![CDATA[wxb1427ebebeeaxxxx]]></appid>
<bank_type><![CDATA[CFT]]></bank_type>
<cash_fee><![CDATA[1]]></cash_fee>
<device_info><![CDATA[WEB]]></device_info>
<fee_type><![CDATA[CNY]]></fee_type>
<is_subscribe><![CDATA[Y]]></is_subscribe>
<mch_id><![CDATA[132186xxxx]]></mch_id>
<nonce_str><![CDATA[07FC15C9D169EE48573EDD749D25945D]]></nonce_str>
<openid><![CDATA[oo8WUt0taCqjt552htW1vw-xxxxx]]></openid>
<out_trade_no><![CDATA[你的订单编号]]></out_trade_no>
<result_code><![CDATA[SUCCESS]]></result_code>
<return_code><![CDATA[SUCCESS]]></return_code>
<sign><![CDATA[E69940B3EDC437CB5A181210D523806E]]></sign>
<time_end><![CDATA[20160621134204]]></time_end>
<total_fee>1</total_fee>
<trade_type><![CDATA[JSAPI]]></trade_type>
<transaction_id><![CDATA[400386200120160621763973xxxx]]></transaction_id>
</xml>

对以上第一点和第三点做个解释。

再次吐槽一下。微信真的很喜欢用签名啊。整个过程,3遍签名。也是醉了。

1)我们看到上述微信返回的xml中含有很多字段。使用上述xml中,处sign意外的值+key,进行签名。你没有看错。包含result_code和return_code。

微信的官方对于签名有解释。

微信公眾號支付開發全過程

原谅我真的好久不学语文了。真的没理解这句话,是用微信回调函数中传的参数,进行重新签名。傻傻的,还在想,用第二次签名是的参数进行签名,时间戳怎么办,要不要存在数据库里面。

将获得的签名与xml中的sign对比,如果相同,证明是微信返回的通知。如果不同,你的通知地址可能被黑客破解了。要不要告诉老板呢,告诉老板了,我怎么解决呢。

 

2)商户逻辑处理,不解释

3)告诉微信,我收到了你的通知,不需要在发送了。

怎么告诉微信呢。我翻遍了微信的文档,也没有找到回复微信通知这个url。

经人知道,再一次的刷新了认知观。用response.

我是这么写的


 response.getWriter().write(xml);


这个xml就是微信给你的那个流转化的字符串。

xml中的return_code要是SUCCESS或者FAIL

别问我怎么知道的。官方的demo里面写的

if($notify->checkSign() == FALSE){
        $notify->setReturnParameter("return_code","FAIL");//返回状态码
        $notify->setReturnParameter("return_msg","签名失败");//返回信息
    }else{
        $notify->setReturnParameter("return_code","SUCCESS");//设置返回码
    }
    $returnXml = $notify->returnXml();

按照这个写法,返回的数据。在没有收到微信的通知。

之前在测试的时候,返回字符串之后,在没有收到微信的通知,这两天偶然查日志,发现,微信在一直的,通知,不一定是8次。从打印的日志看

有4次,6次。突然,好晕啊。有明白的朋友,还请多多指教

--------------------------------------------------------------

微信公众号支付--JSAPI的开发思路和一下参数的具体解释,全部完成了。具体代码。等我从公司项目里面抽出来。在整理。

还有一个坑:我们在第一步的时候,body传的是英文,如果传中文,直接能用的赶紧感谢一下上苍,返回参数错误的,应该是正常吧。

我的对象和xml转化是用的Java的JAXBContext。很好用的赶脚。赶脚比XMLStream好用。

更多微信公眾號支付開發全過程相关文章请关注PHP中文网!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。