在微信的應(yīng)用上,微信支付是一個比較有用的部分,但也是比較復(fù)雜的技術(shù)要點(diǎn),在微商大行其道的年代,自己的商店沒有增加微信支付好像也說不過去,微信支付旨在為廣大微信用戶及商戶提供更優(yōu)質(zhì)的支付服務(wù),微信的支付和安全系統(tǒng)由騰訊財(cái)付通提供支持。本文主要介紹如何在微信公眾號上實(shí)現(xiàn)微信支付的接入、微信支付API的封裝,以及API的調(diào)用,實(shí)現(xiàn)我們一些常見的業(yè)務(wù)調(diào)用。
1、開通微信支付并配置
微信支付是需要微信公眾號的認(rèn)證基礎(chǔ),也就是只對認(rèn)證的公眾號開放,微信認(rèn)證需要簽署相關(guān)的資料,并且進(jìn)行對賬認(rèn)證,一般會有電話聯(lián)系確認(rèn)相關(guān)的信息的。
在微信支付API開始使用前,我們一般需要在后臺進(jìn)行一定的配置,如我們需要配置公眾號支付的授權(quán)目錄,測試白名單等信息,以及掃碼支持的回調(diào)處理地址(這個實(shí)現(xiàn)在后面再講),如下所示。
在使用API之前,我們要知道微信一些關(guān)鍵的操作,如退款、撤銷訂單等操作是需要證書的,而且常規(guī)的支付操作,我們也需要商戶號、商戶支付秘鑰等信息,這些證書和秘鑰信息,是我們從微信支付的商戶平臺上獲取的,我們微信支付開通并審核通過后,我們就可以登錄商戶平臺進(jìn)行相關(guān)的操作了。
首先我們需要在開發(fā)的電腦上安裝證書。
然后需要設(shè)置API的秘鑰
最后在【API安全】項(xiàng)目上下載證書供我們開發(fā)環(huán)境使用。
?
2、微信支付API的介紹
微信支付配置相關(guān)的參數(shù),并獲得證書、API秘鑰、商戶號等信息后,我們可以開始了解微信支付的API的具體使用了,我們需要先把API封裝為C#的類庫進(jìn)行使用,這樣才能在各種應(yīng)用里面方便調(diào)用。
微信支付分為有多種方式,如掃碼支付、公眾號支付、JSAPI支付、APP支付等方面,不過核心的API都差不多,基本上都覆蓋了下面截圖的幾個API,只是有部分的接口差異。
我們可以從其中掃碼支付開始了解,這個是對二維碼進(jìn)行掃碼支付的場景,分為了模式一和模式二兩種方式。
掃碼支付可分為兩種模式,商戶根據(jù)支付場景選擇相應(yīng)模式。
【模式一】:商戶后臺系統(tǒng)根據(jù)微信支付規(guī)則鏈接生成二維碼,鏈接中帶固定參數(shù)productid(可定義為產(chǎn)品標(biāo)識或訂單號)。用戶掃碼后,微信支付系統(tǒng)將productid和用戶唯一標(biāo)識(openid)回調(diào)商戶后臺系統(tǒng)(需要設(shè)置支付回調(diào)URL),商戶后臺系統(tǒng)根據(jù)productid生成支付交易,最后微信支付系統(tǒng)發(fā)起用戶支付流程。
【模式二】:商戶后臺系統(tǒng)調(diào)用微信支付【統(tǒng)一下單API】生成預(yù)付交易,將接口返回的鏈接生成二維碼,用戶掃碼后輸入密碼完成支付交易。注意:該模式的預(yù)付單有效期為2小時(shí),過期后無法支付。
根據(jù)掃碼支付的API說明,我們可以分別對這些接口(如統(tǒng)一下單、查詢訂單、關(guān)閉訂單、申請退款、查詢退款、下載對賬單等接口進(jìn)行逐一封裝,以方便我們的開發(fā)使用。
模式一和模式二,都需要使用到了統(tǒng)一下單的接口,然后生成相應(yīng)的二維碼給客戶掃碼支付使用。
那么我們先來看看統(tǒng)一下單的接口說明,以了解它的具體使用。
1)應(yīng)用場景
除被掃支付場景以外,商戶系統(tǒng)先調(diào)用該接口在微信支付服務(wù)后臺生成預(yù)支付交易單,返回正確的預(yù)支付交易回話標(biāo)識后再按掃碼、JSAPI、APP等不同場景生成交易串調(diào)起支付。
2)接口鏈接
URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder
3)是否需要證書
不需要
4)請求參數(shù)
請求參數(shù)看似很多,大概分為兩部分,一部分是系統(tǒng)必須的固定參數(shù),一部分是業(yè)務(wù)所需的參數(shù)。
系統(tǒng)必須的固定參數(shù)如下所示。
一部分是業(yè)務(wù)參數(shù),業(yè)務(wù)參數(shù)如下所示,主要是記錄訂單的相關(guān)產(chǎn)品ID、說明、費(fèi)用等等
微信支付接口的調(diào)用和公眾號其他接口調(diào)用不太一樣,這里全部是采用XML進(jìn)行交換的,感覺沒有JSON那么方便靈活,如下所示是統(tǒng)一下單的接口提交數(shù)據(jù)。
?
然后返回的數(shù)據(jù)也是XML的,如下面例子代碼所示,而且其中的字段內(nèi)容還不太確定,因此按官網(wǎng)的建議,使用字典集合來存儲返回的數(shù)據(jù)對象。
?
3、微信支付APIC#封裝和調(diào)用
根據(jù)上面的描述,我們大概了解了微信支付API 的大概說明,根據(jù)這些信息,我們可以對它進(jìn)行C#代碼的封裝了,對于代碼的封裝,我們關(guān)鍵點(diǎn)在其中第一個,如果順利封裝好第一個接口,那么后面的根據(jù)通用的方式,就很容易繼續(xù)處理這些接口了。
例如,我們可以定義好微信支付的API接口定義,如下所示。
///?<summary> ????///?微信支付接口 ????///?</summary> ????public?interface?ITenPayApi ????{?????? ????????///?<summary> ????????///?生成掃描支付模式一URL ????????///?</summary> ????????///?<param name="productId">商品ID</param> ????????///?<returns></returns> ????????string?GetPrePayUrl(string?productId); ????????///?<summary> ????????///?生成直接支付url,支付url有效期為2小時(shí),模式二 ????????///?</summary> ????????///?<param name="info">商品訂單數(shù)據(jù)</param> ????????///?<returns></returns> ????????string?GetPayUrl(WxPayOrderData?info); ????????///?<summary> ????????///?統(tǒng)一下單。(不需要證書,默認(rèn)不需要) ????????///?除被掃支付場景以外,商戶系統(tǒng)先調(diào)用該接口在微信支付服務(wù)后臺生成預(yù)支付交易單, ????????///?返回正確的預(yù)支付交易回話標(biāo)識后再按掃碼、JSAPI、APP等不同場景生成交易串調(diào)起支付。 ????????///?</summary> ????????///?<param name="info">商品訂單數(shù)據(jù)</param> ????????WxPayData?UnifiedOrder(WxPayOrderData?info); ????????.............
其中的接口方法的輸入?yún)?shù)我們定義一個實(shí)體類?WxPayOrderData?來存儲一些業(yè)務(wù)參數(shù),這些參數(shù)根據(jù)第二點(diǎn)的接口說明進(jìn)行定義,代碼如下所示
///?<summary> ????///?統(tǒng)一下單的商品訂單信息 ????///?</summary> ????public?class?WxPayOrderData ????{ ????????///?<summary> ????????///?商品ID,?trade_type=NATIVE,此參數(shù)必傳 ????????///?</summary> ????????public?string?product_id?{?get;?set;?} ????????///?<summary> ????????///?商品或支付單簡要描述 ????????///?</summary> ????????public?string?body?{?get;?set;?} ????????///?<summary> ????????///?訂單總金額,單位為分 ????????///?</summary> ????????public?int?total_fee?{?get;?set;?} ????????///?<summary> ????????///?商品標(biāo)記,代金券或立減優(yōu)惠功能的參數(shù),說明詳見代金券或立減優(yōu)惠 ????????///?</summary> ????????public?string?goods_tag?{?get;?set;?} ????????///?<summary> ????????///?交易類型,默認(rèn)為:NATIVE。 ????????///?JSAPI--公眾號支付、NATIVE--原生掃碼支付、APP--app支付 ????????///?</summary> ????????public?string?trade_type?{?get;?set;?} ????????///?<summary> ????????///?商品名稱明細(xì)列表 ????????///?</summary> ????????public?string?detail?{?get;?set;?} ????????///?<summary> ????????///?附加數(shù)據(jù) ????????///?在查詢API和支付通知中原樣返回,該字段主要用于商戶攜帶訂單的自定義數(shù)據(jù) ????????///?</summary> ????????public?string?attach?{?get;?set;?} ????????///?<summary> ????????///?用戶標(biāo)識 ????????///?trade_type=JSAPI,此參數(shù)必傳,用戶在商戶appid下的唯一標(biāo)識。 ????????///?</summary> ????????public?string?openid?{?get;?set;?} ????????public?WxPayOrderData() ????????{ ????????????this.trade_type?=?"NATIVE"; ????????} ????}
然后我們定義一個接口返回的類WxPayData,它用來存儲返回的對象信息的,這個類在官網(wǎng)例子里面有說明,其里面內(nèi)置一個排序過的字典對象進(jìn)行存儲數(shù)據(jù),部分代碼如下所示,我對它進(jìn)行了相關(guān)的修改,以方便在構(gòu)造函數(shù)里面初始化一些必備的參數(shù)(固定參數(shù))。
public?class?WxPayData ????{ ????????//采用排序的Dictionary的好處是方便對數(shù)據(jù)包進(jìn)行簽名,不用再簽名之前再做一次排序 ????????private?SortedDictionary<string, object>?m_values?=?new?SortedDictionary<string, object>(); ???????? ????????///?<summary> ????????///?默認(rèn)構(gòu)造函數(shù) ????????///?如果initDefault為true,則自動填入字段(appid,mch_id,time_stamp,nonce_str,out_trade_no,) ????????///?</summary> ????????public?WxPayData(bool?initDefault?=?false) ????????{ ????????????if(initDefault) ????????????{ ????????????????Init(); ????????????} ????????} ????????///?<summary> ????????///?對象初始化后,自動填入字段(appid,mch_id,time_stamp,nonce_str,out_trade_no,) ????????///?</summary> ????????public?void?Init() ????????{ ????????????//初始化幾個參數(shù) ????????????this.SetValue("appid",?WxPayConfig.APPID);//公眾帳號id ????????????this.SetValue("mch_id",?WxPayConfig.MCHID);//商戶號 ????????????this.SetValue("nonce_str",?GenerateNonceStr());//隨機(jī)字符串 ????????????this.SetValue("out_trade_no",?GenerateOutTradeNo(WxPayConfig.MCHID));//隨機(jī)字符串 ????????}
然后我們根據(jù)上面的數(shù)據(jù)定義,可以實(shí)現(xiàn)統(tǒng)一下單的函數(shù)內(nèi)容,主要是把輸入?yún)?shù)轉(zhuǎn)換為我們需要的字典參數(shù)集合,如下代碼所示。
///?<summary> ????????///?統(tǒng)一下單。(不需要證書,默認(rèn)不需要) ????????///?除被掃支付場景以外,商戶系統(tǒng)先調(diào)用該接口在微信支付服務(wù)后臺生成預(yù)支付交易單, ????????///?返回正確的預(yù)支付交易回話標(biāo)識后再按掃碼、JSAPI、APP等不同場景生成交易串調(diào)起支付。 ????????///?</summary> ????????///?<param name="info">商品訂單數(shù)據(jù)</param> ????????public?WxPayData?UnifiedOrder(WxPayOrderData?info) ????????{ ????????????WxPayData?data?=?new?WxPayData(true); ????????????data.SetValue("product_id",?info.product_id);//商品ID ????????????data.SetValue("openid",?info.openid);//商品ID ????????????//其他信息 ????????????data.SetValue("body",?info.body);//商品描述 ????????????data.SetValue("attach",?info.attach);//附加數(shù)據(jù) ????????????data.SetValue("total_fee",?info.total_fee);//總金額 ????????????data.SetValue("goods_tag",?info.goods_tag);//商品標(biāo)記 ????????????data.SetValue("trade_type",?info.trade_type);//交易類型 ????????????//默認(rèn)構(gòu)建 ????????????data.SetValue("time_start",?DateTime.Now.ToString("yyyyMMddHHmmss"));//交易起始時(shí)間 ????????????data.SetValue("time_expire",?DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));//交易結(jié)束時(shí)間 ??????????..............
最后的數(shù)據(jù)交換邏輯,我們通過對URL進(jìn)行POST提交XML數(shù)據(jù)給它獲取返回結(jié)果就可以了,如下所示。
????????????string?url?=?"https://api.mch.weixin.qq.com/pay/unifiedorder"; ????????????return?GetPostResult(data,?url);
其中上面的函數(shù)的代碼邏輯如下所示,主要是把返回的結(jié)果再還原為XML對象類WxPayData。
///?<summary> ????????///?通用的獲取結(jié)果函數(shù) ????????///?</summary> ????????private?WxPayData?GetPostResult(WxPayData?data,?string?url) ????????{ ????????????string?xml?=?data.ToXml(); ????????????string?response?=?helper.GetHtml(url,?xml,?true); ????????????WxPayData?result?=?new?WxPayData(); ????????????result.FromXml(response); ????????????return?result; ????????}
對于掃碼操作的模式二,直接生成一種二維碼,不需要后臺進(jìn)行回調(diào)的,那么它的實(shí)現(xiàn)邏輯只需要對上面代碼進(jìn)行封裝就可以了,如先構(gòu)建二維碼的函數(shù)代碼如下所示。
///?<summary> ????????///?生成直接支付url,支付url有效期為2小時(shí),模式二 ????????///?</summary> ????????///?<param name="info">商品訂單數(shù)據(jù)</param> ????????///?<returns></returns> ????????public?string?GetPayUrl(WxPayOrderData?info) ????????{ ????????????WxPayData?result?=?UnifiedOrder(info);//調(diào)用統(tǒng)一下單接口 ????????????return?result.GetString("code_url");//獲得統(tǒng)一下單接口返回的二維碼鏈接 ????????}
如在Winform界面里面,調(diào)用生成二維碼的代碼如下所示,主要邏輯就是構(gòu)建好二維碼,然后顯示在界面上。
private?void?btnGetPayUrl_Click(object?sender,?EventArgs?e) ????????{ ????????????//測試掃碼模式二的生成二維碼方式 ????????????WxPayOrderData?data?=?new?WxPayOrderData() ????????????{ ????????????????product_id?=?"123456789", ????????????????body?=?"測試支付-模式二", ????????????????attach?=?"愛奇迪技術(shù)支持", ????????????????detail?=?"測試掃碼支付-模式二", ????????????????total_fee?=?1, ????????????????goods_tag?=?"test1" ????????????}; ????????????var?url?=?api.GetPayUrl(data); ????????????var?image?=?api.GenerateQRImage(url); ????????????this.imgGetPayUrl.Image?=?image; ????????????this.imgGetPayUrl.SizeMode?=?PictureBoxSizeMode.StretchImage; ????????}
另外對于模式一,它在前端傳入一個簡單的產(chǎn)品ID,生成二維碼,當(dāng)用戶掃碼的時(shí)候,微信后臺會調(diào)用商戶平臺(我們服務(wù)器)的回調(diào)處理方法,這個回調(diào)方法會調(diào)用統(tǒng)一下單的API進(jìn)行生成支付交易,過程有點(diǎn)復(fù)雜,我們來看看,我們的實(shí)現(xiàn)代碼如下所示。
///?<summary> ????????///?生成掃描支付模式一URL ????????///?</summary> ????????///?<param name="productId">商品ID</param> ????????///?<returns></returns> ????????public?string?GetPrePayUrl(string?productId) ????????{ ????????????WxPayData?data?=?new?WxPayData(true); ????????????data.SetValue("product_id",?productId);//商品ID????? ????????????data.SetValue("time_stamp",?data.GenerateTimeStamp());//隨機(jī)字符串????????? ????????????data.SetValue("sign",?data.MakeSign());//簽名 ????????????string?str?=?data.ToUrlParams();//轉(zhuǎn)換為URL串 ????????????string?url?=?"weixin://wxpay/bizpayurl?"?+?str; ????????????return?url; ????????}
它的調(diào)用代碼生成二維碼操作如下所示。
private?void?btnGetPrePayUrl_Click(object?sender,?EventArgs?e) ????????{ ????????????var?productId?=?"12345678"; ????????????var?url?=?api.GetPrePayUrl(productId); ????????????var?image?=?api.GenerateQRImage(url); ????????????this.imgGetPrePayUrl.Image?=?image; ????????????this.imgGetPayUrl.SizeMode?=?PictureBoxSizeMode.StretchImage; ????????}
我們在第一小節(jié)里面介紹了,需要在微信后臺配置掃碼的回調(diào)函數(shù),如下所示。
這樣我們還需要添加一個頁面aspx、或者一般處理程序ashx的方式來實(shí)現(xiàn)掃碼的回調(diào)過程。具體的邏輯也就是在這個頁面里面獲取到提交過來的參數(shù),然后調(diào)用統(tǒng)一下單處理后,進(jìn)行數(shù)據(jù)返回即可,代碼邏輯如下所示。
?
4、在頁面上進(jìn)行掃碼處理
前面的例子,我介紹了Winfrom的掃碼例子,很多時(shí)候,我們的應(yīng)用可能是基于Web的,那么它的實(shí)現(xiàn)是如何的呢,下面我繼續(xù)介紹一下。
首先我們在自己的業(yè)務(wù)Web后臺系統(tǒng)里面,添加兩個頁面,主要是用來生成二維碼在頁面上進(jìn)行展示的,如下所示。
最終我們在NativePayPage.aspx頁面上展示我們的二維碼,方便用戶進(jìn)行掃碼支付處理,頁面的代碼很簡單,我們只需要在前端頁面放置兩個圖片控件,圖片內(nèi)容通過MakeQRCode.aspx頁面進(jìn)行生成就可以了。
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> ????<meta http-equiv="content-type" content="text/html;image/gif;charset=utf-8"/> ????<meta name="viewport" content="width=device-width, initial-scale=1" />? ????<title>微信支付樣例-掃碼支付</title> </head> <body> ????<div style="margin-left: 10px;color:#00CD00;font-size:30px;font-weight: bolder;">掃碼支付模式一</div><br/> ????<asp:Image ID="Image1" runat="server" style="width:200px;height:200px;"/> ????<br/><br/><br/> ????<div style="margin-left: 10px;color:#00CD00;font-size:30px;font-weight: bolder;">掃碼支付模式二</div><br/> ????<asp:Image ID="Image2" runat="server" style="width:200px;height:200px;"/> ???? </body> </html>
頁面后臺的代碼就是綁定二維碼的過程,代碼如下所示,和Winform的代碼類似操作。
protected?void?Page_Load(object?sender,?EventArgs?e) ????????{ ????????????TenPayApi?api?=?new?TenPayApi(); ????????????var?productId?=?"123456789"; ????????????//生成掃碼支付模式一url ????????????string?url1?=?api.GetPrePayUrl(productId); ????????????//生成掃碼支付模式二url ????????????WxPayOrderData?info?=?new?WxPayOrderData() ????????????{ ????????????????product_id?=?"123456789", ????????????????body?=?"測試支付-模式二", ????????????????attach?=?"愛奇迪技術(shù)支持", ????????????????detail?=?"測試掃碼支付-模式二", ????????????????total_fee?=?1, ????????????????goods_tag?=?"test1" ????????????}; ????????????string?url2?=?api.GetPayUrl(info); ????????????//將url生成二維碼圖片 ????????????Image1.ImageUrl?=?"MakeQRCode.aspx?data="?+?HttpUtility.UrlEncode(url1); ????????????Image2.ImageUrl?=?"MakeQRCode.aspx?data="?+?HttpUtility.UrlEncode(url2); ????????}
實(shí)現(xiàn)后的頁面效果如下所示。
實(shí)現(xiàn)并預(yù)覽效果,確定是我們所需的頁面后,我們可以發(fā)布在公眾號的菜單連接上進(jìn)行測試使用了。
打開微信公眾號-廣州愛奇迪,我們可以看到對應(yīng)的菜單發(fā)生改變,并且看到進(jìn)入微信支付的菜單可以進(jìn)行支付了。
??
??
?
以上就是微信支付的掃碼過程的一個實(shí)現(xiàn),微信支付還包括很多其他API接口,后面有機(jī)會可以繼續(xù)進(jìn)行介紹。微信支付的接口實(shí)現(xiàn)雖然相對其他微信接口比較復(fù)雜一些,但是我們一旦完成幾個案例,后面的就相對比較容易的了,因?yàn)樗恼{(diào)用方式基本上比較一致,很類似。
?更多C#開發(fā)微信門戶及應(yīng)用微信支付接入和API封裝使用相關(guān)文章請關(guān)注PHP中文網(wǎng)!

熱AI工具

Undress AI Tool
免費(fèi)脫衣服圖片

Undresser.AI Undress
人工智能驅(qū)動的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover
用于從照片中去除衣服的在線人工智能工具。

Clothoff.io
AI脫衣機(jī)

Video Face Swap
使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費(fèi)的代碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
功能強(qiáng)大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6
視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版
神級代碼編輯軟件(SublimeText3)