• c# 微信开发 《微信支付》


    首先要理解微信支付的流程。需二次握手。

    先把订单信息,金额传给微信,微信返回相应信息,再调用微信支付。

     详细的查看微信公众号的相关资料

     /// <summary>
            /// 新建一个普通订单
            /// </summary>
            /// <returns></returns>
            public Entity NewOrder(Entity en)
            {
                string WeiXinOpenID = en.GetValue("WeiXinOpenID").TryString();
                string AddressID = en.GetValue("AddressID").TryString();
                string OrderMessage = en.GetValue("OrderMessage").TryString();
                int OrderStatus = (int)OrderEnum.OrderStatus.待付款;
                string CommodityList = en.GetValue("CommodityList").TryString();
                string CouponRecordGuid = en.GetValue("CouponRecordGuid").TryString(); //优惠券
                decimal ManorMoney = en.GetValue("ManorMoney").TryDecimal(); //庄园币
     
                string OrderGuid = System.Guid.NewGuid().ToString();
                try
                {
                    using (System.Transactions.TransactionScope scope = new System.Transactions.TransactionScope())
                    {
                     
    
                        #region 支付信息
                        string PayRecordID = System.Guid.NewGuid().TryString();
                        int PayStatus = (int)OrderEnum.PayStatus.未支付;
                        string OrderNum = OrderServiceDA.NewOrder(OrderGuid, WeiXinOpenID, AddressID, OriginalTotalPrice, SaleTotalPrice, OrderMessage, OrderStatus);
    
                        //添加支付记录
                        OrderServiceDA.AddPayRecord(PayRecordID, SaleTotalPrice, WeiXinOpenID, OrderGuid, PayStatus);
         
    
    
                        decimal WeixinPayMoney = SaleTotalPrice - (ManorMoney + Couponvalue);
                        if (WeixinPayMoney > 0)
                        {
                            int PayType = (int)OrderEnum.PayType.微信支付;
                            OrderServiceDA.AddPayRecordWeixinDetail(PayRecordID, PayType, WeixinPayMoney, PayStatus);
                            OrderServiceDA.UpdatePayRecordPayType(PayRecordID, PayType);
                            WeixinPayService WeixinPayService = new WeixinPayService();
                            PaymentData payData = new PaymentData();
                            payData.SetValue("attach", OrderNum);
                            payData.SetValue("body", "微信在线支付");
                            payData.SetValue("out_trade_no", OrderNum);
                            payData.SetValue("trade_type", "JSAPI");
                            payData.SetValue("total_fee", (WeixinPayMoney * 100).ToInt32());//付款金额,单位分
                            payData.SetValue("openid", WeiXinOpenID);
                            PaymentData returnData = WeixinPayService.UnifiedOrder(payData);
    
                            string prepay_id = "";
                            string SignKey = "";
                            string TimeStamp = "";
                            string NonceStr = "";
                            string returnCode = returnData.GetValue("return_code").ToString();
                            if (returnCode.ToUpper().Equals("SUCCESS"))
                            {
                                #region 获取支付签名
                                //获取支付ID
                                prepay_id = returnData.GetValue("prepay_id").ToString();
                                PaymentData jsApiParam = new PaymentData();
                                NonceStr = WeixinPayService.GenerateNonceStr();
                                TimeStamp = WeixinPayService.GenerateTimeStamp();
                                jsApiParam.SetValue("appId", WeixinPayService.AppId);
                                jsApiParam.SetValue("timeStamp", TimeStamp);
                                jsApiParam.SetValue("nonceStr", NonceStr);
                                jsApiParam.SetValue("package", "prepay_id=" + prepay_id);
                                jsApiParam.SetValue("signType", "MD5");
                                SignKey = jsApiParam.MakeSign(WeixinPayService.SignKey);
                                #endregion
                            }
                            else
                            {
                                string ErrorMessage = returnData.GetValue("return_msg").ToString();
                                FaultException exception = new FaultException(ErrorMessage);
                                throw (exception);
                            }
                   //保存信息,用于前端再进行调起支付。 OrderServiceDA.UpdateWeixinPayRecord(PayRecordID, prepay_id, SignKey, TimeStamp, NonceStr); } else { if (ManorMoney == 0) { int PayType = (int)OrderEnum.PayType.优惠券; OrderServiceDA.UpdatePayRecordPayType(PayRecordID, PayType); } else { int PayType = (int)OrderEnum.PayType.庄园币; OrderServiceDA.UpdatePayRecordPayType(PayRecordID, PayType); } } #endregion scope.Complete(); } } catch (Exception ex) { Entity result = new Entity(new PropertyCollection()); result.AddSimple("Status", -10, typeof(int)); result.AddSimple("StatusText", ex.Message, typeof(string)); return result; } Entity resultEntity = new Entity(new PropertyCollection()); resultEntity.AddSimple("Status", 115, typeof(int)); resultEntity.AddSimple("StatusText", "操作成功.", typeof(string)); resultEntity.AddSimple("OrderGuid", OrderGuid, typeof(string)); return resultEntity; }

      

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using TalentCloud.Common;
    using TalentCloud.Base.Utils;
    using TalentCloud.Agriculture.Services;
    using System.Security.Cryptography;
    using System.IO;
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    using TalentCloud.Common.Log;
    
    namespace TalentCloud.Agriculture.Weixin.Services
    {
        public class WeixinPayService
        {
            /// <summary>
            /// 微信分配的AppId
            /// </summary>
            public string AppId = TCConfigManager.GetConfig("WeixinPayAppid").TryToString();
            /// <summary>
            /// 公众号的支付密钥appsecret
            /// </summary>
            public string AppSecret = TCConfigManager.GetConfig("WeixinPayAppsecret").TryToString();
            /// <summary>
            /// 当前用户IP
            /// </summary>
            public string Ip = WCFClientInfo.ClientIP;
            /// <summary>
            /// 商户号
            /// </summary>
            public string MchId = TCConfigManager.GetConfig("MchId").TryToString();
            /// <summary>
            /// 签名Key
            /// </summary>
            public string SignKey = TCConfigManager.GetConfig("SignKey").TryToString();
            //=======【证书路径设置】===================================== 
            /* 证书路径,注意应该填写绝对路径(仅退款、撤销订单时需要)
            */
            public string CertPath = TCConfigManager.GetConfig("certPath").TrySafeString();
            /// <summary>
            /// 证书密码,windows上可以直接双击导入系统,导入过程中会提示输入证书密码,证书密码默认为您的商户ID
            /// </summary>
            public string CertPassword = TCConfigManager.GetConfig("certpsd").TrySafeString();
            /// <summary>
            /// 支付结果通知回调url,用于商户接收支付结果
            /// </summary>
            public string NOTIFY_URL =TCConfigManager.GetConfig("WebSite").TryToString()+ "/Weixin/PayCallback.aspx";
    
           
            /// <summary>
            ///   生成随机串,随机串包含字母或数字 @return 随机串
            /// </summary>
            /// <returns></returns>
            public string GenerateNonceStr()
            {
                return Guid.NewGuid().ToString().Replace("-", "");
            }
    
            /// <summary>
            /// 生成时间戳,标准北京时间,时区为东八区,自1970年1月1日 0点0分0秒以来的秒数
            /// </summary>
            /// <returns></returns>
            public string GenerateTimeStamp()
            {
                TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
                return Convert.ToInt64(ts.TotalSeconds).ToString();
            }
    
            /// <summary>
            ///  * 统一下单
            ///* @param WxPaydata inputObj 提交给统一下单API的参数
            ///* @param int timeOut 超时时间
            ///* @throws WxPayException
            ///* @return 成功时返回,其他抛异常
            /// <returns></returns>
            public PaymentData UnifiedOrder(PaymentData inputObj, int timeOut = 15)
            {
                string url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
                //检测必填参数
                if (!inputObj.IsSet("out_trade_no"))
                {
                    throw new Exception("缺少统一支付接口必填参数out_trade_no!");
                }
                else if (!inputObj.IsSet("body"))
                {
                    throw new Exception("缺少统一支付接口必填参数body!");
                }
                else if (!inputObj.IsSet("total_fee"))
                {
                    throw new Exception("缺少统一支付接口必填参数total_fee!");
                }
                else if (!inputObj.IsSet("trade_type"))
                {
                    throw new Exception("缺少统一支付接口必填参数trade_type!");
                }
    
                //关联参数
                if (inputObj.GetValue("trade_type").ToString() == "JSAPI" && !inputObj.IsSet("openid"))
                {
                    throw new Exception("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!");
                }
                if (inputObj.GetValue("trade_type").ToString() == "NATIVE" && !inputObj.IsSet("product_id"))
                {
                    throw new Exception("统一支付接口中,缺少必填参数product_id!trade_type为JSAPI时,product_id为必填参数!");
                }
    
                //异步通知url未设置,则使用配置文件中的url
                if (!inputObj.IsSet("notify_url"))
                {
                    inputObj.SetValue("notify_url", NOTIFY_URL);//异步通知url
                }
    
    
                inputObj.SetValue("appid", AppId);//公众账号ID
                inputObj.SetValue("mch_id", MchId);//商户号
                inputObj.SetValue("spbill_create_ip", Ip);//终端ip	  	    
                inputObj.SetValue("nonce_str", GenerateNonceStr());//随机字符串
                //签名
                inputObj.SetValue("sign", inputObj.MakeSign(SignKey));
                string xml = inputObj.ToXml();
                string response = HttpService.Post(xml, url, false, timeOut, "", "");
                PaymentData result = new PaymentData();
                result.FromXml(response);
                return result;
            }
    
            /// <summary>
            /// 申请退款
            /// </summary>
            /// <param name="inputObj">提交给申请退款API的参数</param>
            /// <param name="CertPath">证书路径</param>
            /// <param name="CertPassword">证书密码</param>
            /// <param name="timeOut">超时时间</param>
            /// <returns></returns>
            public PaymentData Refund(PaymentData inputObj, int timeOut = 6)
            {
                string url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
                //检测必填参数
                if (!inputObj.IsSet("out_trade_no") && !inputObj.IsSet("transaction_id"))
                {
                    throw new Exception("退款申请接口中,out_trade_no、transaction_id至少填一个!");
                }
                else if (!inputObj.IsSet("out_refund_no"))
                {
                    throw new Exception("退款申请接口中,缺少必填参数out_refund_no!");
                }
                else if (!inputObj.IsSet("total_fee"))
                {
                    throw new Exception("退款申请接口中,缺少必填参数total_fee!");
                }
                else if (!inputObj.IsSet("refund_fee"))
                {
                    throw new Exception("退款申请接口中,缺少必填参数refund_fee!");
                }
                else if (!inputObj.IsSet("op_user_id"))
                {
                    throw new Exception("退款申请接口中,缺少必填参数op_user_id!");
                }
    
                inputObj.SetValue("appid", AppId);//公众账号ID
                inputObj.SetValue("mch_id", MchId);//商户号
                inputObj.SetValue("nonce_str", Guid.NewGuid().ToString().Replace("-", ""));//随机字符串
                inputObj.SetValue("sign", inputObj.MakeSign(SignKey));//签名
                string xml = inputObj.ToXml();
                string response = HttpService.Post(xml, url, true, timeOut, CertPath, CertPassword);
                //将xml格式的结果转换为对象以返回
                PaymentData result = new PaymentData();
                result.FromXml(response);
                return result;
            }
    
            /// <summary>
            /// 企业付款接口( 开通条件:
            /// 1、商户号已入驻90日
            /// 2、商户号有30天连续正常交易
            /// 登录微信支付商户平台-产品中心,开通企业付款。)
            /// </summary>
            /// <param name="inputObj">参数</param>
            /// <param name="CertPath">证书路径</param>
            /// <param name="CertPassword">证书密码</param>
            /// <param name="timeOut">超时时间</param>
            /// <returns></returns>
            public PaymentData Transfers(PaymentData inputObj, int timeOut = 6)
            {
                string url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
    
                #region 检测必要参数
    
                //检测必填参数
                if (!inputObj.IsSet("partner_trade_no") && !inputObj.IsSet("partner_trade_no"))
                {
                    throw new Exception("企业付款接口中,缺少必填参数partner_trade_no!");
                }
                if (!inputObj.IsSet("openid"))
                {
                    throw new Exception("企业付款接口中,缺少必填参数openid!");
                }
                if (!inputObj.IsSet("check_name"))
                {
                    throw new Exception("企业付款接口中,缺少必填参数check_name!");
                }
                else
                {
                    string checkName = inputObj.GetValue("check_name").ToString();
                    switch (checkName)
                    {
                        case "FORCE_CHECK":
                        case "OPTION_CHECK":
                            if (!inputObj.IsSet("check_name"))
                            {
                                throw new Exception("企业付款接口中,缺少必填参数re_user_name!");
                            }
                            break;
                        default:
                            break;
                    }
                }
                if (!inputObj.IsSet("amount"))
                {
                    throw new Exception("企业付款接口中,缺少必填参数amount!");
                }
                if (!inputObj.IsSet("desc"))
                {
                    throw new Exception("企业付款接口中,缺少必填参数desc!");
                }
                if (!inputObj.IsSet("spbill_create_ip"))
                {
                    throw new Exception("企业付款接口中,缺少必填参数spbill_create_ip!");
                }
                #endregion
    
                #region 添加公共参数
                inputObj.SetValue("mch_appid", AppId);//公众账号ID
                inputObj.SetValue("mchid", MchId);//商户号
                inputObj.SetValue("spbill_create_ip", Ip);//随机字符串
                inputObj.SetValue("nonce_str", Guid.NewGuid().ToString().Replace("-", ""));//随机字符串
                inputObj.SetValue("sign", inputObj.MakeSign(SignKey));//签名 
                #endregion
                string xml = inputObj.ToXml();
                var start = DateTime.Now;
                string response = HttpService.Post(xml, url, true, timeOut, CertPath, CertPassword);
                LogHelper.WriteFileLog("TransfersData", response);
                PaymentData result = new PaymentData();
                result.FromXml(response);
    
                return result;
            }
    
    
            #region 微信发红发,未事项,签名失败问题,未解决
            /// <summary>
            /// 微信红包
            /// </summary>
            public class PayWeiXin
            {
                public string nonce_str { get; set; }
                public string sign { get; set; }
                public string mch_billno { get; set; }
                public string mch_id { get; set; }
                public string wxappid { get; set; }
                public string nick_name { get; set; }
                public string send_name { get; set; }
                public string re_openid { get; set; }
                public int total_amount { get; set; }
                public int min_value { get; set; }
                public int max_value { get; set; }
                public int total_num { get; set; }
                public string wishing { get; set; }
                public string client_ip { get; set; }
                public string act_id { get; set; }
                public string act_name { get; set; }
                public string remark { get; set; }
                public string logo_imgurl { get; set; }
                public string share_content { get; set; }
                public string share_url { get; set; }
                public string share_imgurl { get; set; }
    
            }
    
            /// <summary>
            /// 调用微信支付接口,发送红包
            /// </summary>
            /// <param name="payForWeiXin"></param>
            /// <returns></returns>
            public string PayRedBag(PaymentData inputObj)
            {   ////商户号
                inputObj.SetValue("mch_id", MchId);
                //商户 appid 
                inputObj.SetValue("wxappid", AppId);
                inputObj.SetValue("nonce_str", GenerateNonceStr());//随机字符串
                //签名
                inputObj.SetValue("sign", inputObj.MakeSign(SignKey));
                string xml = inputObj.ToXml();
                string result = string.Empty;
                try
                {
                    result = PostPage("https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack", xml);
                    LogHelper.WriteFileLog("PayRedBagpostData", xml);
                    LogHelper.WriteFileLog("PayRedBag", result);
                }
                catch (Exception ex)
                {
                    LogHelper.WriteFileLog("PayRedBagError", ex.Message);
                }
                return result;
            }
    
    
            /// <summary>
            /// post微信请求
            /// </summary>
            /// <param name="posturl"></param>
            /// <param name="postData"></param>
            /// <returns></returns>
            public string PostPage(string posturl, string postData)
            {
                Stream outstream = null;
                Stream instream = null;
                StreamReader sr = null;
                HttpWebResponse response = null;
                HttpWebRequest request = null;
                Encoding encoding = Encoding.UTF8;
                byte[] data = encoding.GetBytes(postData);
                // 准备请求...  
                try
                {
                    
                    //CerPath证书路径
                    string certPath = TCConfigManager.GetConfig("certPath").TrySafeString();
                    //证书密码
                    string password = TCConfigManager.GetConfig("certpsd").TrySafeString();
                    
                    X509Certificate2 cert = new System.Security.Cryptography.X509Certificates.X509Certificate2(certPath, password, X509KeyStorageFlags.MachineKeySet);
    
                    // 设置参数  
                    request = WebRequest.Create(posturl) as HttpWebRequest;
                    CookieContainer cookieContainer = new CookieContainer();
                    request.CookieContainer = cookieContainer;
                    request.AllowAutoRedirect = true;
                    request.Method = "POST";
                    request.ContentType = "text/xml";
                    request.ContentLength = data.Length;
                    request.ClientCertificates.Add(cert);
                    outstream = request.GetRequestStream();
                    outstream.Write(data, 0, data.Length);
                    outstream.Close();
                    //发送请求并获取相应回应数据  
                    response = request.GetResponse() as HttpWebResponse;
                    //直到request.GetResponse()程序才开始向目标网页发送Post请求  
                    instream = response.GetResponseStream();
                    sr = new StreamReader(instream, encoding);
                    //返回结果网页(html)代码  
                    string content = sr.ReadToEnd();
                    string err = string.Empty;
                    return content;
    
                }
                catch (Exception ex)
                {
                    string err = ex.Message;
                    return string.Empty;
                }
            }
    
            /// <summary>
            /// Md5加密
            /// </summary>
            /// <param name="s"></param>
            /// <returns></returns>
            public static String Encrypt(String s)
            {
                MD5 md5 = new MD5CryptoServiceProvider();
                byte[] bytes = System.Text.Encoding.UTF8.GetBytes(s);
                bytes = md5.ComputeHash(bytes);
                md5.Clear();
                string ret = "";
                for (int i = 0; i < bytes.Length; i++)
                {
                    ret += Convert.ToString(bytes[i], 16).PadLeft(2, '0');
                }
                return ret.PadLeft(32, '0');
            }
    
            public string RandomStr(string str, int Length)
            {
                string result = string.Empty;
                Random rd = new Random();
                for (int i = 0; i < Length; i++)
                {
                    result += str[rd.Next(str.Length)];
                }
                return result;
            }
            #endregion
        }
    }

                    //弹出微信支付页面
                    WeixinJSBridge.invoke('getBrandWCPayRequest',
                        {
                            "appId": data.AppID,     //公众号名称,由商户传入
                            "timeStamp": data.TimeStamp,         //时间戳,自1970年以来的秒数
                            "nonceStr":  data.nonceStr, //随机串
                            "package": "prepay_id="+data.prepay_id,
                            "signType": "MD5",         //微信签名方式:
                            "paySign":  data.SignKey //微信签名
                        },
                        function (res) {
                            switch (res.err_msg) {
                                case "get_brand_wcpay_request:ok":
                                    layer.open({
                                        content: '充值成功',
                                        skin: 'msg',
                                        time: 2 //2秒后自动关闭
                                    });
                                    browserHistory.push('/WeChat/dist/member/wallet/');
                                    break;
                                case "get_brand_wcpay_request:cancel":
                                    break;
                                case "get_brand_wcpay_request:fail":
                                    layer.open({
                                        content: '充值失败!',
                                        skin: 'msg',
                                        time: 2 //2秒后自动关闭
                                    });
                                    break;
                                default:
                            }
                        });
    

      

    public partial class PayCallback : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                StreamReader reader = new StreamReader(Request.InputStream, Encoding.UTF8);
                string postStr = reader.ReadToEnd();
                reader.Close();
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(postStr);
                string ReturnCode = doc.SelectSingleNode("//result_code").InnerText;//获取支付结果代码
                StringBuilder xmlStr = new StringBuilder();
                LogHelper.WriteFileLog("PayCallback", ReturnCode);
                if (ReturnCode.ToUpper().Equals("SUCCESS"))
                {
                    string strOrderNo = doc.SelectSingleNode("//out_trade_no").InnerText;
                    //获取微信支付流水号
                    string weChatTransaction_Id = doc.SelectSingleNode("//transaction_id").InnerText;
                    string WeiXinOpenID = doc.SelectSingleNode("//openid").InnerText;
                    try
                    {
                        //获取订单号
                        WeiXinService WeiXinService = new WeiXinService();
                        Entity result= WeiXinService.PayOrder(WeiXinOpenID, strOrderNo, weChatTransaction_Id);
                        string Status = result.GetValue("Status").ToString();
                        string StatusText = result.GetValue("StatusText").ToString();
                        LogHelper.WriteFileLog("Pay", WeiXinOpenID + "," + strOrderNo + "," + weChatTransaction_Id + "," + Status + "," + StatusText);
                    }
                    catch (Exception ex)
                    {
                        LogHelper.WriteFileLog("PayError", ex.Message + "," + WeiXinOpenID + "," + strOrderNo + "," + weChatTransaction_Id);
                        //记录错误
                        throw ex;
                    }
    
                    #region 通知微信后台支付成功
                    Response.ContentType = "text/xml";
                    xmlStr.AppendLine("<xml>");
                    xmlStr.AppendFormat("<return_code><![CDATA[SUCCESS]]></return_code>");
                    xmlStr.AppendFormat("<return_msg><![CDATA[OK]]></return_msg>");
                    xmlStr.AppendFormat("</xml>");
                    #endregion
                }
                else
                {
                    #region 通知微信后台支付失败
                    Response.ContentType = "text/xml";
                    xmlStr.AppendLine("<xml>");
                    xmlStr.AppendFormat("<return_code><![CDATA[FAIL]]></return_code>");
                    xmlStr.AppendFormat("<return_msg><![CDATA[支付失败]]></return_msg>");
                    xmlStr.AppendFormat("</xml>");
                    #endregion
                }
                Response.Write(xmlStr.ToString());
            }
    

      

      

  • 相关阅读:
    结婚电子
    ASP.NET 5简介
    定位500错误!
    Web项目
    JS编程
    CQRS 示例
    领域驱动设计的面向服务架构
    Oracle免费的便捷Web应用开发框架
    ThreadLocal是否会引发内存泄露的分析 good
    应用的代码没有用新的类库来进行编译(转)
  • 原文地址:https://www.cnblogs.com/yyyuguo/p/8426839.html
Copyright © 2020-2023  润新知