返回顶部
首页 > 资讯 > 后端开发 > ASP.NET >ASP.Net项目中实现微信APP支付功能
  • 790
分享到

ASP.Net项目中实现微信APP支付功能

2024-04-02 19:04:59 790人浏览 薄情痞子
摘要

最近挺忙的,没时间写东西。然后在弄微信APP支付,网上的搜索一趟,都比较凌乱,我也遇到一些坑,不过也算弄好了,记录分享一下。 1、准备各种调用接口需要的参数,配置app.config

最近挺忙的,没时间写东西。然后在弄微信APP支付,网上的搜索一趟,都比较凌乱,我也遇到一些坑,不过也算弄好了,记录分享一下。

1、准备各种调用接口需要的参数,配置app.config。

<!--AppID-->
<add key="AppID" value="" />
<!--AppSecret-->
<add key="AppSecret" value="" />
<!--商户号-->
<add key="MchID" value="" />
<!--apiKey-->
<add key="APIKey" value="" />

2、调用统一下单API,直接上代码了。

	/// <summary>
    /// Builds the request.
    /// </summary>
    /// <returns></returns>
    public static string BuildRequest()
    {
        var dicParam = CreateParam();

        var signString = CreateURLParamString(dicParam);
        var preString = signString + "&key=" + ConfigHelper.APIKey;
        var sign = Sign(preString, "utf-8").ToUpper();
        dicParam.Add("sign", sign);

        return BuildFORM(dicParam);
    }    	

	/// <summary>
    /// Generates the out trade no.
    /// </summary>
    /// <returns></returns>
    private static string GenerateOutTradeNo()
    {
        var ran = new Random();
        return $"{ConfigHelper.MchID}{DateTime.Now:yyyyMMddHHmmss}{ran.Next(999)}";
    }

	/// <summary>
    /// Signs the specified prestr.
    /// </summary>
    /// <param name="prestr">The prestr.</param>
    /// <param name="_input_charset">The input charset.</param>
    /// <returns></returns>
    private static string Sign(string prestr, string _input_charset)
    {
        var sb = new StringBuilder(32);
        MD5 md5 = new MD5CryptoServiceProvider();
        var t = md5.ComputeHash(Encoding.GetEncoding(_input_charset).GetBytes(prestr));
        foreach (var t1 in t)
        {
            sb.Append(t1.ToString("x").PadLeft(2, '0'));
        }

        return sb.ToString();
    }

	/// <summary>
    /// Creates the parameter.
    /// </summary>
    /// <returns></returns>
    private static SortedDictionary<string, string> CreateParam()
    {
        const string amount = "1";
        double dubamount;
        double.TryParse(amount, out dubamount);
        var notify_url = ConfigHelper.WEBSiteUrl + "/api/v1/testWeiXin"; //支付完成后的回调处理页面
        const string detail = "xxxx";

        var dic = new SortedDictionary<string, string>
        {
            {"appid", ConfigHelper.AppID},//账号ID
            {"mch_id", ConfigHelper.MchID},//商户号
            {"nonce_str", Guid.NewGuid().ToString().Replace("-", "")},//随机字符串
            {"body", detail}, //商品描述
            {"out_trade_no", GenerateOutTradeNo()},//商户订单号
            {"total_fee", (dubamount * 100).ToString(CultureInfo.InvariantCulture)},//总金额
            {"spbill_create_ip", GeneralHelper.GetIP()},//终端IP
            {"notify_url", notify_url},//通知地址
            {"trade_type", "APP"}//交易类型
        };
                      
        return dic;
    }

	/// <summary>
    /// Creates the URL parameter string.
    /// </summary>
    /// <param name="dicArray">The dic array.</param>
    /// <returns></returns>
    private static string CreateURLParamString(SortedDictionary<string, string> dicArray)
    {
        var prestr = new StringBuilder();
        foreach (var temp in dicArray.OrderBy(o => o.Key))
        {
            prestr.Append(temp.Key + "=" + temp.Value + "&");
        }

        var nLen = prestr.Length;
        prestr.Remove(nLen - 1, 1);
        return prestr.ToString();
    }

	/// <summary>
    /// Builds the form.
    /// </summary>
    /// <param name="dicParam">The dic parameter.</param>
    /// <returns></returns>
    private static string BuildForm(SortedDictionary<string, string> dicParam)
    {
        var sbXML = new StringBuilder();
        sbXML.Append("<xml>");
        foreach (var temp in dicParam)
        {
            sbXML.Append("<" + temp.Key + ">" + temp.Value + "</" + temp.Key + ">");
        }

        sbXML.Append("</xml>");
        return sbXML.ToString();
    }

	/// <summary>
    /// Froms the XML.
    /// </summary>
    /// <param name="xml">The XML.</param>
    /// <returns></returns>
    /// <exception cref="Exception">将空的xml串转换为WxPayData不合法!</exception>
    public static SortedDictionary<string, string> FromXml(string xml)
    {
        var sortDic = new SortedDictionary<string, string>();
        if (string.IsNullOrEmpty(xml))
        {
            throw new Exception("将空的xml串转换为WxPayData不合法!");
        }

        var xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(xml);
        var xmlnode = xmlDoc.FirstChild;//获取到根节点<xml>
        var nodes = xmlNode.ChildNodes;
        foreach (XmlNode xn in nodes)
        {
            var xe = (XmlElement)xn;

            if (!sortDic.ContainsKey(xe.Name))
                sortDic.Add(xe.Name, xe.InnerText);
        }
        return sortDic;
    }

	/// <summary>
    /// Posts the specified URL.
    /// </summary>
    /// <param name="url">The URL.</param>
    /// <param name="content">The content.</param>
    /// <param name="contentType">Type of the content.</param>
    /// <returns></returns>
    /// <exception cref="Exception">POST请求错误" + e</exception>
    public static string Post(string url, string content, string contentType = "application/x-www-form-urlencoded")
    {
        string result;
        try
        {
            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(contentType));
                var strinGContent = new StringContent(content, Encoding.UTF8);
                var response = client.PostAsync(url, stringContent).Result;
                result = response.Content.ReadAsStringAsync().Result;
            }
        }
        catch (Exception e)
        {
            throw new Exception("POST请求错误" + e);
        }
        return result;
    }

3、生成预付订单,获取prepay_id。

	/// <summary>
    /// Gets the value from dic.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="dic">The dic.</param>
    /// <param name="key">The key.</param>
    /// <returns></returns>
    public static T GetValueFromDic<T>(IDictionary<string, string> dic, string key)
    {
        string val;
        dic.TryGetValue(key, out val);

        var returnVal = default(T);
        if (val != null)
            returnVal = (T)Convert.ChangeType(val, typeof(T));

        return returnVal;
    }

	/// <summary>
    /// Builds the application pay.
    /// </summary>
    /// <param name="prepayid">The prepayid.</param>
    /// <returns></returns>
    public static string BuildAppPay(string prepayid)
    {
        var dicParam = CreateWapAndAppPayParam(prepayid);
        var signString = CreateURLParamString(dicParam);
        var preString = signString + "&key=" + ConfigHelper.APIKey;

        var sign = Sign(preString, "utf-8").ToUpper();
        dicParam.Add("sign", sign);

        return JSONConvert.SerializeObject(
            new
            {
                appid = dicParam["appid"],
                partnerid = dicParam["partnerid"],
                prepayid = dicParam["prepayid"],
                package = dicParam["package"],
                noncestr = dicParam["noncestr"],
                timestamp = dicParam["timestamp"],
                sign = dicParam["sign"]
            });
    }

	/// <summary>
    /// Creates the wap and application pay parameter.
    /// </summary>
    /// <param name="prepayId">The prepay identifier.</param>
    /// <returns></returns>
    private static SortedDictionary<string, string> CreateWapAndAppPayParam(string prepayId)
    {
        var dic = new SortedDictionary<string, string>
        {
            {"appid", ConfigHelper.AppID},//公众账号ID
            {"partnerid", ConfigHelper.MchID},//商户号
            {"prepayid", prepayId},//预支付交易会话ID
            {"package", "Sign=WXPay"},//扩展字段
            {"noncestr", Guid.NewGuid().ToString().Replace("-", "")},//随机字符串
            {
                "timestamp",
                (Convert.ToInt32((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds)).ToString()
            }//时间戳
        };
        
        return dic;
    }

	/// <summary>
    /// Validatons the query result.
    /// </summary>
    /// <param name="dic">The dic.</param>
    /// <returns></returns>
    public static bool ValidatonQueryResult(SortedDictionary<string, string> dic)
    {
        var result = false;

        if (dic.ContainsKey("return_code") && dic.ContainsKey("return_code"))
        {
            if (dic["return_code"] == "SUCCESS" && dic["result_code"] == "SUCCESS")
                result = true;
        }

        if (result) return true;

        var sb = new StringBuilder();
        foreach (var item in dic.Keys)
        {
            sb.Append(item + ":" + dic[item] + "|");
        }

        return false;
    }

4、调用获取支付信息,给到APP发起支付操作。

		var requestXml = WeiXinUtil.BuildRequest();
        var resultXml = WeiXinUtil.Post("https://api.mch.weixin.qq.com/pay/unifiedorder", requestXml);

        var dic = WeiXinUtil.FromXml(resultXml);

        string returnCode;
        dic.TryGetValue("return_code", out returnCode);

        if (returnCode == "SUCCESS")
        {
            var prepay_id = WeiXinUtil.GetValueFromDic<string>(dic, "prepay_id");
            if (!string.IsNullOrEmpty(prepay_id))
            {
                var payInfo = jsonConvert.DeserializeObject<WeiXinUtil.WxPayModel>(WeiXinUtil.BuildAppPay(prepay_id));

                json.Add(new JProperty("appid", payInfo.appid));
                json.Add(new JProperty("partnerid", payInfo.partnerid));
                json.Add(new JProperty("prepayid", payInfo.prepayid));
                json.Add(new JProperty("package", payInfo.package));
                json.Add(new JProperty("noncestr", payInfo.noncestr));
                json.Add(new JProperty("timestamp", payInfo.timestamp));
                json.Add(new JProperty("sign", payInfo.sign));
                json.Add(new JProperty("code", 0));
                json.Add(new JProperty("msg", "成功"));
                return this.Jsonp(json.ToString());
            }
            else
            {
                json.Add(new JProperty("code", 40028));
                json.Add(new JProperty("msg", "支付错误:" + WeiXinUtil.GetValueFromDic<string>(dic, "err_code_des")));
                return this.Jsonp(json.ToString());
            }
        }
        else
        {
            return this.Jsonp(ApiException.OrderFailed());
        }

5、APP支付完成,获得回调信息,就OK了。

		var context = this.HttpContext;
        var request = context.Request;
        var verifyResult = false;
        var requestXml = WeiXinUtil.GetRequestXmlData(request);
        var dic = WeiXinUtil.FromXml(requestXml);
        var returnCode = WeiXinUtil.GetValueFromDic<string>(dic, "return_code");

        if (!string.IsNullOrEmpty(returnCode) && returnCode == "SUCCESS")//通讯成功
        {
            var result = WeiXinUtil.WePayNotifyValidation(dic);
            if (result)
            {
                var transactionid = WeiXinUtil.GetValueFromDic<string>(dic, "transaction_id");

                if (!string.IsNullOrEmpty(transactionid))
                {
                    var queryXml = WeiXinUtil.BuildQueryRequest(transactionid, dic);
                    var queryResult = WeiXinUtil.Post("https://api.mch.weixin.qq.com/pay/orderquery", queryXml);
                    var queryReturnDic = WeiXinUtil.FromXml(queryResult);

                    if (WeiXinUtil.ValidatonQueryResult(queryReturnDic))//查询成功
                    {
                        verifyResult = true;
                        var status = WeiXinUtil.GetValueFromDic<string>(dic, "result_code");

                        if (!string.IsNullOrEmpty(status) && status == "SUCCESS")
                        {
                            var order = new Order()
                            {
                                OrderNumber = WeiXinUtil.GetValueFromDic<string>(dic, "out_trade_no"),
                                TransactionId = transactionid,
                                ProductPrice = WeiXinUtil.GetValueFromDic<decimal>(dic, "total_fee") / 100,
                                TradeType = WeiXinUtil.GetValueFromDic<string>(dic, "trade_type"),
                                BankType = WeiXinUtil.GetValueFromDic<string>(dic, "bank_type"),
                                PayDate = DateTime.Parse(WeiXinUtil.GetValueFromDic<string>(dic, "time_end")),
                                StatusId = 1,
                                IsPresent = false,
                                ADDDate = DateTime.Now,
                                IsDelete = false
                            };

                            CURD.Add(order, ConfigHelper.WriteDB);

                            WeiXinUtil.BuildReturnXml("OK", "成功");
                        }
                    }
                    else
                        WeiXinUtil.BuildReturnXml("FAIL", "订单查询失败");
                }
                else
                    WeiXinUtil.BuildReturnXml("FAIL", "支付结果中微信订单号不存在");
            }
            else
                WeiXinUtil.BuildReturnXml("FAIL", "签名失败");
        }
        else
        {
            string returnmsg;
            dic.TryGetValue("return_msg", out returnmsg);
            throw new Exception("异步通知错误:" + returnmsg);
        }

        return verifyResult;

	/// <summary>
    /// Gets the request XML data.
    /// </summary>
    /// <param name="request">The request.</param>
    /// <returns></returns>
    public static string GetRequestXmlData(HttpRequestBase request)
    {
        var stream = request.InputStream;
        int count;
        var buffer = new byte[1024];
        var builder = new StringBuilder();
        while ((count = stream.Read(buffer, 0, 1024)) > 0)
        {
            builder.Append(Encoding.UTF8.GetString(buffer, 0, count));
        }
        stream.Flush();
        stream.Close();

        return builder.ToString();
    }

    /// <summary>
    /// Wes the pay notify validation.
    /// </summary>
    /// <param name="dic">The dic.</param>
    /// <returns></returns>
    public static bool WePayNotifyValidation(SortedDictionary<string, string> dic)
    {
        var sign = GetValueFromDic<string>(dic, "sign");
        if (dic.ContainsKey("sign"))
        {
            dic.Remove("sign");
        }

        var tradeType = GetValueFromDic<string>(dic, "trade_type");
        var preString = CreateURLParamString(dic);

        if (string.IsNullOrEmpty(tradeType))
        {
            var preSignString = preString + "&key=" + ConfigHelper.APIKey;
            var signString = Sign(preSignString, "utf-8").ToUpper();
            return signString == sign;
        }
        else
            return false;
    }

	/// <summary>
    /// Builds the query request.
    /// </summary>
    /// <param name="transactionId">The transaction identifier.</param>
    /// <param name="dic">The dic.</param>
    /// <returns></returns>
    public static string BuildQueryRequest(string transactionId, SortedDictionary<string, string> dic)
    {
        var dicParam = CreateQueryParam(transactionId);
        var signString = CreateURLParamString(dicParam);
        var key = ConfigHelper.APIKey;
        var preString = signString + "&key=" + key;
        var sign = Sign(preString, "utf-8").ToUpper();
        dicParam.Add("sign", sign);

        return BuildForm(dicParam);
    }

    /// <summary>
    /// Creates the query parameter.
    /// </summary>
    /// <param name="transactionId">The transaction identifier.</param>
    /// <returns></returns>
    private static SortedDictionary<string, string> CreateQueryParam(string transactionId)
    {
        var dic = new SortedDictionary<string, string>
        {
            {"appid", ConfigHelper.AppID},//公众账号ID
            {"mch_id", ConfigHelper.MchID},//商户号
            {"nonce_str", Guid.NewGuid().ToString().Replace("-", "")},//随机字符串
            {"transaction_id", transactionId}//微信订单号
        };
        return dic;
    }

	/// <summary>
    /// Builds the return XML.
    /// </summary>
    /// <param name="code">The code.</param>
    /// <param name="returnMsg">The return MSG.</param>
    /// <returns></returns>
    public static string BuildReturnXml(string code, string returnMsg)
    {
        return
            $"<xml><return_code><![CDATA[[code]]]></return_code><return_msg><![CDATA[{returnMsg}]]></return_msg></xml>";
    }

6、总结:这个可以直接拿来用了,反反复复测试了很多遍,遇到的问题有关于钱,还有签名的问题,调试都解决了。继续解决问题,积累经验。

到此这篇关于asp.net项目中实现微信APP支付功能的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: ASP.Net项目中实现微信APP支付功能

本文链接: https://lsjlt.com/news/165056.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • ASP.Net项目中实现微信APP支付功能
    最近挺忙的,没时间写东西。然后在弄微信APP支付,网上的搜索一趟,都比较凌乱,我也遇到一些坑,不过也算弄好了,记录分享一下。 1、准备各种调用接口需要的参数,配置app.config...
    99+
    2024-04-02
  • vue项目中的支付功能实现(微信支付和支付宝支付)
    目录项目中常见的支付方式    支付宝支付微信支付项目中常见的支付方式     支付宝支付  &nbs...
    99+
    2024-04-02
  • PHP实现 APP端微信支付功能
    一丶 PHP后台生成预支付交易单,返回正确的预支付交易回话标识后 调起支付,根据文档拼接微信需要的参数,这里将需要的几个方法进行示例; 传输给微信的参数要组装成xml格式发送,传如参数数组! publ...
    99+
    2023-10-18
    php 微信 android
  • 如何进行vue项目中的支付功能实现(微信支付和支付宝支付)
    如何进行vue项目中的支付功能实现(微信支付和支付宝支付),针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。项目中常见的支付方式    支付宝支付...
    99+
    2023-06-22
  • php实现微信支付功能
    一、生成预支付订单并获取预支付ID(prepay_id): ...
    99+
    2023-09-11
    php
  • Android中怎么实现微信支付功能
    Android中怎么实现微信支付功能,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。 去微信开放平台申请微信支付服务,绑定自己的应用这里具体不多讲,但是一定要申请完成,将会得到是...
    99+
    2023-05-31
    android
  • python3wechatpy微信支付的项目实践
    目录1.公众号申请及配置流程2.python wechatpy操作记录一下微信支付整个流程 1.公众号申请及配置流程 使用微信支付的前提是必须要有公众号。 申请链接: 微信公众号申请...
    99+
    2023-01-18
    python3 wechatpy微信支付 python3 微信支付
  • 怎么用Java也实现微信和支付宝支付功能
    这篇文章主要介绍“怎么用Java也实现微信和支付宝支付功能”,在日常操作中,相信很多人在怎么用Java也实现微信和支付宝支付功能问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”...
    99+
    2024-04-02
  • 微信支付,JSAPI支付,APP支付,H5支付,Native支付,小程序支付功能详情以及回调处理
    一.支付相关文档地址 支付wiki: https://pay.weixin.qq.com/wiki/doc/apiv3/index.shtml 支付api: https://pay.weixin.qq.com/wiki/...
    99+
    2023-09-20
    微信 小程序 微信小程序 微信支付 Powered by 金山文档
  • UniApp + SpringBoot 实现微信支付和退款功能
    目录开发准备微信支付开发后端部分前端部分开发准备 一台用于支付的测试机,必须得是一个安卓机因为需要打支付基座才能使用。用于编写的后端框架接口的 IDE (IDEA 或者 Eclips...
    99+
    2024-04-02
  • 微信小程序支付功能如何实现
    这篇文章主要介绍了微信小程序支付功能如何实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇微信小程序支付功能如何实现文章都会有所收获,下面我们一起来看看吧。微信小程序支付功能开发文档如下:小程序端,保留大部分的...
    99+
    2023-06-26
  • 微信小程序支付功能怎么实现
    实现微信小程序支付功能,需要以下步骤:1. 首先,在微信公众平台申请开通支付功能,并获取到支付相关的配置信息,包括 appID、商户...
    99+
    2023-08-16
    微信小程序
  • Android开发微信APP支付功能的要点小结
    基本概念 包名值得是你APP的包,在创建工程时候设置的,需要在微信支付平台上面设置。 签名指的是你生成APK时候所用的签名文件的md5,去掉:全部小写,需要在微信支付平台上面设...
    99+
    2022-06-06
    小结 android开发 app 微信app 微信app支付 Android
  • Android集成微信支付功能
    准备工作这里就不说了,包括签约和申请APPID,附上微信开放平台APP开发步骤,不懂的同学可以参考这里: https://pay.weixin.qq.com/wiki/doc/...
    99+
    2022-06-06
    微信支付 Android
  • iOS APP实现微信H5支付示例总结
    微信H5支付流程 发起下单请求(调用统一下单接口)注:交易类型trade_type=MWEB 统一下单接口返回支付相关参数给商户后台,如支付跳转url(参数名“mweb_url”)...
    99+
    2022-05-27
    iOS 微信支付 H5支付
  • SpringBoot + 微信公众号JSAPI支付功能的实现
    1、pom.xml依赖配置 <!-- 微信支付 --> <dependency> <groupId>com.egzosn</grou...
    99+
    2024-04-02
  • PHP实现微信支付流程(Native支付)
    最近项目需要做微信支付的功能,想着把流程以及遇到的坑记录下来 1.到微信商户平台中去开通Native支付(产品中心-Native支付-申请开通) 2.微信商户平台中下载证书以及设置api密钥(账户中心-api安全),查看指引中很详细的说...
    99+
    2023-08-31
    php 微信 Powered by 金山文档
  • 利用golang怎么实现一个微信支付功能
    本文章向大家介绍利用golang怎么实现一个微信支付功能的基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。golang的优点有哪些golang是一种编译语言,可以将代码编译为机器代码,编译后的二进制文件可以直接部署...
    99+
    2023-06-06
  • 小程序发起微信支付功能怎么实现
    这篇文章主要讲解了“小程序发起微信支付功能怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“小程序发起微信支付功能怎么实现”吧!wx.requestPayment(OBJECT)发起微信...
    99+
    2023-06-26
  • 怎么用PHP实现支付宝和微信扫码在线支付的功能
    本篇内容介绍了“怎么用PHP实现支付宝和微信扫码在线支付的功能”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作