好烟
好烟
  • 发布:2015-07-10 12:26
  • 更新:2019-08-24 14:14
  • 阅读:37597

微信支付服务端代码 .net C# MVC

分类:HTML5+

研究了很多demo示例,最后整理出了如下的.net MVC版本的微信支付服务端代码,亲测可行,服务端所需要的其他类文件我已经打包存附件了,需要的可以下载使用
以下只实现了基础功能,如果有什么问题还请大神们多多指教。

服务端代码:

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Web;  
using System.Web.Mvc;  
using WeddingCarService.Models;  
using Newtonsoft.Json;  
using System.Text;  
using System.Xml;  
using System.Collections;  
using System.Text.RegularExpressions;  
using System.Reflection;  
using WxPayAPI;  
using WeddingCarService.WXPay;  

namespace WeddingCarService.Controllers  
{  
    public class Wx_Pay_Model  
    {  
        public int retcode { get; set; }  
        public string retmsg { get; set; }  
        public string appid { get; set; }  
        public string noncestr { get; set; }  
        public string package { get; set; }  
        public string partnerid { get; set; }  
        public string prepayid { get; set; }  
        public string timestamp { get; set; }  
        public string sign { get; set; }  
    }  
    public class wxPayController : Controller  
    {  

        public static string mchid = "11111"; //mchid  
        public static string appId = "11111"; //appid  
        public static string appsecret = "11111"; //appsecret  
        public static string appkey = "11111"; //paysignkey(非appkey 在微信商户平台设置 (md5)111111111111)    
        public static string notify_url = Common.CommonDefine.ServerPath + "/wxpay/wxtNotify"; //支付完成后的回调处理页面  
        //  
        // GET: /wxPay/  

        public ActionResult Index()  
        {  
            return View();  
        }  

        /// <summary>  
        /// 微信支付主体接口  
        /// </summary>  
        /// <returns></returns>  
        public ActionResult wxpay()  
        {  
            //************************************************支付参数接收********************************  
            ///获取金额  
            string amount = Request.QueryString["_amount"];  
            string sp_billno = string.IsNullOrEmpty(Request.QueryString["_orderid"]) ? DateTime.Now.ToString("yyyyMMddhhmmssffff") : Request.QueryString["_orderid"];  
            string detail = Request.QueryString["_detail"];  
            double dubamount;  
            double.TryParse(amount, out dubamount);  
            //根据appid和appappsecret获取refresh_token  
            //string url_token = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", appId, appsecret);  
            //string returnStr = tokenservice.GetToken(appId, appsecret);  
            //时间戳  
            var timeStamp = TenpayUtil.getTimestamp();  
            //随机验证码  
            var nonceStr = TenpayUtil.getNoncestr();  

            //****************************************************************获取预支付订单编号***********************  
            //设置package订单参数  
            Hashtable packageParameter = new Hashtable();  
            packageParameter.Add("appid", appId);//开放账号ID    
            packageParameter.Add("mch_id", mchid); //商户号  
            packageParameter.Add("nonce_str", nonceStr); //随机字符串  
            packageParameter.Add("body", detail); //商品描述      
            packageParameter.Add("out_trade_no", sp_billno); //商家订单号   
            packageParameter.Add("total_fee", (dubamount*100).ToString()); //商品金额,以分为单位      
            packageParameter.Add("spbill_create_ip", Request.UserHostAddress); //订单生成的机器IP,指用户浏览器端IP    
            packageParameter.Add("notify_url", notify_url); //接收财付通通知的URL    
            packageParameter.Add("trade_type", "APP");//交易类型    
            packageParameter.Add("fee_type", "CNY"); //币种,1人民币   66    
            //获取签名  
            var sign = CreateMd5Sign("key", appkey, packageParameter, Request.ContentEncoding.BodyName);  
            //拼接上签名  
            packageParameter.Add("sign", sign);  
            //生成加密包的XML格式字符串  
            string data = parseXML(packageParameter);  
            //调用统一下单接口,获取预支付订单号码  
            string prepayXml = HttpUtil.Send(data, "https://api.mch.weixin.qq.com/pay/unifiedorder");  

            //获取预支付ID  
            var prepayId = string.Empty;  
            var xdoc = new XmlDocument();  
            xdoc.LoadXml(prepayXml);  
            XmlNode xn = xdoc.SelectSingleNode("xml");  
            XmlNodeList xnl = xn.ChildNodes;  
            if (xnl.Count > 7)  
            {  
                prepayId = xnl[7].InnerText;  
            }  

            //**************************************************封装调起微信客户端支付界面字符串********************  
            //设置待加密支付参数并加密  
            Hashtable paySignReqHandler = new Hashtable();  
            paySignReqHandler.Add("appid", appId);  
            paySignReqHandler.Add("partnerid", mchid);  
            paySignReqHandler.Add("prepayid", prepayId);  
            paySignReqHandler.Add("package", "Sign=WXPay");  
            paySignReqHandler.Add("noncestr", nonceStr);  
            paySignReqHandler.Add("timestamp", timeStamp);  
            var paySign = CreateMd5Sign("key", appkey, paySignReqHandler, Request.ContentEncoding.BodyName);  

            //设置支付包参数  
            Wx_Pay_Model wxpaymodel = new Wx_Pay_Model();  
            wxpaymodel.retcode = 0;//5+固定调起参数  
            wxpaymodel.retmsg = "ok";//5+固定调起参数  
            wxpaymodel.appid = appId;//AppId,微信开放平台新建应用时产生  
            wxpaymodel.partnerid = mchid;//商户编号,微信开放平台申请微信支付时产生  
            wxpaymodel.prepayid = prepayId;//由上面获取预支付流程获取  
            wxpaymodel.package = "Sign=WXpay";//APP支付固定设置参数  
            wxpaymodel.noncestr = nonceStr;//随机字符串,  
            wxpaymodel.timestamp = timeStamp;//时间戳  
            wxpaymodel.sign = paySign;//上面关键参数加密获得  
            //将参数对象直接返回给客户端  
            return Json(new { msg = "", result = wxpaymodel }, JsonRequestBehavior.AllowGet);  
        }  

        /// <summary>  
        /// 将类对象拼接成调起支付字符串  
        /// </summary>  
        /// <param name="_model"></param>  
        /// <returns></returns>  
        private string ReSetPayString(Wx_Pay_Model _model)  
        {  
            StringBuilder strpay = new StringBuilder();  
            PropertyInfo[] props = _model.GetType().GetProperties();  
            strpay.Append("{");  
            foreach (PropertyInfo property in props)  
            {  
                strpay.Append(property.Name + ":\""+property.GetValue(_model, null).ToString()+"\",");  
            }  
            strpay.Remove(strpay.Length - 1, 1);  
            strpay.Append("}");  
            return strpay.ToString();  
        }  

        /// <summary>  
        /// 输出XML  
        /// </summary>  
        /// <returns></returns>  
        public string parseXML(Hashtable _parameters)  
        {  
            var sb = new StringBuilder();  
            sb.Append("<xml>");  
            var akeys = new ArrayList(_parameters.Keys);  
            foreach (string k in akeys)  
            {  
                var v = (string)_parameters[k];  
                if (Regex.IsMatch(v, @"^[0-9.]$"))  
                {  
                    sb.Append("<" + k + ">" + v + "</" + k + ">");  
                }  
                else  
                {  
                    sb.Append("<" + k + "><![CDATA[" + v + "]]></" + k + ">");  
                }  
            }  
            sb.Append("</xml>");  
            return sb.ToString();  
        }  

        /// <summary>  
        /// 创建package签名  
        /// </summary>  
        /// <param name="key">密钥键</param>  
        /// <param name="value">财付通商户密钥(自定义32位密钥)</param>  
        /// <returns></returns>  
        public virtual string CreateMd5Sign(string key, string value, Hashtable parameters, string _ContentEncoding)  
        {  
            var sb = new StringBuilder();  
            //数组化键值对,并排序  
            var akeys = new ArrayList(parameters.Keys);  
            akeys.Sort();  
            //循环拼接包参数  
            foreach (string k in akeys)  
            {  
                var v = (string)parameters[k];  
                if (null != v && "".CompareTo(v) != 0  
                    && "sign".CompareTo(k) != 0 && "key".CompareTo(k) != 0)  
                {  
                    sb.Append(k + "=" + v + "&");  
                }  
            }  
            //最后拼接商户自定义密钥  
            sb.Append(key + "=" + value);  
            //加密  
            string sign = MD5Util.GetMD5(sb.ToString(), _ContentEncoding).ToUpper();  
            //返回密文  
            return sign;  
        }  

        /// <summary>  
        /// 日志记录工具类  
        /// </summary>  
        /// <param name="pathWrite"></param>  
        /// <param name="content"></param>  
        public static void WriteFile(string pathWrite, string content)  
        {  
            try  
            {  
                if (System.IO.File.Exists(pathWrite))  
                {  
                    //System.IO.File.Delete(pathWrite);  
                }  
                else  
                {  
                    System.IO.File.Create(pathWrite);  
                }  
                System.IO.File.AppendAllText(pathWrite, content + "\r\n----------------------------------------\r\n",  
                    Encoding.GetEncoding("utf-8"));  
            }  
            catch (Exception e)  
            {  

            }  
        }  

        /// <summary>  
        /// 微信支付异步回调方法  
        /// </summary>  
        /// <returns></returns>  
        public ActionResult wxtNotify()  
        {  
            ResultNotify resultNotify = new ResultNotify(Request);  
            resultNotify.ProcessNotify();  
            return Json(new { msg = "成功" }, JsonRequestBehavior.AllowGet);  
        }  
    }  
}  

客户端代码:  
<!DOCTYPE html>  
<html>  

    <head>  
        <meta charset="utf-8">  
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />  
        <title></title>  
        <script src="js/mui.min.js"></script>  
        <link href="css/mui.min.css" rel="stylesheet" />  
        <script type="text/javascript" charset="utf-8">  
            mui.init();  
            var channel = null;  
            var channels = null;  
             // 1. 获取支付通道  
            function plusReady() {  
                // 获取支付通道  
                plus.payment.getChannels(function(cs) {  
                    channels = cs;  
                }, function(e) {  
                    alert("获取支付通道失败:" + e.message);  
                });  
            }  
            document.addEventListener('plusready', plusReady, false);  
            var ALIPAYSERVER = 'http://demo.dcloud.net.cn/helloh5/payment/alipay.php?total=';  
            var WXPAYSERVER = 'http://192.168.3.141/wxPay/wxpay';  
            /*var WXPAYSERVER = 'http://demo.dcloud.net.cn/payment/?payid=wxpay&appid=HBuilder&total=1';*/  
             // 2. 发起支付请求  
            function pay(id) {  
                // 从服务器请求支付订单  
                var PAYSERVER = '';  
                if (id == 'alipay') {  
                    PAYSERVER = ALIPAYSERVER;  
                } else if (id == 'wxpay') {  
                    PAYSERVER = WXPAYSERVER;  
                } else {  
                    plus.nativeUI.alert("不支持此支付通道!", null, "捐赠");  
                    return;  
                }  
                //获取支付通道  
                for (var i in channels) {  
                    if (channels[i].id == id) {  
                        channel = channels[i];  
                    }  
                }  
                mui.get(PAYSERVER, {  
                    _amount: 1,  
                    _orderid: "",  
                    _detail: "测试微信支付"  
                }, function(data) {  
                    var varpay = {  
                        retcode: 0,  
                        retmsg: "ok",  
                        appid: data.result.appid,  
                        noncestr: data.result.noncestr,  
                        package: "Sign=WXPay",  
                        partnerid: data.result.partnerid,  
                        prepayid: data.result.prepayid,  
                        timestamp: data.result.timestamp,  
                        sign: data.result.sign  
                    }  
                    plus.payment.request(channel, varpay, function(result) {  
                        plus.nativeUI.alert("支付成功!", function() {  
                            back();  
                        });  
                    }, function(e) {  
                        plus.nativeUI.alert("支付失败:" + e.code + "支付失败:" + e.message);  
                        console.log(e.code);  
                        console.log(e.message);  
                    });  
                }, "json");  
                var xhr = new XMLHttpRequest();  
                xhr.onreadystatechange = function() {  
                        switch (xhr.readyState) {  
                            case 4:  
                                if (xhr.status == 200) {  
                                    alert(xhr.result);  
                                    plus.payment.request(channel, xhr.result, function(result) {  
                                        plus.nativeUI.alert("支付成功!", function() {  
                                            back();  
                                        });  
                                    }, function(error) {  
                                        plus.nativeUI.alert("支付失败:" + error.code);  
                                    });  
                                } else {  
                                    alert("获取订单信息失败!");  
                                }  
                                break;  
                            default:  
                                break;  
                        }  
                    }  
                    /*          xhr.open('GET',PAYSERVER);  
                                xhr.send();*/  
            }  
        </script>  
    </head>  

    <body>  
        <header class="mui-bar mui-bar-nav">  
            <a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a>  
            <h1 class="mui-title">支付测试</h1>  
        </header>  
        <div class="mui-content">  
            <input type="button" class="btn btn-lg" id="pay" value="pay" onclick="pay('wxpay')" />  
        </div>  

    </body>  

</html>
15 关注 分享
小菜鸟 AsakoStudio Fun JL G_jia 臭皮匠娃娃 5675557 Trust 陈太初 安之若素 3***@qq.com 8***@qq.com ikballsoft w***@163.com 8***@qq.com

要回复文章请先登录注册

1***@qq.com

1***@qq.com

string prepayXml = HttpUtil.Send(data, "https://api.mch.weixin.qq.com/pay/unifiedorder");
HttpUtil怎么定义?
2019-08-24 14:14
3***@qq.com

3***@qq.com

支付 net 做后台
2019-08-18 16:46
2***@qq.com

2***@qq.com

樓主的這個支付代碼,現在還可以用嗎?我配置都沒問題,用樓主的代碼一直提示簽名錯誤,求幫忙!
2018-12-14 15:53
c***@163.com

c***@163.com

public static string notify_url = Common.CommonDefine.ServerPath + "/wxpay/wxtNotify" Common.CommonDefine.ServerPath 应该怎么定义?
2018-08-31 13:51
太2真人

太2真人

好人拿
2018-05-29 16:49
Lspring

Lspring

谢谢楼主了,我的问题也是后台的问题,终于解决了。(楼主的头像和我微信的头像一样,哈哈)
2018-05-03 12:47
安之若素

安之若素

你好,我用你的办法老是报-100的错误。但我第一次请求的时候支付成功了,然后之后就不行了,请问这是什么原因?
2017-04-10 09:09
炸鸡排超人

炸鸡排超人

回复 小菜鸟 :
还有那种方式..不都一样的么
2017-01-10 09:09
好烟

好烟 (作者)

回复 大嘴巴 :
前面错误了就检查签名呀,微信支付签名大概有两块块:微信商户平台上的公钥和私钥(服务端使用);微信开发平台上配置的apk包签名(由apk包解析可以获取到,前端使用);
2016-06-12 13:41
大嘴巴

大嘴巴

回复 Yiso丶 :
你好,现在我也在开发安卓app微信支付,请问签名错误这个问题解决了吗?我现在也是遇到同样的问题,可以和我分享一下吗?谢谢,万分感激,我的QQ940353000,如果可以的话,麻烦加下我的qq,谢谢
2016-06-10 11:21