溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

.NET支付寶App支付接入的實例分析

發(fā)布時間:2021-06-08 10:29:52 來源:億速云 閱讀:216 作者:小新 欄目:編程語言

這篇文章將為大家詳細(xì)講解有關(guān).NET支付寶App支付接入的實例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

一、前言

      最近也是為了新產(chǎn)品忙得起飛,博客都更新的慢了。新產(chǎn)品為了方便用戶支付,需要支付寶掃碼接入。這活落到了我的身上。產(chǎn)品是Windows系統(tǒng)下的桌面軟件,通過軟件生成二維碼支付。界面以原生的MVVM編寫,下面敘述一下基本的過程,做過的老司機(jī)可以直接點關(guān)閉了。

二、申請接口

      申請接口是第一步,首先有這么幾件事:

  1. 公司具有支付寶賬戶

  2. 公司具有營業(yè)資質(zhì)(廢話)

  3. 創(chuàng)建應(yīng)用,簽約電腦網(wǎng)站支付,手機(jī)支付,App支付。

  4. 創(chuàng)建私鑰、公鑰、支付寶公鑰

  5. 配置網(wǎng)關(guān)及回調(diào)地址

       需要注意的是以下幾點:

  1. 創(chuàng)建應(yīng)用時,名稱不要帶有“支付”、“pay”等字樣,圖片建議高清

  2. 創(chuàng)建應(yīng)用時,簽約支付需要一些申請材料,如:營業(yè)資質(zhì)照片,公司照片4張,應(yīng)用的介紹(名稱,下載地址,公司網(wǎng)站是否有該應(yīng)用,該應(yīng)用出現(xiàn)支付寶支付的界面樣式)

  3. 簽約后需要審核,大致一天,(阿里確實快,騰訊微信要4天),審核通過會發(fā)送一份郵件,里面有鏈接,點擊鏈接完成簽約

  4. 創(chuàng)建私鑰、公鑰、支付寶公鑰,在支付寶接口網(wǎng)站上有官方工具,下載使用即可

  5. 網(wǎng)關(guān)與回調(diào)地址要與公司網(wǎng)站形成關(guān)聯(lián),比如是二級域名;如果網(wǎng)關(guān)、回調(diào)地址與公司網(wǎng)站沒什么聯(lián)系,恐怕不行。

三、代碼流程

       有三個構(gòu)成元素??蛻舳塑浖虘?a title="服務(wù)器" target="_blank" href="http://www.kemok4.com/">服務(wù)器后臺,支付寶后臺

       客戶端軟件點擊“獲取支付二維碼”去獲得一個可支付的二維碼:

       封裝客戶端的一些必要信息發(fā)送給商戶服務(wù)器后臺形成一個商戶訂單

        /// <summary>
        /// 獲取二維碼信息        /// </summary>
        /// <param name="packageClientInfo">封裝信息</param>
        /// <param name="serverAddress">商戶產(chǎn)品服務(wù)器地址</param>
        /// <returns></returns>
        public static void GetQRCodeInfo(string packageClientInfo, string serverAddress, Action<string> getQRCodeAction)
        {            if (!string.IsNullOrEmpty(packageClientInfo))
            {                try
                {
                    HttpClient httpsClient = new HttpClient
                    {
                        BaseAddress = new Uri(serverAddress),
                        Timeout = TimeSpan.FromMinutes(20)
                    };                    if (DsClientOperation.ConnectionTest(httpsClient))
                    {
                        StringContent strData = new StringContent(
                                                           packageClientInfo,
                                                           Encoding.UTF8,
                                                           RcCommonNames.JasonMediaType);                        
                                                           string PostUrl = httpsClient.BaseAddress + "api/AlipayForProduct/GetQRCodeString";
                        Uri address = new Uri(PostUrl);
                        Task<HttpResponseMessage> response = httpsClient.PostAsync(address, strData);
                        response.ContinueWith(
                            (postTask) =>
                            {                                
                            if (postTask.IsFaulted)
                                {                                    
                                throw postTask.Exception;
                                }
                                HttpResponseMessage postResponse = postTask.Result;
                                postResponse.EnsureSuccessStatusCode();                                
                                var result = postResponse.Content.ReadAsStringAsync().Result;
                                getQRCodeAction(JsonConvert.DeserializeObject<string>(result)); //注意這個委托                      
                                          return result;
                            });
                    }
                }                catch
                {                    // ignored                }
            }
        }

        這里的委托方法是用來生成二維碼的,當(dāng)你從這個“api/AlipayForProduct/GetQRCodeString”返回一些字符串(result),比如返回的是:

        "http://xxx.xxx.com/AlipayForProduct/SendInfoToAlipay?ordernumber=" + $"{orderNumber}";(orderNumber為商戶訂單號)

        然后使用ThoughtWorks.QRCode.dll去生成二維碼

        /// <summary>
        /// 根據(jù)字符串得到相應(yīng)的二維碼        /// </summary>
        /// <param name="qrInfo"></param>
        /// <param name="productName"></param>
        /// <param name="version"></param>
        /// <returns></returns>
        public static Image CreateQRCodeImage(string qrInfo, string productName, string version)
        {            try
            {                if (!string.IsNullOrEmpty(qrInfo))
                {
                    QRCodeEncoder encoder = new QRCodeEncoder
                    {
                        QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE,
                        QRCodeScale = 4,
                        QRCodeVersion = 0,
                        QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M
                    };                    
                    //編碼方式(注意:BYTE能支持中文,ALPHA_NUMERIC掃描出來的都是數(shù)字)                    
                    //大小(值越大生成的二維碼圖片像素越高)                    
                    //版本(注意:設(shè)置為0主要是防止編碼的字符串太長時發(fā)生錯誤)                    
                    //錯誤效驗、錯誤更正(有4個等級)
                    Image image = encoder.Encode(qrInfo, Encoding.GetEncoding("utf-8"));                    
                    string filename = $"{productName}_{version}.png";                    
                    var userLocalPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);                    
                    var docPath = Path.Combine(userLocalPath, @"YourProduct\QRCode");                    
                    if (!Directory.Exists(docPath))
                    {
                        Directory.CreateDirectory(docPath);
                    }                    string filepath = Path.Combine(docPath, filename); 
                    using (FileStream fs = new FileStream(filepath, FileMode.OpenOrCreate, FileAccess.Write))
                    {
                        image.Save(fs, System.Drawing.Imaging.ImageFormat.Png);
                        fs.Close();
                        image.Dispose();
                    }                    return image;
                }
            }            catch (Exception)
            {                return null;
            }            return null;
        }

這樣就產(chǎn)生了二維碼,說白了,就是把一個服務(wù)的api由字符串變成了圖片,當(dāng)用戶使用支付寶app去掃這個二維碼時,會去請求這個api:

          "http://xxx.xxx.com/AlipayForProduct/SendInfoToAlipay?ordernumber=" + $"{orderNumber}";(orderNumber為商戶訂單號)    

          orderNumber = Request[ (! matchedItem = db.OrderInfoForProduct.FirstOrDefault(x => x.OrderNumber == (matchedItem !=  && matchedItem.IsPaid == 
                     alipayServerURL =  app_id = privateKeyPem = format =  version =  signType = 
                     out_trade_no = orderNumber; 
                     product_code = ; 
                     total_amount = ;  
                     subject = ; 
                     body = ; =  returnurl = $ notifyurl == =  +                                      + body +  +                                      + subject +  +                                      + out_trade_no +  +                                      + total_amount +  +                                      + product_code +  +                                     
                    requestWap.SetReturnUrl(returnurl); = pNone =  + responseWap.Body +

異步請求一般需要做這么幾件事:

  1. 用戶掃碼支付完之后,支付寶后臺會把所有需要驗證的信息發(fā)給你,除了一個參數(shù)不需要驗簽完,其余都需要驗簽;

  2. 如果驗簽成功且支付狀態(tài)也是成功交易后,你需要更新商戶服務(wù)器后臺關(guān)于此條商戶訂單的狀態(tài),比如將其支付狀態(tài)變成已支付,填充支付時間等等;

 
          <, > sPara = (sPara.Count > 
                 sign_type = Request.Form[
                 seller_id = Request.Form[]; 
                 trade_status = Request.Form[]; 
                 notify_time = Request.Form[]; 
                 app_id = Request.Form[]; 
                 out_trade_no = Request.Form[]; 
                 total_amount = Request.Form[]; 
                 receipt_amount = Request.Form[]; 
                 invoice_amount = Request.Form[]; 
                 buyer_pay_amount = Request.Form[]; 
                 body = Request.Form[]; 
                 gmt_payment = Request.Form[]; 

                 tradeGuid = 
                 isVerfied = AlipaySignature.RSACheckV1(sPara, alipayPublicKey, , sign_type,  (app_id == appID && seller_id == isTradeSuccess = .Equals(trade_status, ) || .Equals(trade_status,  (

同步請求一般需要做這么幾件事:

       1. 當(dāng)異步調(diào)用完后,如果支付成功而且商戶服務(wù)器后臺對此條訂單號處理也正確的話;同步請求可以再做一次驗證

       2. 如果驗證成功,跳轉(zhuǎn)支付成功頁面;如果失敗,跳轉(zhuǎn)支付失敗頁面。

        public ActionResult AlipayResult()
        {
            SortedDictionary<string, string> sPara = GetRequestGet();            if (sPara.Count > 0)
            {                //非驗簽參數(shù)
                var sign_type = Request.QueryString["sign_type"];                //接收參數(shù)并排序
                var seller_id = Request.QueryString["seller_id"]; //賣家支付寶用戶號
                var app_id = Request.QueryString["app_id"]; //開發(fā)者AppId
                var out_trade_no = Request.QueryString["out_trade_no"]; //交易訂單號

                var orderNumberGuid = new Guid(out_trade_no);                try
                {                    var isVerfied = AlipaySignature.RSACheckV1(sPara, alipayPublicKey, "utf-8", sign_type, false);    
                                if (isVerfied)
                    {                        if (app_id == appID && seller_id == sellerID)
                        {
                           //你的支付成功頁面
                        }
                    }

                }                catch
                {
                   //你的支付失敗頁面
                }
            }            else
            {               //你的支付失敗頁面
            }            return View();
        }        /// <summary>
        /// 參數(shù)排序字典        /// </summary>
        /// <returns></returns>
        private SortedDictionary<string, string> GetRequestGet()
        {
            SortedDictionary<string, string> sArray = new SortedDictionary<string, string>();
            NameValueCollection coll = Request.QueryString;

            String[] requestItem = coll.AllKeys;            foreach (string t in requestItem)
            {
                sArray.Add(t, Request.QueryString[t]);
            }            return sArray;
        }

關(guān)于“.NET支付寶App支付接入的實例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI