C#开发微信门户及应用(32)--微信支付接入和API封装使用
C#開發微信門戶及應用(32)--微信支付接入和API封裝使用
在微信的應用上,微信支付是一個比較有用的部分,但也是比較復雜的技術要點,在微商大行其道的年代,自己的商店沒有增加微信支付好像也說不過去,微信支付旨在為廣大微信用戶及商戶提供更優質的支付服務,微信的支付和安全系統由騰訊財付通提供支持。本文主要介紹如何在微信公眾號上實現微信支付的接入、微信支付API的封裝,以及API的調用,實現我們一些常見的業務調用。
1、開通微信支付并配置
微信支付是需要微信公眾號的認證基礎,也就是只對認證的公眾號開放,微信認證需要簽署相關的資料,并且進行對賬認證,一般會有電話聯系確認相關的信息的。
在微信支付API開始使用前,我們一般需要在后臺進行一定的配置,如我們需要配置公眾號支付的授權目錄,測試白名單等信息,以及掃碼支持的回調處理地址(這個實現在后面再講),如下所示。
在使用API之前,我們要知道微信一些關鍵的操作,如退款、撤銷訂單等操作是需要證書的,而且常規的支付操作,我們也需要商戶號、商戶支付秘鑰等信息,這些證書和秘鑰信息,是我們從微信支付的商戶平臺上獲取的,我們微信支付開通并審核通過后,我們就可以登錄商戶平臺進行相關的操作了。
首先我們需要在開發的電腦上安裝證書。
然后需要設置API的秘鑰
最后在【API安全】項目上下載證書供我們開發環境使用。
?
2、微信支付API的介紹
微信支付配置相關的參數,并獲得證書、API秘鑰、商戶號等信息后,我們可以開始了解微信支付的API的具體使用了,我們需要先把API封裝為C#的類庫進行使用,這樣才能在各種應用里面方便調用。
微信支付分為有多種方式,如掃碼支付、公眾號支付、JSAPI支付、APP支付等方面,不過核心的API都差不多,基本上都覆蓋了下面截圖的幾個API,只是有部分的接口差異。
我們可以從其中掃碼支付開始了解,這個是對二維碼進行掃碼支付的場景,分為了模式一和模式二兩種方式。
掃碼支付可分為兩種模式,商戶根據支付場景選擇相應模式。
【模式一】:商戶后臺系統根據微信支付規則鏈接生成二維碼,鏈接中帶固定參數productid(可定義為產品標識或訂單號)。用戶掃碼后,微信支付系統將productid和用戶唯一標識(openid)回調商戶后臺系統(需要設置支付回調URL),商戶后臺系統根據productid生成支付交易,最后微信支付系統發起用戶支付流程。
【模式二】:商戶后臺系統調用微信支付【統一下單API】生成預付交易,將接口返回的鏈接生成二維碼,用戶掃碼后輸入密碼完成支付交易。注意:該模式的預付單有效期為2小時,過期后無法支付。
根據掃碼支付的API說明,我們可以分別對這些接口(如統一下單、查詢訂單、關閉訂單、申請退款、查詢退款、下載對賬單等接口進行逐一封裝,以方便我們的開發使用。
模式一和模式二,都需要使用到了統一下單的接口,然后生成相應的二維碼給客戶掃碼支付使用。
那么我們先來看看統一下單的接口說明,以了解它的具體使用。
1)應用場景
除被掃支付場景以外,商戶系統先調用該接口在微信支付服務后臺生成預支付交易單,返回正確的預支付交易回話標識后再按掃碼、JSAPI、APP等不同場景生成交易串調起支付。
2)接口鏈接
URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder
3)是否需要證書
不需要
4)請求參數
請求參數看似很多,大概分為兩部分,一部分是系統必須的固定參數,一部分是業務所需的參數。
系統必須的固定參數如下所示。
一部分是業務參數,業務參數如下所示,主要是記錄訂單的相關產品ID、說明、費用等等
微信支付接口的調用和公眾號其他接口調用不太一樣,這里全部是采用XML進行交換的,感覺沒有JSON那么方便靈活,如下所示是統一下單的接口提交數據。
?
然后返回的數據也是XML的,如下面例子代碼所示,而且其中的字段內容還不太確定,因此按官網的建議,使用字典集合來存儲返回的數據對象。
?
3、微信支付APIC#封裝和調用
根據上面的描述,我們大概了解了微信支付API 的大概說明,根據這些信息,我們可以對它進行C#代碼的封裝了,對于代碼的封裝,我們關鍵點在其中第一個,如果順利封裝好第一個接口,那么后面的根據通用的方式,就很容易繼續處理這些接口了。
例如,我們可以定義好微信支付的API接口定義,如下所示。
/// <summary>/// 微信支付接口/// </summary>public interface ITenPayApi{ /// <summary>/// 生成掃描支付模式一URL/// </summary>/// <param name="productId">商品ID</param>/// <returns></returns>string GetPrePayUrl(string productId);/// <summary>/// 生成直接支付url,支付url有效期為2小時,模式二/// </summary>/// <param name="info">商品訂單數據</param>/// <returns></returns>string GetPayUrl(WxPayOrderData info);/// <summary>/// 統一下單。(不需要證書,默認不需要)/// 除被掃支付場景以外,商戶系統先調用該接口在微信支付服務后臺生成預支付交易單,/// 返回正確的預支付交易回話標識后再按掃碼、JSAPI、APP等不同場景生成交易串調起支付。/// </summary>/// <param name="info">商品訂單數據</param>WxPayData UnifiedOrder(WxPayOrderData info);.............其中的接口方法的輸入參數我們定義一個實體類?WxPayOrderData?來存儲一些業務參數,這些參數根據第二點的接口說明進行定義,代碼如下所示
/// <summary>/// 統一下單的商品訂單信息/// </summary>public class WxPayOrderData{/// <summary>/// 商品ID, trade_type=NATIVE,此參數必傳/// </summary>public string product_id { get; set; }/// <summary>/// 商品或支付單簡要描述/// </summary>public string body { get; set; }/// <summary>/// 訂單總金額,單位為分/// </summary>public int total_fee { get; set; }/// <summary>/// 商品標記,代金券或立減優惠功能的參數,說明詳見代金券或立減優惠/// </summary>public string goods_tag { get; set; }/// <summary>/// 交易類型,默認為:NATIVE。/// JSAPI--公眾號支付、NATIVE--原生掃碼支付、APP--app支付/// </summary>public string trade_type { get; set; }/// <summary>/// 商品名稱明細列表/// </summary>public string detail { get; set; }/// <summary>/// 附加數據/// 在查詢API和支付通知中原樣返回,該字段主要用于商戶攜帶訂單的自定義數據/// </summary>public string attach { get; set; }/// <summary>/// 用戶標識/// trade_type=JSAPI,此參數必傳,用戶在商戶appid下的唯一標識。/// </summary>public string openid { get; set; }public WxPayOrderData(){this.trade_type = "NATIVE";}}然后我們定義一個接口返回的類WxPayData,它用來存儲返回的對象信息的,這個類在官網例子里面有說明,其里面內置一個排序過的字典對象進行存儲數據,部分代碼如下所示,我對它進行了相關的修改,以方便在構造函數里面初始化一些必備的參數(固定參數)。
public class WxPayData{//采用排序的Dictionary的好處是方便對數據包進行簽名,不用再簽名之前再做一次排序private SortedDictionary<string, object> m_values = new SortedDictionary<string, object>();/// <summary>/// 默認構造函數/// 如果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(){//初始化幾個參數this.SetValue("appid", WxPayConfig.APPID);//公眾帳號idthis.SetValue("mch_id", WxPayConfig.MCHID);//商戶號this.SetValue("nonce_str", GenerateNonceStr());//隨機字符串this.SetValue("out_trade_no", GenerateOutTradeNo(WxPayConfig.MCHID));//隨機字符串}然后我們根據上面的數據定義,可以實現統一下單的函數內容,主要是把輸入參數轉換為我們需要的字典參數集合,如下代碼所示。
/// <summary>/// 統一下單。(不需要證書,默認不需要)/// 除被掃支付場景以外,商戶系統先調用該接口在微信支付服務后臺生成預支付交易單,/// 返回正確的預支付交易回話標識后再按掃碼、JSAPI、APP等不同場景生成交易串調起支付。/// </summary>/// <param name="info">商品訂單數據</param>public WxPayData UnifiedOrder(WxPayOrderData info){WxPayData data = new WxPayData(true);data.SetValue("product_id", info.product_id);//商品IDdata.SetValue("openid", info.openid);//商品ID//其他信息data.SetValue("body", info.body);//商品描述data.SetValue("attach", info.attach);//附加數據data.SetValue("total_fee", info.total_fee);//總金額data.SetValue("goods_tag", info.goods_tag);//商品標記data.SetValue("trade_type", info.trade_type);//交易類型//默認構建data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss"));//交易起始時間data.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss"));//交易結束時間..............最后的數據交換邏輯,我們通過對URL進行POST提交XML數據給它獲取返回結果就可以了,如下所示。
string url = "https://api.mch.weixin.qq.com/pay/unifiedorder";return GetPostResult(data, url);其中上面的函數的代碼邏輯如下所示,主要是把返回的結果再還原為XML對象類WxPayData。
/// <summary>/// 通用的獲取結果函數/// </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;}對于掃碼操作的模式二,直接生成一種二維碼,不需要后臺進行回調的,那么它的實現邏輯只需要對上面代碼進行封裝就可以了,如先構建二維碼的函數代碼如下所示。
/// <summary>/// 生成直接支付url,支付url有效期為2小時,模式二/// </summary>/// <param name="info">商品訂單數據</param>/// <returns></returns>public string GetPayUrl(WxPayOrderData info){WxPayData result = UnifiedOrder(info);//調用統一下單接口return result.GetString("code_url");//獲得統一下單接口返回的二維碼鏈接}如在Winform界面里面,調用生成二維碼的代碼如下所示,主要邏輯就是構建好二維碼,然后顯示在界面上。
private void btnGetPayUrl_Click(object sender, EventArgs e){//測試掃碼模式二的生成二維碼方式WxPayOrderData data = new WxPayOrderData(){product_id = "123456789",body = "測試支付-模式二",attach = "愛奇迪技術支持",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;}另外對于模式一,它在前端傳入一個簡單的產品ID,生成二維碼,當用戶掃碼的時候,微信后臺會調用商戶平臺(我們服務器)的回調處理方法,這個回調方法會調用統一下單的API進行生成支付交易,過程有點復雜,我們來看看,我們的實現代碼如下所示。
/// <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());//隨機字符串 data.SetValue("sign", data.MakeSign());//簽名string str = data.ToUrlParams();//轉換為URL串string url = "weixin://wxpay/bizpayurl?" + str;return url;}它的調用代碼生成二維碼操作如下所示。
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;}我們在第一小節里面介紹了,需要在微信后臺配置掃碼的回調函數,如下所示。
這樣我們還需要添加一個頁面aspx、或者一般處理程序ashx的方式來實現掃碼的回調過程。具體的邏輯也就是在這個頁面里面獲取到提交過來的參數,然后調用統一下單處理后,進行數據返回即可,代碼邏輯如下所示。
?
4、在頁面上進行掃碼處理
前面的例子,我介紹了Winfrom的掃碼例子,很多時候,我們的應用可能是基于Web的,那么它的實現是如何的呢,下面我繼續介紹一下。
首先我們在自己的業務Web后臺系統里面,添加兩個頁面,主要是用來生成二維碼在頁面上進行展示的,如下所示。
最終我們在NativePayPage.aspx頁面上展示我們的二維碼,方便用戶進行掃碼支付處理,頁面的代碼很簡單,我們只需要在前端頁面放置兩個圖片控件,圖片內容通過MakeQRCode.aspx頁面進行生成就可以了。
<!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";//生成掃碼支付模式一urlstring url1 = api.GetPrePayUrl(productId);//生成掃碼支付模式二urlWxPayOrderData info = new WxPayOrderData(){product_id = "123456789",body = "測試支付-模式二",attach = "愛奇迪技術支持",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);}實現后的頁面效果如下所示。
實現并預覽效果,確定是我們所需的頁面后,我們可以發布在公眾號的菜單連接上進行測試使用了。
打開微信公眾號-廣州愛奇迪,我們可以看到對應的菜單發生改變,并且看到進入微信支付的菜單可以進行支付了。
????
?
以上就是微信支付的掃碼過程的一個實現,微信支付還包括很多其他API接口,后面有機會可以繼續進行介紹。微信支付的接口實現雖然相對其他微信接口比較復雜一些,但是我們一旦完成幾個案例,后面的就相對比較容易的了,因為它的調用方式基本上比較一致,很類似。
?
?
如果對這個《C#開發微信門戶及應用》系列感興趣,可以關注我的其他文章,系列隨筆如下所示:
C#開發微信門戶及應用(32)--微信支付接入和API封裝使用
C#開發微信門戶及應用(31)--微信語義理解接口的實現和處理
C#開發微信門戶及應用(30)--消息的群發處理和預覽功能
C#開發微信門戶及應用(28)--微信“搖一搖·周邊”功能的使用和接口的實現
C#開發微信門戶及應用(27)-公眾號模板消息管理?
C#開發微信門戶及應用(26)-公眾號微信素材管理
C#開發微信門戶及應用(25)-微信企業號的客戶端管理功能
C#開發微信門戶及應用(24)-微信小店貨架信息管理
C#開發微信門戶及應用(23)-微信小店商品管理接口的封裝和測試
C#開發微信門戶及應用(22)-微信小店的開發和使用
C#開發微信門戶及應用(21)-微信企業號的消息和事件的接收處理及解密?
C#開發微信門戶及應用(20)-微信企業號的菜單管理
C#開發微信門戶及應用(19)-微信企業號的消息發送(文本、圖片、文件、語音、視頻、圖文消息等)
C#開發微信門戶及應用(18)-微信企業號的通訊錄管理開發之成員管理
C#開發微信門戶及應用(17)-微信企業號的通訊錄管理開發之部門管理
C#開發微信門戶及應用(16)-微信企業號的配置和使用
C#開發微信門戶及應用(15)-微信菜單增加掃一掃、發圖片、發地理位置功能
C#開發微信門戶及應用(14)-在微信菜單中采用重定向獲取用戶數據
C#開發微信門戶及應用(13)-使用地理位置擴展相關應用
C#開發微信門戶及應用(12)-使用語音處理
C#開發微信門戶及應用(11)--微信菜單的多種表現方式介紹
C#開發微信門戶及應用(10)--在管理系統中同步微信用戶分組信息
C#開發微信門戶及應用(9)-微信門戶菜單管理及提交到微信服務器
C#開發微信門戶及應用(8)-微信門戶應用管理系統功能介紹
C#開發微信門戶及應用(7)-微信多客服功能及開發集成
C#開發微信門戶及應用(6)--微信門戶菜單的管理操作
C#開發微信門戶及應用(5)--用戶分組信息管理
C#開發微信門戶及應用(4)--關注用戶列表及詳細信息管理
C#開發微信門戶及應用(3)--文本消息和圖文消息的應答
C#開發微信門戶及應用(2)--微信消息的處理和應答
C#開發微信門戶及應用(1)--開始使用微信接口
轉載于:https://www.cnblogs.com/zxtceq/p/5417495.html
總結
以上是生活随笔為你收集整理的C#开发微信门户及应用(32)--微信支付接入和API封装使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 查找问题的利器 - Git Bisect
- 下一篇: 快捷配置Hibernate实现对数据库的