C#開發微信入口網站及應用程式微信支付存取與API封裝使用

高洛峰
發布: 2017-03-07 10:09:27
原創
2164 人瀏覽過

在微信的應用上,微信支付是一個比較有用的部分,但也是比較複雜的技術要點,在微商大行其道的年代,自己的商店沒有增加微信支付好像也說不過去,微信支付旨在為廣大微信用戶及商家提供更優質的支付服務,微信的支付和安全系統由騰訊財付通提供支援。本文主要介紹如何在微信公眾號上實現微信支付的接入、微信支付API的封裝,以及API的調用,實現我們一些常見的業務調用。

1、開通微信支付並配置

微信支付是需要微信公眾號的認證基礎,也就是只對認證的公眾號開放,微信認證需要簽署相關的資料,並且進行對帳認證,一般會有電話聯絡確認相關的資訊的。

C#開發微信入口網站及應用程式微信支付存取與API封裝使用

在微信支付API開始使用前,我們一般需要在後台進行一定的配置,如我們需要配置公眾號支付的授權目錄,測試白名單等信息,以及掃碼支援的回調處理位址(這個實作在後面再講),如下所示。

C#開發微信入口網站及應用程式微信支付存取與API封裝使用

在使用API​​之前,我們要知道微信一些關鍵的操作,如退款、撤銷訂單等操作是需要證書的,而且常規的支付操作,我們也需要商戶號、商家支付秘鑰等信息,這些證書和秘鑰信息,是我們從微信支付的商戶平台上獲取的,我們微信支付開通並審核通過後,我們就可以登錄商戶平台進行相關的操作了。

首先我們需要在開發的電腦上安裝憑證。

C#開發微信入口網站及應用程式微信支付存取與API封裝使用

然後需要設定API的密碼金鑰

C#開發微信入口網站及應用程式微信支付存取與API封裝使用

#最後在【API安全】專案上下載憑證供我們開發環境使用。

C#開發微信入口網站及應用程式微信支付存取與API封裝使用

 

2、微信支付API的介紹

微信支付配置相關的參數,並取得憑證、API密碼、商家號等資訊後,我們可以開始了解微信支付的API的具體使用了,我們需要先把API封裝為C#的類別庫進行使用,這樣才能在各種應用裡面方便呼叫。

微信支付分為有多種方式,如掃碼支付、公眾號支付、JSAPI支付、APP支付等方面,不過核心的API都差不多,基本上都覆蓋了下面截圖的幾個API ,只是有部分的介面差異。

C#開發微信入口網站及應用程式微信支付存取與API封裝使用

我們可以從其中掃碼付款開始了解,這個是對二維碼進行掃碼支付的場景,分為了模式一和模式二兩種方式。

C#開發微信入口網站及應用程式微信支付存取與API封裝使用

掃碼付款可分為兩種模式,商家依照支付場景選擇對應模式。

【模式一】:商家後台系統依據微信支付規則連結產生二維碼,連結中帶固定參數productid(可定義為產品識別或訂單號)。用戶掃碼後,微信支付系統將productid和用戶唯一識別(openid)回調商戶後台系統(需要設定支付回調URL),商戶後台系統根據productid產生支付交易,最後微信支付系統發起用戶支付流程。

【模式二】:商家後台系統呼叫微信支付【統一下單API】產生預付交易,將介面回傳的連結產生二維碼,用戶掃碼後輸入密碼完成支付交易。注意:此模式的預付單有效期限為2小時,過期後無法支付。

根據掃碼支付的API說明,我們可以分別對這些介面(如統一下單、查詢訂單、關閉訂單、申請退款、查詢退款、下載對帳單等介面進行逐一包裝,以方便我們的開發使用。先來看看統一下單的介面說明,以了解它的具體使用。

##除被掃支付場景以外,商家系統先呼叫該介面在微信支付服務後台產生預付交易單,回傳正確的預付交易回話標識後再按掃碼、JSAPI、APP等不同場景產生交易串調起付款。


2)介面連結


URL位址:https ://api.mch.weixin.qq.com/pay/unifiedorder


#3)是否需要憑證


##不需要

4)請求參數


請求參數看似很多,大概分成兩個部分,一部分是系統必須的固定參數,一部分是業務所需的參數。

系統必須的固定參數如下所示。

有一部分是業務參數,業務參數如下所示,主要是記錄訂單的相關產品ID、說明、費用等等


微信支付介面的呼叫和公眾號其他介面呼叫不太一樣,這裡全部是採用XML進行交換的,感覺沒有JSON那麼方便靈活,如下所示是統一下單的接口提交資料。

 

然後傳回的資料也是XML的,如下面範例程式碼所示,而且其中的欄位內容還不太確定,因此按官網的建議,使用字典集合來儲存傳回的資料對象。

C#開發微信入口網站及應用程式微信支付存取與API封裝使用

 

3、微信支付APIC#封裝和呼叫C#開發微信入口網站及應用程式微信支付存取與API封裝使用

#根據上面的描述,我們大概了解了微信支付API 的大概說明,根據這些信息,我們可以對它進行C#代碼的封裝了,對於代碼的封裝,我們關鍵點在其中第一個,如果順利封裝好第一個接口,那麼後面的根據通用的方式,就很容易繼續處理這些介面了。

例如,我們可以定義好微信支付的API介面定義,如下所示。

C#開發微信入口網站及應用程式微信支付存取與API封裝使用

/// <summary>
    /// 微信支付接口
    /// </summary>
    public interface ITenPayApi
    {      
        /// <summary>
        /// 生成扫描支付模式一URL
        /// </summary>
        /// <param>商品ID
        /// <returns></returns>
        string GetPrePayUrl(string productId);

        /// <summary>
        /// 生成直接支付url,支付url有效期为2小时,模式二
        /// </summary>
        /// <param>商品订单数据
        /// <returns></returns>
        string GetPayUrl(WxPayOrderData info);

        /// <summary>
        /// 统一下单。(不需要证书,默认不需要)
        /// 除被扫支付场景以外,商户系统先调用该接口在微信支付服务后台生成预支付交易单,
        /// 返回正确的预支付交易回话标识后再按扫码、JSAPI、APP等不同场景生成交易串调起支付。
        /// </summary>
        /// <param>商品订单数据
        WxPayData UnifiedOrder(WxPayOrderData info);

        .............
登入後複製

其中的介面方法的輸入參數我們定義一個實體類別 C#開發微信入口網站及應用程式微信支付存取與API封裝使用

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> m_values = new SortedDictionary<string>();
        
        /// <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);//公众帐号id
            this.SetValue("mch_id", WxPayConfig.MCHID);//商户号
            this.SetValue("nonce_str", GenerateNonceStr());//随机字符串
            this.SetValue("out_trade_no", GenerateOutTradeNo(WxPayConfig.MCHID));//随机字符串

        }</string></string>
登入後複製

然後我們根據上面的資料定義,可以實現統一下單的函數內容,主要是把輸入參數轉換成我們需要的字典參數集合,如下程式碼所示。

/// <summary>
        /// 统一下单。(不需要证书,默认不需要)
        /// 除被扫支付场景以外,商户系统先调用该接口在微信支付服务后台生成预支付交易单,
        /// 返回正确的预支付交易回话标识后再按扫码、JSAPI、APP等不同场景生成交易串调起支付。
        /// </summary>
        /// <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);//附加数据
            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>商品订单数据
        /// <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;
        }
登入後複製

C#開發微信入口網站及應用程式微信支付存取與API封裝使用

另外对于模式一,它在前端传入一个简单的产品ID,生成二维码,当用户扫码的时候,微信后台会调用商户平台(我们服务器)的回调处理方法,这个回调方法会调用统一下单的API进行生成支付交易,过程有点复杂,我们来看看,我们的实现代码如下所示。

/// <summary>
        /// 生成扫描支付模式一URL
        /// </summary>
        /// <param>商品ID
        /// <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;
        }
登入後複製

我们在第一小节里面介绍了,需要在微信后台配置扫码的回调函数,如下所示。

C#開發微信入口網站及應用程式微信支付存取與API封裝使用

这样我们还需要添加一个页面aspx、或者一般处理程序ashx的方式来实现扫码的回调过程。具体的逻辑也就是在这个页面里面获取到提交过来的参数,然后调用统一下单处理后,进行数据返回即可,代码逻辑如下所示。

C#開發微信入口網站及應用程式微信支付存取與API封裝使用

 

4、在页面上进行扫码处理

前面的例子,我介绍了Winfrom的扫码例子,很多时候,我们的应用可能是基于Web的,那么它的实现是如何的呢,下面我继续介绍一下。

首先我们在自己的业务Web后台系统里面,添加两个页面,主要是用来生成二维码在页面上进行展示的,如下所示。

C#開發微信入口網站及應用程式微信支付存取與API封裝使用

最终我们在NativePayPage.aspx页面上展示我们的二维码,方便用户进行扫码支付处理,页面的代码很简单,我们只需要在前端页面放置两个图片控件,图片内容通过MakeQRCode.aspx页面进行生成就可以了。

nbsp;html>


    <meta>
    <meta> 
    <title>微信支付样例-扫码支付</title>


    <div>扫码支付模式一</div><br>
    <image></image>
    <br><br><br>
    <div>扫码支付模式二</div><br>
    <image></image>
    

登入後複製

页面后台的代码就是绑定二维码的过程,代码如下所示,和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 = "爱奇迪技术支持",
                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);
        }
登入後複製

实现后的页面效果如下所示。

C#開發微信入口網站及應用程式微信支付存取與API封裝使用

实现并预览效果,确定是我们所需的页面后,我们可以发布在公众号的菜单连接上进行测试使用了。

C#開發微信入口網站及應用程式微信支付存取與API封裝使用

打开微信公众号-广州爱奇迪,我们可以看到对应的菜单发生改变,并且看到进入微信支付的菜单可以进行支付了。

C#開發微信入口網站及應用程式微信支付存取與API封裝使用  C#開發微信入口網站及應用程式微信支付存取與API封裝使用  C#開發微信入口網站及應用程式微信支付存取與API封裝使用

 

以上就是微信支付的掃碼過程的一個實現,微信支付還包括很多其他API接口,後面有機會可以繼續介紹。微信支付的介面實作雖然相對其他微信介面比較複雜一些,但是我們一旦完成幾個案例,後面的就相對比較容易的了,因為它的呼叫方式基本上比較一致,很類似。

 更多C#開發微信入口網站及應用微信支付存取與API封裝使用相關文章請關注PHP中文網!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!