說說微信支付遇到的坑

最近公司上的app需要增加一個(gè)微信支付的功能。初看微信支付API開發(fā)文檔還是很簡(jiǎn)單的,但是在簡(jiǎn)單的背后卻隱藏這幾個(gè)不小的坑。

公司要接入的是APP支付(微信支付有如下幾種[圖1]),所以這里只談APP支付遇到的坑,其它支付估計(jì)也有類似的坑吧。

圖1

微信給出的業(yè)務(wù)流程

APP支付業(yè)務(wù)流程

商戶系統(tǒng)和微信支付系統(tǒng)主要交互說明:
步驟1:用戶在商戶APP中選擇商品,提交訂單,選擇微信支付。
步驟2:商戶后臺(tái)收到用戶支付單,調(diào)用微信支付統(tǒng)一下單接口。參見【統(tǒng)一下單API】。
步驟3:統(tǒng)一下單接口返回正常的prepay_id,再按簽名規(guī)范重新生成簽名后,將數(shù)據(jù)傳輸給APP。參與簽名的字段名為appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式為Sign=WXPay
步驟4:商戶APP調(diào)起微信支付。api參見本章節(jié)【app端開發(fā)步驟說明
步驟5:商戶后臺(tái)接收支付通知。api參見【支付結(jié)果通知API
步驟6:商戶后臺(tái)查詢支付結(jié)果。,api參見【查詢訂單API


1、統(tǒng)一下單API遇到的坑
商戶后臺(tái)系統(tǒng)需要把一些關(guān)于支付的信息post到微信的統(tǒng)一下單接口,post信息是xml格式的,如下圖2;一開始我直接通過拼接字符串的方式寫的,結(jié)果就各種不成功,由于提交的xml里面有中文,所以需要在xml里指定utf-8的編碼,如此就可以提交成功得到prepay_id了。

圖2

2、APP支付業(yè)務(wù)流程步驟3:統(tǒng)一下單接口返回正常的prepay_id,再按簽名規(guī)范重新生成簽名后,將數(shù)據(jù)傳輸給APP。參與簽名的字段名為appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式為Sign=WXPay遇到的坑。

由于需要簽名,然后我就根據(jù)微信支付簽名算法把步驟3中提到的字段加上key值進(jìn)行簽名了,結(jié)果android和ios端用接口返回的prepayId和簽名掉起微信時(shí)總是報(bào)參數(shù)錯(cuò)誤,以為是簽名簽的不對(duì),最后發(fā)現(xiàn)簽名的這些字段名必須全部小些才可以。


附C#部分關(guān)鍵代碼
1、簽名算法

string strA="appid=wx111111111111&body=xxx付費(fèi)&mch_id=141111111&nonce_str=37A749D808E46495A8DA1E5352D03CAE&notify_url=https://weixinpay.com/notify.ashx&out_trade_no=20170315113530201659&spbill_create_ip=127.0.0.1&total_fee=1&trade_type=APP&key=imkey121";
string sign=System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(strA, "MD5").ToUpper();

2、制作需要post到微信接口的xml數(shù)據(jù)

            XmlDataDocument doc = new XmlDataDocument();
            XmlNode node = doc.CreateXmlDeclaration("1.0", "utf-8", "");
            doc.AppendChild(node);

            XmlNode root = doc.CreateElement("xml");
            doc.AppendChild(root);
            CreateNode(doc, root, "appid", appid);
            CreateNode(doc, root, "mch_id", mch_id);
            CreateNode(doc, root, "nonce_str", nonce_str);
            CreateNode(doc, root, "sign", sign);
            CreateNode(doc, root, "body", body);
            CreateNode(doc, root, "out_trade_no", out_trade_no);
            CreateNode(doc, root, "total_fee", total_fee);
            CreateNode(doc, root, "spbill_create_ip", spbill_create_ip);
            CreateNode(doc, root, "notify_url", notify_url);
            CreateNode(doc, root, "trade_type", trade_type);

        //CreateNode方法
        private void CreateNode(XmlDocument xmlDoc, XmlNode parentNode, string name, string value)
        {
            XmlNode node = xmlDoc.CreateNode(XmlNodeType.Element, name, null);
            node.InnerText = value;
            parentNode.AppendChild(node);
        }

3、post方法調(diào)用微信接口

                //menuInfo=需要post的xml參數(shù)
                //postUrl 微信接口地址
                //returnValue  通過微信接口獲取的返回值xml格式
                byte[] byteData = Encoding.UTF8.GetBytes(menuInfo);
                Uri uri = new Uri(postUrl);
                HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(uri);
                webReq.Method = "POST";
                webReq.ContentType = "application/x-www-form-urlencoded";
                webReq.ContentLength = byteData.Length;
                //定義Stream信息
                Stream stream = webReq.GetRequestStream();
                stream.Write(byteData, 0, byteData.Length);
                stream.Close();
                //獲取返回信息
                HttpWebResponse response = (HttpWebResponse)webReq.GetResponse();
                StreamReader streamReader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                returnValue = streamReader.ReadToEnd();
                //關(guān)閉信息
                streamReader.Close();
                response.Close();
                stream.Close();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容