.NET MVC結構框架下的微信掃碼支付模式二 API接口開發測試

 直接上乾貨 ,咱們的宗旨就是爲人民服務、授人以魚不如授人以漁、不吹毛求疵、不浮誇、不虛僞、不忽悠、一切都是爲了社會共同進步,繁榮昌盛,小程序猿、大程序猿、老程序猿仍是嫩程序猿,但願這個社會不要太急功近利 ,但願每一個IT行業的BOSS要有良知,程序猿的青春年華都是無私默默奉獻,都是拿命拼出來瞭如今的成就,若是卸磨殺驢,若是逼良爲娼,請MM你的良心對得起你爹媽嗎,你也有家,你也有小孩,你也有父母的。html

  在這裏致敬程序猿, 致敬咱們的攻城獅,致敬咱們最可愛的人! 珍惜生命,換種活法也是依然精彩。 小程序

View層代碼:api

NativePay.cshtml:數組

@{
    ViewBag.Title = "微信掃碼支付";
}
<style>
    .container .row{ margin-left: 0;margin-right: 0;}
    .page-header .header img{width:40px;}
    .page-header .row div,.payinfo{padding-left: 0;}
     .row .paymoney{text-align: right;}
    .payinfo img{height: 30px;}
    .payinfo span{vertical-align: middle;color: gray}
    .paymoney span.warning{color:orangered;margin: 0 5px;}
     .qrcode {width: 200px;height: 200px; display: block;margin-top: 20px;margin-bottom: 20px;}
     .payqr img{width: 200px;}
</style>
<div class="container">
    <div class="row">
        <div class="page">
            <div class="page-header">
                <div class="row header">
                    <h2><img src="~/WxPayAPI/imgs/logo.png" /> 收銀臺</h2>
                </div>
                <div class="row">
                    <div class="col-md-8">
                        <p>訂單編號:@ViewBag.OrderNumber</p>
                    </div>
                    <div class="col-md-4 paymoney">
                        <h2>應付金額:@ViewBag.OrderPrice</h2>
                    </div>
                </div>
            </div>
            <div class="row">
                <div class="col-md-8 payinfo">
                    <img src="~/WxPayAPI/imgs/WePayLogo.png" />
                    <img src="~/WxPayAPI/imgs/按鈕標籤.png" />
                    <span>億萬用戶的選擇,更快更安全</span>
                </div>
                <div class="col-md-4 paymoney">支付<span class="warning">@ViewBag.OrderPrice</span></div>
            </div>
            <div class="row payqr">
                <img src="@ViewBag.QRCode" class="qrcode"  />
                <img src="~/WxPayAPI/imgs/說明文字.png" />
            </div>
            <input type="hidden" id="trade" value="@ViewBag.OrderNumber"/>
        </div>
    </div>
</div>

<script>
    $(function() {
        var trade = $("#trade").val();
        setInterval(function() {
            $.post("/WeChatPay/WXNativeNotifyPage", { tradeno: trade }, function (data) {
                if (data == 1) {
                    location.href = "/WeChatPay/PaySuccess?tradeno=" + trade;
                } if (data == 2) {
                    location.href = "/WeChatPay/PaySuccess?tradeno=" + trade;
                }
            });
        }, 1000);

    });
  

</script>

通知頁面 能夠忽略:安全

WXNativeNotifyPage.cshtml服務器

@{
    ViewBag.Title = "WXNativeNotifyPage";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>WXNativeNotifyPage</h2>

PaySuccess.cshtml微信

<@using WeChatPayMvc.Models
@model  PayOrder

@{
    ViewBag.Title = "PaySuccess";
}
<style>
     .container .row{ margin-left: 0;margin-right: 0;}
</style>
<div class="container">
    <div class="row">
        <div class="page">
            <div class="page-header">
                <div class="row header">
                    @if (Model.PayStatus ==1)
                    {
                        <h2>支付成功!</h2>
                    }
                    else
                    {
                        <h2>支付失敗!</h2>
                    }
                </div>
                <div>訂單號:@Model.OrderNumber</div>
            </div>
        </div>
    </div>
</div>

 

Controller 控制器代碼:併發

WeChatPayControllerapp

using Business;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Xml;
using ThoughtWorks.QRCode.Codec;
using WeChatPayMvc.Models;
using System.Text.RegularExpressions;

namespace WeChatPayMvc.Controllers
{
    public class WeChatPayController : Controller
    {
        //
        // GET: /WeChatPay/

        public ActionResult Index()
        {
            return RedirectToAction("NativePay");
        }

        /// <summary>
        /// 掃碼支付下單入口
        /// </summary>
        /// <returns></returns>
        public ActionResult NativePay()
        {
            var order = new PayOrder();
            //order.OrderNumber = GenerateOutTradeNo();
            //order.OrderPrice = (Convert.ToInt32(decimal.Parse("0.01") * 100)).ToString();
            ViewBag.OrderNumber = GenerateOutTradeNo();
            ViewBag.OrderPrice = decimal.Parse("0.01").ToString();
            int total_fee = (Convert.ToInt32(decimal.Parse(ViewBag.OrderPrice) * 100));
            string productid = "2017121000000";

            
            WechatPayHelper wxpay = new WechatPayHelper();
            //主要參數依次是 訂單號 金額 openid 公衆號  產品productid
            string return_response = wxpay.GetUnifiedOrderResultNative(ViewBag.OrderNumber, total_fee, "財政專費", "oC88888df99jdfdWf6p999Jgu4", productid);
            //將url生成二維碼圖片

            ViewBag.QRCode = "http://localhost:38773/WeChatPay/MakeQRCode?data=" + HttpUtility.UrlEncode(return_response);
            return View();
        }
        /// <summary>
        /// 二維碼生成工具
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public FileResult MakeQRCode(string data)
        {
            if (string.IsNullOrEmpty(data))
                throw new ArgumentException("data");

            //初始化二維碼生成工具
            QRCodeEncoder qrCodeEncoder = new QRCodeEncoder();
            qrCodeEncoder.QRCodeEncodeMode = QRCodeEncoder.ENCODE_MODE.BYTE;
            qrCodeEncoder.QRCodeErrorCorrect = QRCodeEncoder.ERROR_CORRECTION.M;
            qrCodeEncoder.QRCodeVersion = 0;
            qrCodeEncoder.QRCodeScale = 4;

            //將字符串生成二維碼圖片
            Bitmap image = qrCodeEncoder.Encode(data, Encoding.Default);

            //保存爲PNG到內存流  
            MemoryStream ms = new MemoryStream();
            image.Save(ms, ImageFormat.Jpeg);

            return File(ms.ToArray(), "image/jpeg");
        }

        /**
        * 根據當前系統時間加隨機序列來生成訂單號
         * @return 訂單號
        */
        public static string GenerateOutTradeNo()
        {
            var ran = new Random();
            return string.Format("{0}{1}", DateTime.Now.ToString("yyyyMMddHHmmss"), ran.Next(99999));
        }

        public ActionResult PaySuccess(string tradeno)
        {
            
            var order = new PayOrder() { OrderNumber = tradeno };
            return View(order);
        }

         /// <summary>
        /// //接收從微信後臺POST過來的數據  通知地址信息
        /// </summary>
        public ActionResult WXNativeNotifyPage()
        { 
             //接收從微信後臺POST過來的數據
            //Stream s = Request.InputStream;
            //int count = 0;
            //byte[] buffer = new byte[1024];
            //StringBuilder builder = new StringBuilder();
            //while ((count = s.Read(buffer, 0, 1024)) > 0)
            //{
            //    builder.Append(Encoding.UTF8.GetString(buffer, 0, count));
            //}
            //s.Flush();
            //s.Close();
            //s.Dispose();

           
            ////轉換數據格式並驗證簽名
            //WxPayData data = new WxPayData();
            //try
            //{
            //    data.FromXml(builder.ToString());
            //}
        StreamReader reader = new StreamReader(Request.InputStream);
        String xmlData = reader.ReadToEnd();
         WriteLogFile("接收post來的微信異步回調:" + xmlData, "微信異步回調");
        //序列化xml //轉換數據格式並驗證簽名
        Dictionary<string, string> dicParam = GetInfoFromXml(xmlData);
        string data = "";
        try
        {
            //當收到通知進行處理時,首先檢查對應業務數據的狀態,判斷該通知是否已經處理過,若是沒有處理過再進行處理,若是處理過直接返回結果成功。在對業務數據進行狀態檢查和處理以前,要採用數據鎖進行併發控制,以免函數重入形成的數據混亂。

            if (dicParam.ContainsKey("return_code") && dicParam["return_code"] == "SUCCESS")
            {

                WechatPayHelper wcHelper = new WechatPayHelper();
                string strRequestData = "";
                //對返回的參數信息進行簽名
                string strSign = wcHelper.MakeSignData(dicParam, ref strRequestData);
                //判斷返回簽名是否正確
                if (strSign == dicParam["sign"])
                {
                    //判斷業務結果
                    if ("SUCCESS" == dicParam["result_code"])
                    {
                        //////檢查openid和product_id是否返回
                        if (string.IsNullOrEmpty(dicParam["openid"]) || string.IsNullOrEmpty(dicParam["product_id"]))
                        {
                            data = "<xml><return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[產品ID不存在回調數據異常]]></return_msg></xml>";
                            Response.Write(data);
                        }

                        //判斷業務是否處理過  應該有通知日誌表  先暫經過繳費表作判斷
                        string out_trade_no = dicParam["out_trade_no"];//訂單編號

                        if (out_trade_no != null)
                        {
                          //查詢訂單
                            PayOrderBLL payoderBll = new PayOrderBLL();
                            PayOrder pay = payoderBll.Query(out_trade_no);

                            if (pay != null)
                            {
                                //商戶系統對於支付結果通知的內容必定要作簽名驗證,並校驗返回的訂單金額是否與商戶側的訂單金額一致,防止數據泄漏致使出現「假通知」,形成資金損失。
                                if (pay.OrderPrice.Equals(decimal.Parse(dicParam["total_fee"]) / 100))
                                {
                                    data = "<xml><return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[金額不一致回調數據異常]]></return_msg></xml>";
                                    Response.Write(data);
                                }
                                if (pay.PayStatus == 1)
                                {
                                    //已經支付 視爲處理過 直接返回
                                    data = "<xml><return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg></xml>";
                                    Response.Write(data);
                                }
                                else
                                {  //收到確認後,更新訂單的狀態
                                    //修改支付狀態
                                    if (payoderBll.UpdatePayStatus(out_trade_no, "1", 1) > 0)
                                    {
                                       
                                        data = "<xml><return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg></xml>";
                                        Response.Write(data);
                                    }
                                }
                            }

                            else
                            {
                                data = "<xml><return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[系統調用超時]]></return_msg></xml>";
                                Response.Write(data);
                            }
                        }
                    }
                    else
                    {
                        //錯誤信息
                        string error = dicParam["err_code"] + ":" + dicParam["err_code_des"];
                        data = "<xml><return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[系統調用超時]]></return_msg></xml>";
                        Response.Write(data);
                    }
                }
                else
                {
                    data = "<xml><return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[系統調用超時]]></return_msg></xml>";
                    Response.Write(data);
                }
            }

        }
        catch (Exception ex)
        {
            WriteLogFile("微信異步回調異常:" + ex.Message, "異常日誌");
            data = "<xml><return_code><![CDATA[FAIL]]></return_code> <return_msg><![CDATA[系統調用超時]]></return_msg></xml>";
            Response.Write(data);
        }
            return View();

        }

        /// <summary>
        /// 把XML數據轉換爲SortedDictionary<string, string>集合
        /// </summary>
        /// <param name="strxml"></param>
        /// <returns></returns>
        public Dictionary<string, string> GetInfoFromXml(string xmlstring)
        {
            Dictionary<string, string> sParams = new Dictionary<string, string>();
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(xmlstring);
                XmlElement root = doc.DocumentElement;
                int len = root.ChildNodes.Count;
                for (int i = 0; i < len; i++)
                {
                    string name = root.ChildNodes[i].Name;
                    if (!sParams.ContainsKey(name))
                    {
                        sParams.Add(name.Trim(), root.ChildNodes[i].InnerText.Trim());
                    }
                }
            }
            catch (Exception ex)
            {

            }
            return sParams;
        }
        
    }   
}

實用類WechatPayHelper代碼:dom

using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Xml;

namespace WeChatPayMvc
{
    public class WechatPayHelper
    {
        private string RequestUrl = "";//接口調用地址
        //交易安全檢驗碼,由數字和字母組成的32位字符串
        private string key = "";
        private string appid = "";//應用ID
        private string mch_id = "";//商戶號
        private string nonce_str = "";//隨機字符串
        private string sign = "";//簽名
        // private string body = "";//商品描述
        // private string out_trade_no = "";//商戶訂單號
        private string spbill_create_ip = "";//終端IP
        private string notify_url = "";//通知地址
        private string trade_type = "";//交易類型
        private string pay_url = "";
        //字符編碼格式 目前支持 utf-8
        private string input_charset = "utf-8";
        //簽名方式,選擇項:0001(RSA)、MD5
        private string sign_type = "MD5";
        public WechatPayHelper()
        {
            HttpContext Context = System.Web.HttpContext.Current;
            DataTable dt = null;
            
            //native 掃碼支付配置
            string strXML = "Wechat_Pay_Native.xml";
            //////////////////////////////////////////////////
            object objValue = GetCache(strXML);
            if (objValue == null)
            {
                dt = GetConfigXml("//PayConfig/" + strXML);
                SetCache(strXML, dt);
            }
            else
            {
                dt = (DataTable)objValue;
            }
            if (dt != null)
            {
                appid = dt.Rows[0]["appid"].ToString();
                mch_id = dt.Rows[0]["mch_id"].ToString();
                notify_url = dt.Rows[0]["notify_url"].ToString();
                pay_url = dt.Rows[0]["pay_url"].ToString();
                spbill_create_ip = GetUserIp();
                nonce_str = StrRodamNo(16);
                trade_type = dt.Rows[0]["trade_type"].ToString();
                key = dt.Rows[0]["key"].ToString();
            }
        }

        /// <summary>
        /// 獲取當前應用程序指定CacheKey的Cache值
        /// </summary>
        /// <param name="CacheKey"></param>
        /// <returns></returns>
        public static object GetCache(string CacheKey)
        {
            System.Web.Caching.Cache objCache = HttpRuntime.Cache;
            return objCache[CacheKey];
        }
        /// <summary>
        /// 設置當前應用程序指定CacheKey的Cache值
        /// </summary>
        /// <param name="CacheKey"></param>
        /// <param name="objObject"></param>
        public static void SetCache(string CacheKey, object objObject)
        {
            System.Web.Caching.Cache objCache = HttpRuntime.Cache;
            if (objObject != null)
                objCache.Insert(CacheKey, objObject, null, DateTime.UtcNow.AddDays(7), TimeSpan.Zero);
        }


       /// <summary>
        /// 生成直接支付url 調用統一下單,得到下單結果 掃碼支付模式二   支付url有效期爲2小時,
        /// </summary>
        /// <param name="out_trade_no"></param>
        /// <param name="total_fee"></param>
        /// <param name="body"></param>
        /// <returns></returns>
        public string GetUnifiedOrderResultNative(string out_trade_no, int total_fee, string body, string openid, string productId)
        {
            //請求業務參數詳細
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("<xml><appid>{0}</appid><mch_id>{1}</mch_id> <body>{2}</body><nonce_str>{3}</nonce_str>", appid, mch_id, body, nonce_str);
            sb.AppendFormat("<out_trade_no>{0}</out_trade_no><total_fee>{1}</total_fee> <spbill_create_ip>{2}</spbill_create_ip><trade_type>{3}</trade_type>", out_trade_no, total_fee.ToString(), spbill_create_ip, trade_type);
            sb.AppendFormat("<notify_url>{0}</notify_url>", notify_url);
            sb.AppendFormat("<openid>{0}</openid>", openid);
            sb.AppendFormat("<product_id>{0}</product_id>", productId);

            //把請求參數打包成數組
            Dictionary<string, string> softdic = new Dictionary<string, string>();
            softdic.Add("appid", appid);
            softdic.Add("mch_id", mch_id);
            softdic.Add("nonce_str", nonce_str);
            softdic.Add("body", body);
            softdic.Add("out_trade_no", out_trade_no);
            softdic.Add("total_fee", total_fee.ToString());
            softdic.Add("spbill_create_ip", spbill_create_ip);
            softdic.Add("trade_type", trade_type);
            softdic.Add("notify_url", notify_url);
            softdic.Add("openid", openid);
            softdic.Add("product_id", productId);
            //請求參數體
            string strRequest = "";

            //加密簽名
            string strSign = MakeSignData(softdic, ref strRequest);

            strRequest += "&sign=" + strSign;

            //打包xml
            sb.AppendFormat("<sign>{0}</sign></xml>", strSign);

            //發送請求
            string strResponse = RequestWechatpay(sb.ToString());


            //URLDECODE返回的信息
            Encoding code = Encoding.GetEncoding(input_charset);
            strResponse = HttpUtility.UrlDecode(strResponse, code);
            string ResponseURL = ReadXmlNode(strResponse);//得到統一下單接口返回的二維碼連接code_url


            return ResponseURL;
        }

       

        /// <summary>
        /// 簽名原始串
        /// </summary>
        /// <param name="dicParm">全部非空參數</param>
        /// <param name="strQueryString">請求串</param>
        /// <returns>簽名串</returns>
        public string MakeSignData(Dictionary<string, string> dicParm, ref string strQueryString)
        {   //先排序
            Dictionary<string, string> dicSort = dicParm.OrderBy(o => o.Key).ToDictionary(o => o.Key, p => p.Value);
            StringBuilder sb = new StringBuilder();
            //再轉換成URL字符串
            foreach (KeyValuePair<string, string> kvParm in dicSort)
            {
                if (null != kvParm.Value && "".CompareTo(kvParm.Value) != 0
                        && "sign".CompareTo(kvParm.Key) != 0 && "key".CompareTo(kvParm.Key) != 0 && "sign_type".CompareTo(kvParm.Key) != 0)
                {
                    if (sb.Length > 0)
                    {
                        sb.Append("&");
                        strQueryString += "&";
                    }
                    sb.Append(kvParm.Key + "=" + HttpUtility.UrlDecode(kvParm.Value));
                    strQueryString += kvParm.Key + "=" + HttpUtility.UrlEncode(kvParm.Value);
                }
            }
            //再和key拼裝成字符串
            sb.Append("&key=" + key);
            //再進行MD5加密轉成大寫
            return MD5Create(sb.ToString(), input_charset).ToUpper();


        }

        public static string MD5Create(string str, string charset)
        {
            string retStr;
            MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider();

            //建立md5對象
            byte[] inputBye;
            byte[] outputBye;

            //使用GB2312編碼方式把字符串轉化爲字節數組.
            try
            {
                inputBye = Encoding.GetEncoding(charset).GetBytes(str);
            }
            catch (Exception ex)
            {
                inputBye = Encoding.GetEncoding("GB2312").GetBytes(str);
            }
            outputBye = m5.ComputeHash(inputBye);

            retStr = System.BitConverter.ToString(outputBye);
            retStr = retStr.Replace("-", "");
            return retStr;
        }

        /// <summary>
        ///把請求參數信息打包發送請求微信支付地址
        /// </summary>
        /// <param name="strRequestData">請求參數字符串(QueryString)</param>
        /// <returns></returns>
        private string RequestWechatpay(string strRequestData)
        {
            Encoding code = Encoding.GetEncoding(input_charset);

            //把數組轉換成流中所需字節數組類型
            byte[] bytesRequestData = code.GetBytes(strRequestData);

            //請求遠程HTTP
            string strResult = "";
            try
            {
                //設置HttpWebRequest基本信息
                HttpWebRequest myReq = (HttpWebRequest)HttpWebRequest.Create(pay_url);
                myReq.Method = "post";
                myReq.ContentType = "text/xml";

                //填充POST數據
                myReq.ContentLength = bytesRequestData.Length;
                Stream requestStream = myReq.GetRequestStream();
                requestStream.Write(bytesRequestData, 0, bytesRequestData.Length);
                requestStream.Close();

                //發送POST數據請求服務器
                HttpWebResponse HttpWResp = (HttpWebResponse)myReq.GetResponse();
                Stream myStream = HttpWResp.GetResponseStream();

                //獲取服務器返回信息
                StreamReader reader = new StreamReader(myStream, code);
                StringBuilder responseData = new StringBuilder();
                String line;
                while ((line = reader.ReadLine()) != null)
                {
                    responseData.Append(line);
                }

                //釋放
                myStream.Close();

                strResult = responseData.ToString();
            }
            catch (Exception exp)
            {
                strResult = "報錯:" + exp.Message;
            }

            return strResult;
        }


        /// <summary>
        /// 得到客戶端的IP
        /// </summary>
        /// <returns>當前頁面客戶端的IP</returns>
        public static string GetUserIp()
        {

            string userHostAddress = HttpContext.Current.Request.UserHostAddress;

            if (string.IsNullOrEmpty(userHostAddress))
            {
                userHostAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            }

            //最後判斷獲取是否成功,並檢查IP地址的格式(檢查其格式很是重要)
            if (!string.IsNullOrEmpty(userHostAddress) && IsIP(userHostAddress))
            {
                return userHostAddress;
            }
            return "127.0.0.1";


        }

        /// <summary>
        /// 檢查IP地址格式
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static bool IsIP(string ip)
        {
            return System.Text.RegularExpressions.Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
        }


        /// <summary>
        /// 生成隨機字母與數字
        /// </summary>
        /// <param name="IntStr">生成長度</param>
        /// <returns></returns>
        public static string StrRodamNo(int Length)
        {
            return StrRodam(Length, false);
        }

        /// <summary>
        /// 生成隨機字母與數字
        /// </summary>
        /// <param name="Length">生成長度</param>
        /// <param name="Sleep">是否要在生成前將當前線程阻止以免重複</param>
        /// <returns></returns>
        public static string StrRodam(int Length, bool Sleep)
        {
            if (Sleep)
                System.Threading.Thread.Sleep(3);
            char[] Pattern = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };
            string result = "";
            int n = Pattern.Length;
            System.Random random = new Random(~unchecked((int)DateTime.Now.Ticks));
            for (int i = 0; i < Length; i++)
            {
                int rnd = random.Next(0, n);
                result += Pattern[rnd];
            }
            return result;
        }

        #region 讀取xml中的指定節點的值
        /// <summary>  
        /// 讀取xml中的指定節點的值
        /// </summary>  
        private string ReadXmlNode(string filename)
        {
            string result = "調用微信服務異常";
            XmlDocument xmlDoc = new XmlDocument();
            try
            {
                xmlDoc.LoadXml(filename);

                XmlNode root = xmlDoc.SelectSingleNode("xml");
                if (root != null)
                    result = (root.SelectSingleNode("code_url")).InnerText;

            }
            catch (Exception e)
            {
                
            }
            return result;
        }

        #endregion
    }
}

配置文件XML :
Wechat_Pay_Native.xml

<?xml version="1.0" encoding="utf-8" ?>
<data>
  <!--接收微信支付異步通知回調地址,通知url必須爲直接可訪問的url,不能攜帶參數-->
  <notify_url>http://5.20.7.8:300/PayNotifyPage/WXNativeNotifyPage</notify_url>
  <pay_url>https://api.mch.weixin.qq.com/pay/unifiedorder</pay_url>
  <!--微信開放平臺審覈經過的應用APPID-->
  <appid>wxf888888888888</appid>
  <!--微信支付分配的商戶號-->
  <mch_id>1485555555</mch_id>
  <key>16ce99d5252525525252529d</key>
  <subject>財政專費</subject>
  <trade_type>NATIVE</trade_type>
</data>

Models 代碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WeChatPayMvc.Models
{
   public class PayOrder
   {
       public PayOrder()
        { }
        public string OrderNumber { get; set; }
        public string OrderPrice { get; set; }
        public int PayStatus { get; set; }
    }
}

便可完成整個掃碼支付過程, 有圖有真相:

打開微信進行掃碼支付便可。

 最後說明 掃碼支付 openID不須要傳遞 

相關文章
相關標籤/搜索