Exemple #1
0
        /// <summary>
        /// 退款通知地址
        /// </summary>
        /// <returns></returns>
        public ActionResult RefundNotifyUrl()
        {
            string responseCode = "FAIL";
            string responseMsg  = "FAIL";

            try
            {
                ResponseHandler resHandler = new ResponseHandler(null);

                string return_code = resHandler.GetParameter("return_code");
                string return_msg  = resHandler.GetParameter("return_msg");


                if (return_code == "SUCCESS")
                {
                    responseCode = "SUCCESS";
                    responseMsg  = "OK";

                    string appId     = resHandler.GetParameter("appid");
                    string mch_id    = resHandler.GetParameter("mch_id");
                    string nonce_str = resHandler.GetParameter("nonce_str");
                    string req_info  = resHandler.GetParameter("req_info");

                    var decodeReqInfo = TenPayV3Util.DecodeRefundReqInfo(req_info, TenPayV3Info.Key);
                    var decodeDoc     = XDocument.Parse(decodeReqInfo);

                    //获取接口中需要用到的信息
                    string transaction_id       = decodeDoc.Root.Element("transaction_id").Value;
                    string out_trade_no         = decodeDoc.Root.Element("out_trade_no").Value;
                    string refund_id            = decodeDoc.Root.Element("refund_id").Value;
                    string out_refund_no        = decodeDoc.Root.Element("out_refund_no").Value;
                    int    total_fee            = int.Parse(decodeDoc.Root.Element("total_fee").Value);
                    int?   settlement_total_fee = decodeDoc.Root.Element("settlement_total_fee") != null
                            ? int.Parse(decodeDoc.Root.Element("settlement_total_fee").Value)
                            : null as int?;

                    int    refund_fee = int.Parse(decodeDoc.Root.Element("refund_fee").Value);
                    int    tosettlement_refund_feetal_fee = int.Parse(decodeDoc.Root.Element("settlement_refund_fee").Value);
                    string refund_status         = decodeDoc.Root.Element("refund_status").Value;
                    string success_time          = decodeDoc.Root.Element("success_time").Value;
                    string refund_recv_accout    = decodeDoc.Root.Element("refund_recv_accout").Value;
                    string refund_account        = decodeDoc.Root.Element("refund_account").Value;
                    string refund_request_source = decodeDoc.Root.Element("refund_request_source").Value;

                    //进行业务处理
                }
            }
            catch (Exception ex)
            {
                responseMsg = ex.Message;
                WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex));
            }

            string xml = string.Format(@"<xml>
<return_code><![CDATA[{0}]]></return_code>
<return_msg><![CDATA[{1}]]></return_msg>
</xml>", responseCode, responseMsg);

            return(Content(xml, "text/xml"));
        }
Exemple #2
0
        public ActionResult PayNotifyUrl()
        {
            try
            {
                ResponseHandler resHandler = new ResponseHandler(HttpContext);

                string return_code = resHandler.GetParameter("return_code");
                string return_msg  = resHandler.GetParameter("return_msg");

                string res = null;

                resHandler.SetKey(TenPyConfigRead.Key);
                //验证请求是否从微信发过来(安全)
                if (resHandler.IsTenpaySign() && return_code.ToUpper() == "SUCCESS")
                {
                    res = "success";//正确的订单处理
                    //直到这里,才能认为交易真正成功了,可以进行数据库操作,但是别忘了返回规定格式的消息!
                }
                else
                {
                    res = "wrong";//错误的订单处理
                }



                #region 记录日志

                var logDir = ServerUtility.ContentRootMapPath(string.Format("~/App_Data/TenPayNotify/{0}", SystemTime.Now.ToString("yyyyMMdd")));
                if (!Directory.Exists(logDir))
                {
                    Directory.CreateDirectory(logDir);
                }

                var logPath = Path.Combine(logDir, string.Format("{0}-{1}-{2}.txt", SystemTime.Now.ToString("yyyyMMdd"), SystemTime.Now.ToString("HHmmss"), Guid.NewGuid().ToString("n").Substring(0, 8)));

                using (var fileStream = System.IO.File.OpenWrite(logPath))
                {
                    var notifyXml = resHandler.ParseXML();
                    //fileStream.Write(Encoding.Default.GetBytes(res), 0, Encoding.Default.GetByteCount(res));

                    fileStream.Write(Encoding.Default.GetBytes(notifyXml), 0, Encoding.Default.GetByteCount(notifyXml));
                    fileStream.Close();
                }

                #endregion


                string xml = string.Format(@"<xml>
<return_code><![CDATA[{0}]]></return_code>
<return_msg><![CDATA[{1}]]></return_msg>
</xml>", return_code, return_msg);
                return(Content(xml, "text/xml"));
            }
            catch (Exception ex)
            {
                WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex));
                throw;
            }
        }
Exemple #3
0
        public HttpResult PayNotifyUrl()
        {
            try
            {
                ResponseHandler resHandler = new ResponseHandler(HttpContext);

                string return_code = resHandler.GetParameter("return_code");
                string return_msg  = resHandler.GetParameter("return_msg");


                resHandler.SetKey(TenPayV3Info.Key);
                //验证请求是否从微信发过来(安全)
                if (resHandler.IsTenpaySign() && return_code.ToUpper() == "SUCCESS")
                {
                    //正确的订单处理
                    //直到这里,才能认为交易真正成功了,可以进行数据库操作,但是别忘了返回规定格式的消息!
                }
                else
                {
                    //错误的订单处理
                }

                /* 这里可以进行订单处理的逻辑 */

                //发送支付成功的模板消息
                try
                {
                    string appId        = Config.SenparcWeixinSetting.TenPayV3_AppId;//与微信公众账号后台的AppId设置保持一致,区分大小写。
                    string openId       = resHandler.GetParameter("openid");
                    var    templateData = new Weixin_PaySuccess("https://yufaquan.cn", "购买商品", "状态:" + return_code);

                    Senparc.Weixin.WeixinTrace.SendCustomLog("支付成功模板消息参数", appId + " , " + openId);

                    var result = TemplateApi.SendTemplateMessage(appId, openId, templateData);
                }
                catch (Exception ex)
                {
                    Senparc.Weixin.WeixinTrace.SendCustomLog("支付成功模板消息", ex.ToString());
                }

                #region 记录日志


                #endregion


                var res = new
                {
                    return_code,
                    return_msg
                };
                return(HttpResult.Success(res));
            }
            catch (Exception ex)
            {
                WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex));
                throw;
            }
        }
Exemple #4
0
 /// <summary>
 /// WeixinException
 /// </summary>
 /// <param name="message">异常消息</param>
 /// <param name="inner">内部异常信息</param>
 /// <param name="logged">是否已经使用WeixinTrace记录日志,如果没有,WeixinException会进行概要记录</param>
 public WeixinException(string message, Exception inner, bool logged = false)
     : base(message, inner, true /* 标记为日志已记录 */)
 {
     if (!logged)
     {
         WeixinTrace.WeixinExceptionLog(this);
     }
 }
Exemple #5
0
        /// <summary>
        /// H5支付
        /// </summary>
        /// <param name="productId"></param>
        /// <param name="hc"></param>
        /// <returns></returns>
        public async Task <IActionResult> H5Pay(int productId, int hc)
        {
            try
            {
                //获取产品信息
                var products = ProductModel.GetFakeProductList();
                var product  = products.FirstOrDefault(z => z.Id == productId);
                if (product == null || product.GetHashCode() != hc)
                {
                    return(Content("商品信息不存在,或非法进入!1002"));
                }

                string openId = null;//此时在外部浏览器,无法或得到OpenId

                string sp_billno = Request.Query["order_no"];
                if (string.IsNullOrEmpty(sp_billno))
                {
                    //生成订单10位序列号,此处用时间和随机数生成,商户根据自己调整,保证唯一
                    sp_billno = string.Format("{0}{1}{2}", TenPayV3Info.MchId /*10位*/, SystemTime.Now.ToString("yyyyMMddHHmmss"),
                                              TenPayV3Util.BuildRandomStr(6));
                }
                else
                {
                    sp_billno = Request.Query["order_no"];
                }

                var timeStamp = TenPayV3Util.GetTimestamp();
                var nonceStr  = TenPayV3Util.GetNoncestr();

                var body  = product == null ? "test" : product.Name;
                var price = product == null ? 100 : (int)(product.Price * 100);

                var notifyUrl = TenPayV3Info.TenPayV3Notify.Replace("/TenpayV3/", "/TenpayRealV3/");

                TransactionsRequestData.Scene_Info sence_info = new(HttpContext.UserHostAddress()?.ToString(), null, null, new("Wap", null, null, null, null));

                TransactionsRequestData requestData = new(TenPayV3Info.AppId, TenPayV3Info.MchId, body, sp_billno, new TenpayDateTime(DateTime.Now.AddHours(1), false), null, notifyUrl, null, new() { currency = "CNY", total = price }, new(openId), null, null, sence_info);

                WeixinTrace.SendCustomLog("H5Pay接口请求", requestData.ToJson());

                var result = await _basePayApis.H5Async(requestData);

                WeixinTrace.SendCustomLog("H5Pay接口返回", result.ToJson());

                if (!result.VerifySignSuccess == true)
                {
                    return(Content("未通过验证,请检查数据有效性!"));
                }

                //直接跳转
                return(Redirect(result.h5_url));
            }
            catch (Exception ex)
            {
                WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex));
                throw;
            }
        }
 /// <summary>
 /// WeixinException
 /// </summary>
 /// <param name="message">异常消息</param>
 /// <param name="inner">内部异常信息</param>
 /// <param name="logged">是否已经使用WeixinTrace记录日志,如果没有,WeixinException会进行概要记录</param>
 public WeixinException(string message, Exception inner, bool logged = false)
     : base(message, inner)
 {
     if (!logged)
     {
         //WeixinTrace.Log(string.Format("WeixinException({0}):{1}", this.GetType().Name, message));
         WeixinTrace.WeixinExceptionLog(this);
     }
 }
Exemple #7
0
        /// <summary>
        /// 退款通知地址
        /// </summary>
        /// <returns></returns>
        public async Task <IActionResult> RefundNotifyUrl()
        {
            WeixinTrace.SendCustomLog("RefundNotifyUrl被访问", "IP" + HttpContext.UserHostAddress()?.ToString());

            NotifyReturnData returnData = new();

            try
            {
                var resHandler       = new TenPayNotifyHandler(HttpContext);
                var refundNotifyJson = await resHandler.AesGcmDecryptGetObjectAsync <RefundNotifyJson>();

                WeixinTrace.SendCustomLog("跟踪RefundNotifyUrl信息", refundNotifyJson.ToJson());

                string refund_status = refundNotifyJson.refund_status;
                if (/*refundNotifyJson.VerifySignSuccess == true &*/ refund_status == "SUCCESS")
                {
                    returnData.code    = "SUCCESS";
                    returnData.message = "OK";

                    //获取接口中需要用到的信息 例
                    string transaction_id = refundNotifyJson.transaction_id;
                    string out_trade_no   = refundNotifyJson.out_trade_no;
                    string refund_id      = refundNotifyJson.refund_id;
                    string out_refund_no  = refundNotifyJson.out_refund_no;
                    int    total_fee      = refundNotifyJson.amount.payer_total;
                    int    refund_fee     = refundNotifyJson.amount.refund;

                    //填写逻辑
                    WeixinTrace.SendCustomLog("RefundNotifyUrl被访问", "验证通过");
                }
                else
                {
                    returnData.code    = "FAILD";
                    returnData.message = "验证失败";
                    WeixinTrace.SendCustomLog("RefundNotifyUrl被访问", "验证失败");
                }

                //进行后续业务处理
            }
            catch (Exception ex)
            {
                returnData.code    = "FAILD";
                returnData.message = ex.Message;
                WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex));
            }

            //https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay3_3.shtml
            return(Json(returnData));
        }
Exemple #8
0
        //DPBMARK_END


        #region 订单及退款

        /// <summary>
        /// 退款申请接口
        /// </summary>
        /// <returns></returns>
        public async Task <IActionResult> Refund()
        {
            try
            {
                WeixinTrace.SendCustomLog("进入退款流程", "1");

                string nonceStr = TenPayV3Util.GetNoncestr();

                string outTradeNo = HttpContext.Session.GetString("BillNo");
                if (!TradeNumberToTransactionId.TryGetValue(outTradeNo, out string transactionId))
                {
                    return(Content("transactionId 不正确,可能是服务器还没有收到微信回调确认通知,退款失败。请稍后刷新再试。"));
                }

                WeixinTrace.SendCustomLog("进入退款流程", "2 outTradeNo:" + outTradeNo + ",transactionId:" + transactionId);

                string outRefundNo = "OutRefunNo-" + SystemTime.Now.Ticks;
                int    totalFee    = int.Parse(HttpContext.Session.GetString("BillFee"));
                int    refundFee   = totalFee;
                string opUserId    = TenPayV3Info.MchId;
                var    notifyUrl   = "https://sdk.weixin.senparc.com/TenPayRealV3/RefundNotifyUrl";
                //var dataInfo = new TenPayV3RefundRequestData(TenPayV3Info.AppId, TenPayV3Info.MchId, TenPayV3Info.Key,
                //    null, nonceStr, null, outTradeNo, outRefundNo, totalFee, refundFee, opUserId, null, notifyUrl: notifyUrl);
                //TODO:该接口参数二选一传入
                var dataInfo = new RefundRequsetData(transactionId, null, outRefundNo, "Senparc TenPayV3 demo退款测试", notifyUrl, null, new RefundRequsetData.Amount(refundFee, null, refundFee, "CNY"), null);


                //#region 新方法(Senparc.Weixin v6.4.4+)
                //var result = TenPayOldV3.Refund(_serviceProvider, dataInfo);//证书地址、密码,在配置文件中设置,并在注册微信支付信息时自动记录
                //#endregion
                var result = await _basePayApis.RefundAsync(dataInfo);

                WeixinTrace.SendCustomLog("进入退款流程", "3 Result:" + result.ToJson());
                ViewData["Message"] = $"退款结果:{result.status} {result.ResultCode}。您可以刷新当前页面查看最新结果。";
                return(View());
                //return Json(result, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex));

                throw;
            }
        }
Exemple #9
0
        public HttpResult Refund()
        {
            try
            {
                WeixinTrace.SendCustomLog("进入退款流程", "1");

                string nonceStr = TenPayV3Util.GetNoncestr();

                string outTradeNo = HttpContext.Session.GetString("BillNo");

                WeixinTrace.SendCustomLog("进入退款流程", "2 outTradeNo:" + outTradeNo);

                string outRefundNo = "OutRefunNo-" + SystemTime.Now.Ticks;
                int    totalFee    = int.Parse(HttpContext.Session.GetString("BillFee"));
                int    refundFee   = totalFee;
                string opUserId    = TenPayV3Info.MchId;
                var    notifyUrl   = "https://yufaquan.cn/wx/PayV3/RefundNotifyUrl";
                var    dataInfo    = new TenPayV3RefundRequestData(TenPayV3Info.AppId, TenPayV3Info.MchId, TenPayV3Info.Key,
                                                                   null, nonceStr, null, outTradeNo, outRefundNo, totalFee, refundFee, opUserId, null, notifyUrl: notifyUrl);

                #region 旧方法
                //var cert = @"D:\cert\apiclient_cert_SenparcRobot.p12";//根据自己的证书位置修改
                //var password = TenPayV3Info.MchId;//默认为商户号,建议修改
                //var result = TenPayV3.Refund(dataInfo, cert, password);
                #endregion

                #region 新方法(Senparc.Weixin v6.4.4+)
                var result = TenPayV3.Refund(_serviceProvider, dataInfo);//证书地址、密码,在配置文件中设置,并在注册微信支付信息时自动记录
                #endregion

                WeixinTrace.SendCustomLog("进入退款流程", "3 Result:" + result.ToJson());

                return(HttpResult.Success($"退款结果:{result.result_code} {result.err_code_des}。", null));
            }
            catch (Exception ex)
            {
                WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex));

                throw;
            }
        }
Exemple #10
0
        /// <summary>
        /// JS-SDK支付回调地址(在下单接口中设置的 notify_url)
        /// </summary>
        /// <returns></returns>
        public async Task <IActionResult> PayNotifyUrl()
        {
            try
            {
                //获取微信服务器异步发送的支付通知信息
                var resHandler      = new TenPayNotifyHandler(HttpContext);
                var orderReturnJson = await resHandler.AesGcmDecryptGetObjectAsync <OrderReturnJson>();

                //记录日志
                Senparc.Weixin.WeixinTrace.SendCustomLog("PayNotifyUrl 接收到消息", orderReturnJson.ToJson(true));

                //演示记录 transaction_id,实际开发中需要记录到数据库,以便退款和后续跟踪
                TradeNumberToTransactionId[orderReturnJson.out_trade_no] = orderReturnJson.transaction_id;

                //获取支付状态
                string trade_state = orderReturnJson.trade_state;

                //验证请求是否从微信发过来(安全)
                NotifyReturnData returnData = new();

                //验证可靠的支付状态
                if (orderReturnJson.VerifySignSuccess == true && trade_state == "SUCCESS")
                {
                    returnData.code = "SUCCESS";//正确的订单处理

                    /* 提示:
                     * 1、直到这里,才能认为交易真正成功了,可以进行数据库操作,但是别忘了返回规定格式的消息!
                     * 2、上述判断已经具有比较高的安全性以外,还可以对访问 IP 进行判断进一步加强安全性。
                     * 3、下面演示的是发送支付成功的模板消息提示,非必须。
                     */

                    #region 发送支付成功模板消息提醒
                    try
                    {
                        string appId        = Config.SenparcWeixinSetting.TenPayV3_AppId;//与微信公众账号后台的AppId设置保持一致,区分大小写。
                        string openId       = orderReturnJson.payer.openid;
                        var    templateData = new WeixinTemplate_PaySuccess("https://weixin.senparc.com", "微信支付 V3 购买商品", "状态:" + trade_state);

                        Senparc.Weixin.WeixinTrace.SendCustomLog("TenPayV3 支付成功模板消息参数", "AppId:" + appId + " ,openId: " + openId);

                        var result = await MP.AdvancedAPIs.TemplateApi.SendTemplateMessageAsync(appId, openId, templateData);
                    }
                    catch (Exception ex)
                    {
                        Senparc.Weixin.WeixinTrace.SendCustomLog("TenPayV3 支付成功模板消息", ex.ToString());
                    }
                    #endregion
                }
                else
                {
                    returnData.code    = "FAILD";//错误的订单处理
                    returnData.message = "验证失败";

                    //此处可以给用户发送支付失败提示等
                }

                #region 记录日志(也可以记录到数据库审计日志中)

                var logDir = ServerUtility.ContentRootMapPath(string.Format("~/App_Data/TenPayNotify/{0}", SystemTime.Now.ToString("yyyyMMdd")));
                if (!Directory.Exists(logDir))
                {
                    Directory.CreateDirectory(logDir);
                }

                var logPath = Path.Combine(logDir, string.Format("{0}-{1}-{2}.txt", SystemTime.Now.ToString("yyyyMMdd"), SystemTime.Now.ToString("HHmmss"), Guid.NewGuid().ToString("n").Substring(0, 8)));

                using (var fileStream = System.IO.File.OpenWrite(logPath))
                {
                    var notifyJson = orderReturnJson.ToString();
                    await fileStream.WriteAsync(Encoding.Default.GetBytes(notifyJson), 0, Encoding.Default.GetByteCount(notifyJson));

                    fileStream.Close();
                }
                #endregion

                //https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_5.shtml
                return(Json(returnData));
            }
            catch (Exception ex)
            {
                WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex));
                throw;
            }
        }
Exemple #11
0
        /// <summary>
        /// JS-SDK支付回调地址(在统一下单接口中设置notify_url)
        /// </summary>
        /// <returns></returns>
        public ActionResult PayNotifyUrl(bool isWxOpenPay = false)//注意:统一下单接口中不能带参数!
        {
            WeixinTrace.SendCustomLog("微信支付回调", "来源:" + (isWxOpenPay ? "微信支付" : "小程序支付"));

            try
            {
                ResponseHandler resHandler = new ResponseHandler(null);

                string return_code = resHandler.GetParameter("return_code");
                string return_msg  = resHandler.GetParameter("return_msg");

                bool paySuccess = false;

                resHandler.SetKey(TenPayV3Info.Key);
                //验证请求是否从微信发过来(安全)
                if (resHandler.IsTenpaySign() && return_code.ToUpper() == "SUCCESS")
                {
                    paySuccess = true;//正确的订单处理
                    //直到这里,才能认为交易真正成功了,可以进行数据库操作,但是别忘了返回规定格式的消息!
                }
                else
                {
                    paySuccess = false;//错误的订单处理
                }

                if (paySuccess)
                {
                    /* 这里可以进行订单处理的逻辑 */

                    //发送支付成功的模板消息
                    try
                    {
                        string appId  = Config.SenparcWeixinSetting.WeixinAppId;//与微信公众账号后台的AppId设置保持一致,区分大小写。
                        string openId = resHandler.GetParameter("openid");

                        if (isWxOpenPay)
                        {
                            //DPBMARK MiniProgram
                            var cacheStrategy           = CacheStrategyFactory.GetObjectCacheStrategyInstance();
                            var unifiedorderRequestData = cacheStrategy.Get <TenPayV3UnifiedorderRequestData>($"WxOpenUnifiedorderRequestData-{openId}"); //获取订单请求信息缓存
                            var unifedorderResult       = cacheStrategy.Get <UnifiedorderResult>($"WxOpenUnifiedorderResultData-{openId}");               //获取订单信息缓存

                            if (unifedorderResult != null || !string.IsNullOrEmpty(unifedorderResult.prepay_id))
                            {
                                Senparc.Weixin.WeixinTrace.SendCustomLog("支付成功模板消息参数(小程序)", appId + " , " + openId);

                                //小程序支付,发送小程序模板消息
                                var templateData = new WxOpenTemplateMessage_PaySuccessNotice(
                                    "在线购买(小程序支付)测试", SystemTime.Now, "小程序支付 | 注意:这条消息来自微信服务器异步回调,官方证明支付成功! | prepay_id:" + unifedorderResult.prepay_id,
                                    unifiedorderRequestData.OutTradeNo, unifiedorderRequestData.TotalFee, "400-031-8816", "https://weixin.senparc.com");

                                //微信官方已停用此接口
                                //Senparc.Weixin.WxOpen.AdvancedAPIs
                                //    .Template.TemplateApi
                                //    .SendTemplateMessage(
                                //        Config.SenparcWeixinSetting.WxOpenAppId, openId, templateData.TemplateId, templateData, unifedorderResult.prepay_id, "pages/index/index", "图书", "#fff00");
                            }
                            else
                            {
                                Senparc.Weixin.WeixinTrace.SendCustomLog("支付成功模板消息参数(小程序)", "prepayId未记录:" + appId + " , " + openId);
                            }
                            //DPBMARK_END
                        }
                        else
                        {
                            //微信公众号支付
                            var templateData = new WeixinTemplate_PaySuccess("https://weixin.senparc.com", "购买商品", "状态:" + return_code);

                            Senparc.Weixin.WeixinTrace.SendCustomLog("支付成功模板消息参数(公众号)", appId + " , " + openId);

                            var result = AdvancedAPIs.TemplateApi.SendTemplateMessage(appId, openId, templateData);
                        }
                    }
                    catch (Exception ex)
                    {
                        WeixinTrace.WeixinExceptionLog(new WeixinException("支付成功模板消息异常", ex));
                        //WeixinTrace.SendCustomLog("支付成功模板消息", ex.ToString());
                    }

                    WeixinTrace.SendCustomLog("PayNotifyUrl回调", "支付成功");
                }
                else
                {
                    Senparc.Weixin.WeixinTrace.SendCustomLog("PayNotifyUrl回调", "支付失败");
                }



                #region 记录日志

                var logDir = ServerUtility.ContentRootMapPath(string.Format("~/App_Data/TenPayNotify/{0}", SystemTime.Now.ToString("yyyyMMdd")));
                if (!Directory.Exists(logDir))
                {
                    Directory.CreateDirectory(logDir);
                }

                var logPath = Path.Combine(logDir, string.Format("{0}-{1}-{2}.txt", SystemTime.Now.ToString("yyyyMMdd"), SystemTime.Now.ToString("HHmmss"), Guid.NewGuid().ToString("n").Substring(0, 8)));

                using (var fileStream = System.IO.File.OpenWrite(logPath))
                {
                    var notifyXml = resHandler.ParseXML();
                    //fileStream.Write(Encoding.Default.GetBytes(res), 0, Encoding.Default.GetByteCount(res));

                    fileStream.Write(Encoding.Default.GetBytes(notifyXml), 0, Encoding.Default.GetByteCount(notifyXml));
                    fileStream.Close();
                }

                #endregion


                string xml = string.Format(@"<xml>
<return_code><![CDATA[{0}]]></return_code>
<return_msg><![CDATA[{1}]]></return_msg>
</xml>", return_code, return_msg);
                return(Content(xml, "text/xml"));
            }
            catch (Exception ex)
            {
                WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex));
                throw;
            }
        }
Exemple #12
0
        /// <summary>
        /// 退款通知地址
        /// </summary>
        /// <returns></returns>
        public ActionResult RefundNotifyUrl()
        {
            WeixinTrace.SendCustomLog("RefundNotifyUrl被访问", "IP" + HttpContext.UserHostAddress()?.ToString());

            string responseCode = "FAIL";
            string responseMsg  = "FAIL";

            try
            {
                ResponseHandler resHandler = new ResponseHandler(null);

                string return_code = resHandler.GetParameter("return_code");
                string return_msg  = resHandler.GetParameter("return_msg");

                WeixinTrace.SendCustomLog("跟踪RefundNotifyUrl信息", resHandler.ParseXML());

                if (return_code == "SUCCESS")
                {
                    responseCode = "SUCCESS";
                    responseMsg  = "OK";

                    string appId     = resHandler.GetParameter("appid");
                    string mch_id    = resHandler.GetParameter("mch_id");
                    string nonce_str = resHandler.GetParameter("nonce_str");
                    string req_info  = resHandler.GetParameter("req_info");

                    if (!appId.Equals(Senparc.Weixin.Config.SenparcWeixinSetting.TenPayV3_AppId))
                    {
                        /*
                         * 注意:
                         * 这里添加过滤只是因为盛派Demo经常有其他公众号错误地设置了我们的地址,
                         * 导致无法正常解密,平常使用不需要过滤!
                         */
                        SenparcTrace.SendCustomLog("RefundNotifyUrl 的 AppId 不正确",
                                                   $"appId:{appId}\r\nmch_id:{mch_id}\r\nreq_info:{req_info}");
                        return(Content("faild"));
                    }

                    var decodeReqInfo = TenPayV3Util.DecodeRefundReqInfo(req_info, TenPayV3Info.Key);
                    var decodeDoc     = XDocument.Parse(decodeReqInfo);

                    //获取接口中需要用到的信息
                    string transaction_id       = decodeDoc.Root.Element("transaction_id").Value;
                    string out_trade_no         = decodeDoc.Root.Element("out_trade_no").Value;
                    string refund_id            = decodeDoc.Root.Element("refund_id").Value;
                    string out_refund_no        = decodeDoc.Root.Element("out_refund_no").Value;
                    int    total_fee            = int.Parse(decodeDoc.Root.Element("total_fee").Value);
                    int?   settlement_total_fee = decodeDoc.Root.Element("settlement_total_fee") != null
                            ? int.Parse(decodeDoc.Root.Element("settlement_total_fee").Value)
                            : null as int?;

                    int    refund_fee = int.Parse(decodeDoc.Root.Element("refund_fee").Value);
                    int    tosettlement_refund_feetal_fee = int.Parse(decodeDoc.Root.Element("settlement_refund_fee").Value);
                    string refund_status         = decodeDoc.Root.Element("refund_status").Value;
                    string success_time          = decodeDoc.Root.Element("success_time").Value;
                    string refund_recv_accout    = decodeDoc.Root.Element("refund_recv_accout").Value;
                    string refund_account        = decodeDoc.Root.Element("refund_account").Value;
                    string refund_request_source = decodeDoc.Root.Element("refund_request_source").Value;


                    WeixinTrace.SendCustomLog("RefundNotifyUrl被访问", "验证通过");

                    //进行后续业务处理
                }
            }
            catch (Exception ex)
            {
                responseMsg = ex.Message;
                WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex));
            }

            string xml = string.Format(@"<xml>
<return_code><![CDATA[{0}]]></return_code>
<return_msg><![CDATA[{1}]]></return_msg>
</xml>", responseCode, responseMsg);

            return(Content(xml, "text/xml"));
        }
Exemple #13
0
        public async Task <IActionResult> RefundGet([FromQuery] RefundModel refund)
        {
            try
            {
                //  WeixinTrace.SendCustomLog("进入退款流程", "1");
                if (string.IsNullOrWhiteSpace(refund.NonceStr))
                {
                    refund.NonceStr = TenPayV3Util.GetNoncestr();
                }
                if (string.IsNullOrWhiteSpace(refund.OpUserId))
                {
                    refund.OpUserId = TenPyConfigRead.MchId;
                }

                if (string.IsNullOrWhiteSpace(refund.OutTradeNo) && string.IsNullOrWhiteSpace(refund.TransactionId))
                {
                    return(BadRequest("需要OutTradeNo,TransactionId之一"));
                }

                //      string outTradeNo = HttpContext.Session.GetString("BillNo");

                // WeixinTrace.SendCustomLog("进入退款流程", "2 outTradeNo:" + refund.OutTradeNo);

                refund.SignType = "MD5";

                var dataInfo = new TenPayV3RefundRequestData(
                    appId: TenPyConfigRead.AppId,
                    mchId: TenPyConfigRead.MchId,
                    key: TenPyConfigRead.Key,
                    deviceInfo: refund.DeviceInfo,
                    nonceStr: refund.NonceStr,
                    transactionId: refund.TransactionId,
                    outTradeNo: refund.OutTradeNo,
                    outRefundNo: refund.OutRefundNo,
                    totalFee: refund.TotalFee,
                    refundFee: refund.RefundFee,
                    opUserId: refund.OpUserId,
                    refundAccount: refund.RefundAccount,
                    notifyUrl: refund.NotifyUrl);


                //#region 旧方法
                //var cert = @"D:\cert\apiclient_cert_SenparcRobot.p12";//根据自己的证书位置修改
                //var password = TenPayV3Info.MchId;//默认为商户号,建议修改
                //var result = TenPayV3.Refund(dataInfo, TenPyConfigRead.CertPath, Int32.Parse(TenPyConfigRead.CertSecret));
                //#endregion

                #region 新方法(Senparc.Weixin v6.4.4+)
                var result = await TenPayV3.RefundAsync(_serviceProvider, dataInfo);//证书地址、密码,在配置文件中设置,并在注册微信支付信息时自动记录

                #endregion
                var log = _logger.CreateLogger("申请退款");
                if (result.return_code == "FAIL")
                {
                    log.LogError($"退款单号(out_refund_no):{refund.OutRefundNo}   通讯标记(return_code):{result.return_code}  {result.return_msg}");
                }
                if (result.result_code == "FAIL")
                {
                    log.LogError($"退款单号(out_refund_no):{refund.OutRefundNo}   业务结果(result_code):{result.result_code}\n{result.err_code}:{result.err_code_des}");
                }
                else if (result.result_code == "SUCCESS")
                {
                    log.LogInformation($"退款单号(out_refund_no):{refund.OutRefundNo}  业务结果(result_code):{result.result_code}");
                }
                // WeixinTrace.SendCustomLog("进入退款流程", "3 Result:" + result.ToJson());
                //   ViewData["Message"] = $"退款结果:{result.result_code} {result.err_code_des}。您可以刷新当前页面查看最新结果。";
                return(Ok(new
                {
                    respond = result,
                    request = refund
                }));
                //return Json(result, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex));

                throw;
            }

            #region 原始方法

            //RequestHandler packageReqHandler = new RequestHandler(null);

            //设置package订单参数
            //packageReqHandler.SetParameter("appid", TenPayV3Info.AppId);		 //公众账号ID
            //packageReqHandler.SetParameter("mch_id", TenPayV3Info.MchId);	     //商户号
            //packageReqHandler.SetParameter("out_trade_no", "124138540220170502163706139412"); //填入商家订单号
            ////packageReqHandler.SetParameter("out_refund_no", "");                //填入退款订单号
            //packageReqHandler.SetParameter("total_fee", "");                    //填入总金额
            //packageReqHandler.SetParameter("refund_fee", "100");                //填入退款金额
            //packageReqHandler.SetParameter("op_user_id", TenPayV3Info.MchId);   //操作员Id,默认就是商户号
            //packageReqHandler.SetParameter("nonce_str", nonceStr);              //随机字符串
            //string sign = packageReqHandler.CreateMd5Sign("key", TenPayV3Info.Key);
            //packageReqHandler.SetParameter("sign", sign);	                    //签名
            ////退款需要post的数据
            //string data = packageReqHandler.ParseXML();

            ////退款接口地址
            //string url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
            ////本地或者服务器的证书位置(证书在微信支付申请成功发来的通知邮件中)
            //string cert = @"D:\cert\apiclient_cert_SenparcRobot.p12";
            ////私钥(在安装证书时设置)
            //string password = TenPayV3Info.MchId;
            //ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
            ////调用证书
            //X509Certificate2 cer = new X509Certificate2(cert, password, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);

            //#region 发起post请求
            //HttpWebRequest webrequest = (HttpWebRequest)HttpWebRequest.Create(url);
            //webrequest.ClientCertificates.Add(cer);
            //webrequest.Method = "post";

            //byte[] postdatabyte = Encoding.UTF8.GetBytes(data);
            //webrequest.ContentLength = postdatabyte.Length;
            //Stream stream;
            //stream = webrequest.GetRequestStream();
            //stream.Write(postdatabyte, 0, postdatabyte.Length);
            //stream.Close();

            //HttpWebResponse httpWebResponse = (HttpWebResponse)webrequest.GetResponse();
            //StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream());
            //string responseContent = streamReader.ReadToEnd();
            //#endregion

            //// var res = XDocument.Parse(responseContent);
            ////string openid = res.Element("xml").Element("out_refund_no").Value;
            //return Content("申请成功:<br>" + HttpUtility.RequestUtility.HtmlEncode(responseContent));

            #endregion
        }
Exemple #14
0
        /// <summary>
        /// JS-SDK支付回调地址(在统一下单接口中设置notify_url)
        /// </summary>
        /// <returns></returns>
        public async Task <ActionResult> PayNotifyUrl(Guid id)
        {
            try
            {
                ResponseHandler resHandler = new ResponseHandler(HttpContext);

                string return_code = resHandler.GetParameter("return_code");
                string return_msg  = resHandler.GetParameter("return_msg");
                resHandler.SetKey(TenPayV3Info.Key);
                bool succeed = resHandler.IsTenpaySign() && return_code.ToUpper() == "SUCCESS";

                /* 这里可以进行订单处理的逻辑 */
                string out_trade_no = resHandler.GetParameter("out_trade_no");
                var    pay          = _paySrv.UpdatePaymentResult(GuidEncoder.Decode(out_trade_no), succeed);
                if (succeed)
                {
                    var result = await ExecuteOrder((Guid)pay.OrderId, pay.Id, true);
                }

                //发送支付成功的模板消息
                try
                {
                    string appId        = Config.SenparcWeixinSetting.TenPayV3_AppId;//与微信公众账号后台的AppId设置保持一致,区分大小写。
                    string openId       = resHandler.GetParameter("openid");
                    var    templateData = new WeixinTemplate_PaySuccess(_siteUrl, "购买商品", "状态:" + return_code);

                    Senparc.Weixin.WeixinTrace.SendCustomLog("支付成功模板消息参数", appId + " , " + openId);

                    // var result = Senparc.Weixin.MP.AdvancedAPIs.TemplateApi.SendTemplateMessage(appId, openId, templateData);
                }
                catch (Exception ex)
                {
                    Senparc.Weixin.WeixinTrace.SendCustomLog("支付成功模板消息", ex.ToString());
                }

                #region 记录日志

                var logDir = ServerUtility.ContentRootMapPath(string.Format("~/App_Data/TenPayNotify/{0}", SystemTime.Now.ToString("yyyyMMdd")));
                if (!Directory.Exists(logDir))
                {
                    Directory.CreateDirectory(logDir);
                }

                var logPath = Path.Combine(logDir, string.Format("{0}-{1}-{2}.txt", SystemTime.Now.ToString("yyyyMMdd"), SystemTime.Now.ToString("HHmmss"), Guid.NewGuid().ToString("n").Substring(0, 8)));

                using (var fileStream = System.IO.File.OpenWrite(logPath))
                {
                    var notifyXml = resHandler.ParseXML();
                    //fileStream.Write(Encoding.Default.GetBytes(res), 0, Encoding.Default.GetByteCount(res));

                    fileStream.Write(Encoding.Default.GetBytes(notifyXml), 0, Encoding.Default.GetByteCount(notifyXml));
                    fileStream.Close();
                }

                #endregion


                string xml = string.Format(@"<xml>
<return_code><![CDATA[{0}]]></return_code>
<return_msg><![CDATA[{1}]]></return_msg>
</xml>", return_code, return_msg);
                return(Content(xml, "text/xml"));
            }
            catch (Exception ex)
            {
                WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex));
                throw;
            }
        }
Exemple #15
0
        IActionResult PayNotifyUrl_Ex(bool isWxOpenPay)//注意:统一下单接口中不能带参数!
        {
            WeixinTrace.SendCustomLog("微信支付回调", "来源:" + (isWxOpenPay ? "微信支付" : "小程序支付"));

            try
            {
                ResponseHandler resHandler = new ResponseHandler(null);

                string return_code = resHandler.GetParameter("return_code");
                string return_msg  = resHandler.GetParameter("return_msg");

                bool paySuccess = false;

                resHandler.SetKey(TenPayV3Info.Key);
                //验证请求是否从微信发过来(安全)
                if (resHandler.IsTenpaySign() && return_code.ToUpper() == "SUCCESS")
                {
                    string out_trade_no   = resHandler.GetParameter("out_trade_no");
                    string openid         = resHandler.GetParameter("openid");
                    string total_fee      = resHandler.GetParameter("total_fee");
                    string transaction_id = resHandler.GetParameter("transaction_id");
                    string end_time       = resHandler.GetParameter("time_end");
                    try
                    {
                        var order = _context.Order.FirstOrDefault(od => od.OrderID == out_trade_no);
                        if (order != null)
                        {
                            if (order.OrderStatus == TradeState.NOTPAY || order.OrderStatus == TradeState.USERPAYING)
                            {
                                order.TransactionId = transaction_id;
                                order.ActPay        = decimal.Parse(total_fee);
                                order.OrderStatus   = TradeState.SUCCESS;
                                order.PayType       = "WeiXin";
                                order.OpenID        = openid;
                                if (DateTime.TryParseExact(end_time, "yyyyMMddHHmmss", null, System.Globalization.DateTimeStyles.None, out DateTime paydatetime_))
                                {
                                    order.PayDateTime = paydatetime_;
                                }
                                else
                                {
                                    order.PayDateTime = DateTime.Now;
                                }
                                _context.Order.Update(order);
                                _context.SaveChanges();
                                paySuccess = true;//正确的订单处理
                            }
                            else
                            {
                                return_code = "SUCCESS";
                                return_msg  = "订单已支付";
                                paySuccess  = true;
                            }
                        }
                        else
                        {
                            return_code = "FAIL";
                            return_msg  = "订单不存在";
                            paySuccess  = false;
                        }
                    }
                    catch (Exception ex)
                    {
                        return_code = "FAIL";
                        return_msg  = "服务器异常";
                        paySuccess  = false;
                        _logger.LogError(ex, "数据无法保存" + ex.Message);
                    }
                }
                else
                {
                    paySuccess = false;//错误的订单处理
                }
                if (paySuccess)
                {
                    /* 这里可以进行订单处理的逻辑 */

                    //发送支付成功的模板消息
                    try
                    {
                        string appId  = Config.SenparcWeixinSetting.WeixinAppId;//与微信公众账号后台的AppId设置保持一致,区分大小写。
                        string openId = resHandler.GetParameter("openid");

                        if (isWxOpenPay)
                        {
                            var cacheStrategy           = CacheStrategyFactory.GetObjectCacheStrategyInstance();
                            var unifiedorderRequestData = cacheStrategy.Get <TenPayV3UnifiedorderRequestData>($"WxOpenUnifiedorderRequestData-{openId}"); //获取订单请求信息缓存
                            var unifedorderResult       = cacheStrategy.Get <UnifiedorderResult>($"WxOpenUnifiedorderResultData-{openId}");               //获取订单信息缓存

                            if (unifedorderResult != null || !string.IsNullOrEmpty(unifedorderResult.prepay_id))
                            {
                                Senparc.Weixin.WeixinTrace.SendCustomLog("支付成功模板消息参数(小程序)", appId + " , " + openId);

                                //小程序支付,发送小程序模板消息
                                var templateData = new WxOpenTemplateMessage_PaySuccessNotice(
                                    "在线购买(小程序支付)测试", DateTime.Now, "小程序支付 | 注意:这条消息来自微信服务器异步回调,官方证明支付成功! | prepay_id:" + unifedorderResult.prepay_id,
                                    unifiedorderRequestData.OutTradeNo, unifiedorderRequestData.TotalFee, "400-031-8816", "https://weixin.senparc.com");

                                Senparc.Weixin.WxOpen.AdvancedAPIs
                                .Template.TemplateApi
                                .SendTemplateMessage(
                                    Config.SenparcWeixinSetting.WxOpenAppId, openId, templateData.TemplateId, templateData, unifedorderResult.prepay_id, "pages/index/index", "图书", "#fff00");
                            }
                            else
                            {
                                Senparc.Weixin.WeixinTrace.SendCustomLog("支付成功模板消息参数(小程序)", "prepayId未记录:" + appId + " , " + openId);
                            }
                        }
                        else
                        {
                            //微信公众号支付
                            var templateData = new WeixinTemplate_PaySuccess("https://weixin.senparc.com", "购买商品", "状态:" + return_code);
                            Senparc.Weixin.WeixinTrace.SendCustomLog("支付成功模板消息参数(公众号)", appId + " , " + openId);
                            var result = Senparc.Weixin.MP.AdvancedAPIs.TemplateApi.SendTemplateMessage(appId, openId, templateData);
                        }
                    }
                    catch (Exception ex)
                    {
                        WeixinTrace.WeixinExceptionLog(new WeixinException("支付成功模板消息异常", ex));
                        //WeixinTrace.SendCustomLog("支付成功模板消息", ex.ToString());
                    }

                    WeixinTrace.SendCustomLog("PayNotifyUrl回调", "支付成功");
                }
                else
                {
                    Senparc.Weixin.WeixinTrace.SendCustomLog("PayNotifyUrl回调", "支付失败");
                }
                string xml = string.Format(@"<xml>
<return_code><![CDATA[{0}]]></return_code>
<return_msg><![CDATA[{1}]]></return_msg>
</xml>", return_code, return_msg);

                return(Content(xml, "text/xml"));
            }
            catch (Exception ex)
            {
                WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex));
                throw;
            }
        }
Exemple #16
0
        /// <summary>
        /// JS-SDK支付回调地址(在统一下单接口中设置notify_url)
        /// </summary>
        /// <returns></returns>
        public ActionResult PayNotifyUrl()
        {
            try
            {
                ResponseHandler resHandler = new ResponseHandler(HttpContext);

                string return_code = resHandler.GetParameter("return_code");
                string return_msg  = resHandler.GetParameter("return_msg");

                string res = null;

                resHandler.SetKey(TenPayV3Info.Key);
                //验证请求是否从微信发过来(安全)
                if (resHandler.IsTenpaySign() && return_code.ToUpper() == "SUCCESS")
                {
                    res = "success";//正确的订单处理
                    //直到这里,才能认为交易真正成功了,可以进行数据库操作,但是别忘了返回规定格式的消息!
                }
                else
                {
                    res = "wrong";//错误的订单处理
                }

                /* 这里可以进行订单处理的逻辑 */

                //发送支付成功的模板消息
                try
                {
                    string appId        = Config.SenparcWeixinSetting.TenPayV3_AppId;//与微信公众账号后台的AppId设置保持一致,区分大小写。
                    string openId       = resHandler.GetParameter("openid");
                    var    templateData = new WeixinTemplate_PaySuccess("https://weixin.senparc.com", "购买商品", "状态:" + return_code);

                    Senparc.Weixin.WeixinTrace.SendCustomLog("支付成功模板消息参数", appId + " , " + openId);

                    var result = AdvancedAPIs.TemplateApi.SendTemplateMessage(appId, openId, templateData);
                }
                catch (Exception ex)
                {
                    Senparc.Weixin.WeixinTrace.SendCustomLog("支付成功模板消息", ex.ToString());
                }

                #region 记录日志

                var logDir = ServerUtility.ContentRootMapPath(string.Format("~/App_Data/TenPayNotify/{0}", SystemTime.Now.ToString("yyyyMMdd")));
                if (!Directory.Exists(logDir))
                {
                    Directory.CreateDirectory(logDir);
                }

                var logPath = Path.Combine(logDir, string.Format("{0}-{1}-{2}.txt", SystemTime.Now.ToString("yyyyMMdd"), SystemTime.Now.ToString("HHmmss"), Guid.NewGuid().ToString("n").Substring(0, 8)));

                using (var fileStream = System.IO.File.OpenWrite(logPath))
                {
                    var notifyXml = resHandler.ParseXML();
                    //fileStream.Write(Encoding.Default.GetBytes(res), 0, Encoding.Default.GetByteCount(res));

                    fileStream.Write(Encoding.Default.GetBytes(notifyXml), 0, Encoding.Default.GetByteCount(notifyXml));
                    fileStream.Close();
                }

                #endregion


                string xml = string.Format(@"<xml>
<return_code><![CDATA[{0}]]></return_code>
<return_msg><![CDATA[{1}]]></return_msg>
</xml>", return_code, return_msg);
                return(Content(xml, "text/xml"));
            }
            catch (Exception ex)
            {
                WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex));
                throw;
            }
        }
Exemple #17
0
        /// <summary>
        /// 退款申请接口
        /// </summary>
        /// <returns></returns>
        public ActionResult Refund()
        {
            try
            {
                WeixinTrace.SendCustomLog("进入退款流程", "1");

                string nonceStr = TenPayV3Util.GetNoncestr();

                string outTradeNo = HttpContext.Session.GetString("BillNo");

                WeixinTrace.SendCustomLog("进入退款流程", "2 outTradeNo:" + outTradeNo);

                string outRefundNo = "OutRefunNo-" + SystemTime.Now.Ticks;
                int    totalFee    = int.Parse(HttpContext.Session.GetString("BillFee"));
                int    refundFee   = totalFee;
                string opUserId    = TenPayV3Info.MchId;
                var    notifyUrl   = "https://sdk.weixin.senparc.com/TenPayV3/RefundNotifyUrl";
                var    dataInfo    = new TenPayV3RefundRequestData(TenPayV3Info.AppId, TenPayV3Info.MchId, TenPayV3Info.Key,
                                                                   null, nonceStr, null, outTradeNo, outRefundNo, totalFee, refundFee, opUserId, null, notifyUrl: notifyUrl);

                #region 旧方法
                //var cert = @"D:\cert\apiclient_cert_SenparcRobot.p12";//根据自己的证书位置修改
                //var password = TenPayV3Info.MchId;//默认为商户号,建议修改
                //var result = TenPayOldV3.Refund(dataInfo, cert, password);
                #endregion

                #region 新方法(Senparc.Weixin v6.4.4+)
                var result = TenPayOldV3.Refund(_serviceProvider, dataInfo);//证书地址、密码,在配置文件中设置,并在注册微信支付信息时自动记录
                #endregion

                WeixinTrace.SendCustomLog("进入退款流程", "3 Result:" + result.ToJson());
                ViewData["Message"] = $"退款结果:{result.result_code} {result.err_code_des}。您可以刷新当前页面查看最新结果。";
                return(View());
                //return Json(result, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex));

                throw;
            }

            #region 原始方法

            //RequestHandler packageReqHandler = new RequestHandler(null);

            //设置package订单参数
            //packageReqHandler.SetParameter("appid", TenPayV3Info.AppId);		 //公众账号ID
            //packageReqHandler.SetParameter("mch_id", TenPayV3Info.MchId);	     //商户号
            //packageReqHandler.SetParameter("out_trade_no", "124138540220170502163706139412"); //填入商家订单号
            ////packageReqHandler.SetParameter("out_refund_no", "");                //填入退款订单号
            //packageReqHandler.SetParameter("total_fee", "");                    //填入总金额
            //packageReqHandler.SetParameter("refund_fee", "100");                //填入退款金额
            //packageReqHandler.SetParameter("op_user_id", TenPayV3Info.MchId);   //操作员Id,默认就是商户号
            //packageReqHandler.SetParameter("nonce_str", nonceStr);              //随机字符串
            //string sign = packageReqHandler.CreateMd5Sign("key", TenPayV3Info.Key);
            //packageReqHandler.SetParameter("sign", sign);	                    //签名
            ////退款需要post的数据
            //string data = packageReqHandler.ParseXML();

            ////退款接口地址
            //string url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
            ////本地或者服务器的证书位置(证书在微信支付申请成功发来的通知邮件中)
            //string cert = @"D:\cert\apiclient_cert_SenparcRobot.p12";
            ////私钥(在安装证书时设置)
            //string password = TenPayV3Info.MchId;
            //ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
            ////调用证书
            //X509Certificate2 cer = new X509Certificate2(cert, password, X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);

            //#region 发起post请求
            //HttpWebRequest webrequest = (HttpWebRequest)HttpWebRequest.Create(url);
            //webrequest.ClientCertificates.Add(cer);
            //webrequest.Method = "post";

            //byte[] postdatabyte = Encoding.UTF8.GetBytes(data);
            //webrequest.ContentLength = postdatabyte.Length;
            //Stream stream;
            //stream = webrequest.GetRequestStream();
            //stream.Write(postdatabyte, 0, postdatabyte.Length);
            //stream.Close();

            //HttpWebResponse httpWebResponse = (HttpWebResponse)webrequest.GetResponse();
            //StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream());
            //string responseContent = streamReader.ReadToEnd();
            //#endregion

            //// var res = XDocument.Parse(responseContent);
            ////string openid = res.Element("xml").Element("out_refund_no").Value;
            //return Content("申请成功:<br>" + HttpUtility.RequestUtility.HtmlEncode(responseContent));

            #endregion
        }