Пример #1
0
        /// <summary>
        /// 处理视频请求
        /// </summary>
        /// <param name="requestMessage"></param>
        /// <returns></returns>
        public override IResponseMessageBase OnVideoRequest(RequestMessageVideo requestMessage)
        {
            var responseMessage = CreateResponseMessage <ResponseMessageText>();

            responseMessage.Content = "您发送了一条视频信息,ID:" + requestMessage.MediaId;

            #region    材并推送到客户端

            Task.Factory.StartNew(async() =>
            {
                //上传素材
                var dir          = Server.GetMapPath("~/App_Data/TempVideo/");
                var file         = await MediaApi.GetAsync(appId, requestMessage.MediaId, dir);
                var uploadResult = await MediaApi.UploadTemporaryMediaAsync(appId, UploadMediaFileType.video, file, 50000);
                await CustomApi.SendVideoAsync(appId, base.WeixinOpenId, uploadResult.media_id, "这是您刚才发送的视频", "这是一条视频消息");
            }).ContinueWith(async task =>
            {
                if (task.Exception != null)
                {
                    WeixinTrace.Log("OnVideoRequest()储存Video过程发生错误:", task.Exception.Message);

                    var msg = string.Format("上传素材出错:{0}\r\n{1}",
                                            task.Exception.Message,
                                            task.Exception.InnerException != null
                                    ? task.Exception.InnerException.Message
                                    : null);
                    await CustomApi.SendTextAsync(appId, base.WeixinOpenId, msg);
                }
            });

            #endregion

            return(responseMessage);
        }
Пример #2
0
        public override bool Lock(string resourceName, int retryCount, TimeSpan retryDelay)
        {
            var key         = _mamcachedStrategy.GetFinalKey(resourceName);
            var successfull = RetryLock(key, retryCount /*暂时不限制*/, retryDelay, () =>
            {
                try
                {
                    if (_mamcachedStrategy._cache.Get(key) != null)
                    {
                        return(false);//已被别人锁住,没有取得锁
                    }
                    else
                    {
                        _mamcachedStrategy._cache.Store(StoreMode.Set, key, new object(), new TimeSpan(0, 0, 10)); //创建锁
                        return(true);                                                                              //取得锁
                    }
                }
                catch (Exception ex)
                {
                    WeixinTrace.Log("Memcached同步锁发生异常:" + ex.Message);
                    return(false);
                }
            }
                                        );

            return(successfull);
        }
Пример #3
0
        public async Task <IActionResult> DecodeEncryptedData(string type, string sessionId, string encryptedData, string iv)
        {
            DecodeEntityBase decodedEntity = null;

            try
            {
                switch (type.ToUpper())
                {
                case "USERINFO":    //wx.getUserInfo()
                    decodedEntity = EncryptHelper.DecodeUserInfoBySessionId(
                        sessionId,
                        encryptedData, iv);
                    break;

                default:
                    break;
                }
            }
            catch (Exception ex)
            {
                WeixinTrace.SendCustomLog("EncryptHelper.DecodeUserInfoBySessionId 方法出错",
                                          $@"sessionId: {sessionId}
encryptedData: {encryptedData}
iv: {iv}
sessionKey: { (await SessionContainer.CheckRegisteredAsync(sessionId)
                ? (await SessionContainer.GetSessionAsync(sessionId)).SessionKey
                : "未保存sessionId")}

异常信息:
{ex.ToString()}
");
            }

            //检验水印
            var checkWatermark = false;

            if (decodedEntity != null)
            {
                checkWatermark = decodedEntity.CheckWatermark(WxOpenAppId);

                //保存用户信息(可选)
                if (checkWatermark && decodedEntity is DecodedUserInfo decodedUserInfo)
                {
                    var sessionBag = await SessionContainer.GetSessionAsync(sessionId);

                    if (sessionBag != null)
                    {
                        await SessionContainer.AddDecodedUserInfoAsync(sessionBag, decodedUserInfo);
                    }
                }
            }

            //注意:此处仅为演示,敏感信息请勿传递到客户端!
            return(Json(new
            {
                success = checkWatermark,
                //decodedEntity = decodedEntity,
                msg = $"水印验证:{(checkWatermark ? "通过" : "不通过")}"
            }));
        }
Пример #4
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"));
        }
Пример #5
0
        /// <summary>
        /// GET方式请求URL,并返回T类型
        /// </summary>
        /// <typeparam name="T">接收JSON的数据类型</typeparam>
        /// <param name="url"></param>
        /// <param name="encoding"></param>
        /// <param name="maxJsonLength">允许最大JSON长度</param>
        /// <returns></returns>
        public static T GetJson <T>(string url, Encoding encoding = null, int?maxJsonLength = null)
        {
            string returnText = RequestUtility.HttpGet(url, encoding);

            WeixinTrace.SendLog(url, returnText);

            JavaScriptSerializer js = new JavaScriptSerializer();

            if (maxJsonLength.HasValue)
            {
                js.MaxJsonLength = maxJsonLength.Value;
            }

            if (returnText.Contains("errcode"))
            {
                //可能发生错误
                WxJsonResult errorResult = js.Deserialize <WxJsonResult>(returnText);
                if (errorResult.errcode != ReturnCode.请求成功)
                {
                    //发生错误
                    throw new ErrorJsonResultException(
                              string.Format("微信请求发生错误!错误代码:{0},说明:{1}",
                                            (int)errorResult.errcode, errorResult.errmsg), null, errorResult, url);
                }
            }

            T result = js.Deserialize <T>(returnText);

            return(result);
        }
Пример #6
0
        public override bool Lock(string resourceName, int retryCount, TimeSpan retryDelay)
        {
            var successful = RetryLock(resourceName, retryCount, retryDelay, () =>
            {
                try
                {
                    if (LockPool.ContainsKey(resourceName))
                    {
                        return(false);//已被别人锁住,没有取得锁
                    }
                    else
                    {
                        LockPool.Add(resourceName, new object()); //创建锁
                        return(true);                             //取得锁
                    }
                }
                catch (Exception ex)
                {
                    WeixinTrace.Log("本地同步锁发生异常:" + ex.Message);
                    return(false);
                }
            }
                                       );

            return(successful);
        }
Пример #7
0
        public void TestAll()
        {
            var mq    = new SenparcMessageQueue();
            var count = mq.GetCount();
            var key   = DateTime.Now.Ticks.ToString();

            //Test Add()
            var item = mq.Add(key, () => WeixinTrace.Log("测试SenparcMessageQueue写入Key=A"));

            Assert.AreEqual(count + 1, mq.GetCount());
            //var hashCode = item.GetHashCode();

            //Test GetCurrentKey()
            var currentKey = mq.GetCurrentKey();

            Assert.AreEqual(key, currentKey);

            //Test GetItem
            var currentItem = mq.GetItem(currentKey);

            Assert.AreEqual(currentItem.Key, item.Key);
            Assert.AreEqual(currentItem.AddTime, item.AddTime);

            //Test Remove
            mq.Remove(key);
            Assert.AreEqual(count, mq.GetCount());
        }
        static MemcachedObjectCacheStrategy()
        {
            // //初始化memcache服务器池
            //SockIOPool pool = SockIOPool.GetInstance();
            ////设置Memcache池连接点服务器端。
            //pool.SetServers(serverlist);
            ////其他参数根据需要进行配置

            //pool.InitConnections = 3;
            //pool.MinConnections = 3;
            //pool.MaxConnections = 5;

            //pool.SocketConnectTimeout = 1000;
            //pool.SocketTimeout = 3000;

            //pool.MaintenanceSleep = 30;
            //pool.Failover = true;

            //pool.Nagle = false;
            //pool.Initialize();

            //cache = new MemcachedClient();
            //cache.EnableCompression = false;
            try
            {
                //config.Authentication.Type = typeof(PlainTextAuthenticator);
                //config.Authentication.Parameters["userName"] = "******";
                //config.Authentication.Parameters["password"] = "******";
                //config.Authentication.Parameters["zone"] = "zone";//domain?   ——Jeffrey 2015.10.20
                DateTime dt1    = DateTime.Now;
                var      config = GetMemcachedClientConfiguration();
                //var cache = new MemcachedClient(config);'


#if NET45 || NET461
                var cache = new MemcachedClient(config);
#else
                var cache = new MemcachedClient(null, config);
#endif

                var testKey   = Guid.NewGuid().ToString();
                var testValue = Guid.NewGuid().ToString();
                cache.Store(StoreMode.Set, testKey, testValue);
                var storeValue = cache.Get(testKey);
                if (storeValue as string != testValue)
                {
                    throw new Exception("MemcachedStrategy失效,没有计入缓存!");
                }
                cache.Remove(testKey);
                DateTime dt2 = DateTime.Now;

                WeixinTrace.Log(string.Format("MemcachedStrategy正常启用,启动及测试耗时:{0}ms", (dt2 - dt1).TotalMilliseconds));
            }
            catch (Exception ex)
            {
                //TODO:记录是同日志
                WeixinTrace.Log(string.Format("MemcachedStrategy静态构造函数异常:{0}", ex.Message));
            }
        }
Пример #9
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;
            }
        }
Пример #10
0
        /// <summary>
        /// OAuthScope.snsapi_base方式回调
        /// </summary>
        /// <param name="code"></param>
        /// <param name="state"></param>
        /// <param name="returnUrl">用户最初尝试进入的页面</param>
        /// <returns></returns>
        public ActionResult BaseCallback(string code, string state, string returnUrl)
        {
            try
            {
                if (string.IsNullOrEmpty(code))
                {
                    return(Content("您拒绝了授权!"));
                }

                if (state != HttpContext.Session.GetString("State"))
                {
                    //这里的state其实是会暴露给客户端的,验证能力很弱,这里只是演示一下,
                    //建议用完之后就清空,将其一次性使用
                    //实际上可以存任何想传递的数据,比如用户ID,并且需要结合例如下面的Session["OAuthAccessToken"]进行验证
                    return(Content("验证失败!请从正规途径进入!"));
                }

                //通过,用code换取access_token
                var result = OAuthApi.GetAccessToken(appId, appSecret, code);
                if (result.errcode != ReturnCode.请求成功)
                {
                    return(Content("错误:" + result.errmsg));
                }

                //下面2个数据也可以自己封装成一个类,储存在数据库中(建议结合缓存)
                //如果可以确保安全,可以将access_token存入用户的cookie中,每一个人的access_token是不一样的
                HttpContext.Session.SetString("OAuthAccessTokenStartTime", SystemTime.Now.ToString());
                HttpContext.Session.SetString("OAuthAccessToken", result.ToJson());

                //因为这里还不确定用户是否关注本微信,所以只能试探性地获取一下
                OAuthUserInfo userInfo = null;
                try
                {
                    //已关注,可以得到详细信息
                    userInfo = OAuthApi.GetUserInfo(result.access_token, result.openid);

                    if (!string.IsNullOrEmpty(returnUrl))
                    {
                        return(Redirect(returnUrl));
                    }


                    ViewData["ByBase"] = true;
                    return(View("UserInfoCallback", userInfo));
                }
                catch (ErrorJsonResultException ex)
                {
                    Console.WriteLine(ex);
                    //未关注,只能授权,无法得到详细信息
                    //这里的 ex.JsonResult 可能为:"{\"errcode\":40003,\"errmsg\":\"invalid openid\"}"
                    return(Content("用户已授权,授权Token:" + result));
                }
            }
            catch (Exception ex)
            {
                WeixinTrace.SendCustomLog("BaseCallback 发生错误", ex.ToString());
                return(Content("发生错误:" + ex.ToString()));
            }
        }
Пример #11
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;
            }
        }
Пример #12
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);
     }
 }
Пример #13
0
        /// <summary>
        /// ErrorJsonResultException
        /// </summary>
        /// <param name="message">异常消息</param>
        /// <param name="inner">内部异常</param>
        /// <param name="jsonResult">WxJsonResult</param>
        /// <param name="url">API地址</param>
        public ErrorJsonResultException(string message, Exception inner, BaseJsonResult jsonResult, string url = null)
            : base(message, inner, true)
        {
            JsonResult = jsonResult;
            Url        = url;

            WeixinTrace.ErrorJsonResultExceptionLog(this);
        }
Пример #14
0
        public ActionResult GetAuthorizerInfoResultPage(string authorizerAppId)
        {
            WeixinTrace.SendCustomLog("查询授权信息json", authorizerAppId);//记录到日志中
            var getAuthorizerInfoResult = AuthorizerContainer.GetAuthorizerInfoResult(component_AppId, authorizerAppId);

            getAuthorizerInfoResult.authorization_info.authorizer_appid = authorizerAppId;
            return(Json(getAuthorizerInfoResult, JsonRequestBehavior.AllowGet));
        }
Пример #15
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;
            }
        }
Пример #16
0
        public ActionResult Result(string openId, string template_id, int scene, string reserved)
        {
            //template_id就是微信后台可以看到的template_id

            if (reserved != Session["WeixinSubscribeMsgReserved"] as string)
            {
                //reserved用于保持请求和回调的状态,授权请后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验,开发者可以填写a-zA-Z0-9的参数值,最多128字节
                return(Content("请求错误!"));
            }

            WeixinTrace.SendCustomLog("一次性订阅消息-参数", string.Format("openId:{0},templateId:{1},scene:{2}", openId, template_id, scene));

            var action = Request.QueryString["action"];//MVC直接通过Action获取到的action参数为ActionName

            if (action == "confirm")
            {
                //发送提示
                var data = new
                {
                    content = new
                    {
                        value = "Value",
                        color = "#00ff00"
                    }
                };

                //var data1 = new
                //{
                //    content = new[]
                //    {
                //        new{
                //        value = "Value",
                //        color = "#00ff00"
                //        }
                //    }
                //};
                try
                {
                    TemplateApi.Subscribe(base.AppId, openId, template_id, scene, "这是一条“一次性订阅消息”", data);
                    return(Content("发送成功!"));
                }
                catch (ErrorJsonResultException e)
                {
                    if (e.JsonResult.errcode == ReturnCode.api功能未授权)
                    {
                        return(Content("功能正常,由于微信官方(程序或文档)问题,返回错误:" + e.JsonResult.errcode + "。请等待微信官方更新!"));
                    }
                    else
                    {
                        return(Content("发生错误:" + e.Message));
                    }
                }
            }
            else
            {
                return(Content("您已取消授权!"));
            }
        }
Пример #17
0
        /// <summary>
        /// 尝试下载
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public ActionResult Download(string guid)
        {
            var success = CheckCanDownload(guid);

            if (!success)
            {
                string message      = null;
                var    guidNotFound = !ConfigHelper.CodeCollection.ContainsKey(guid);
                if (guidNotFound)
                {
                    message = "审核失败,请从官方下载页面进入!";
                }
                else
                {
                    var codeRecord = ConfigHelper.CodeCollection[guid];
                    if (!codeRecord.AllowDownload)
                    {
                        message = string.Format("审核失败,文件不允许下载,或已经下载过!如需重新下载请刷新浏览器!(101 - {0})", guid);
                    }
                }

                message = message ?? string.Format("未通过审核,或此二维码已过期,请刷新网页后重新操作!(102 - {0})", guid);

                var file = File(Encoding.UTF8.GetBytes(message), "text/plain");
                file.FileDownloadName = "下载失败.txt";
                return(file);
            }
            else
            {
                var codeRecord = ConfigHelper.CodeCollection[guid];
                codeRecord.Used = true;
                //codeRecord.AllowDownload = false;//这里如果只允许一次下载,有的浏览器插件或者防护软件会自动访问页面上的链接,导致用户真实的下载时效
                var configHelper = new ConfigHelper();
                var filePath     = configHelper.Download(codeRecord.Version, codeRecord.IsWebVersion).Replace("/", "\\");
                //var file = File(filePath, "application/octet-stream");(此方法在.net core中会失败)

                //使用流的方式来发送
                var fs = new FileStream(filePath, FileMode.Open);
                var ms = new MemoryStream();
                fs.CopyTo(ms);
                ms.Seek(0, SeekOrigin.Begin);

                var file = File(ms, "application/octet-stream");

                var fileName = string.Format("Senparc.Weixin{0}-v{1}.{2}",
                                             codeRecord.IsWebVersion ? "-Web" : "",
                                             codeRecord.Version,
                                             filePath.Split('.').Last()//同步扩展名
                                             );

                file.FileDownloadName = fileName;

                WeixinTrace.SendCustomLog("download-path", filePath + " , " + file.FileDownloadName);

                return(file);
            }
        }
Пример #18
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)
 {
     if (!logged)
     {
         //WeixinTrace.Log(string.Format("WeixinException({0}):{1}", this.GetType().Name, message));
         WeixinTrace.WeixinExceptionLog(this);
     }
 }
Пример #19
0
        /// <summary>
        /// 发起Post请求
        /// </summary>
        /// <typeparam name="T">返回数据类型(Json对应的实体)</typeparam>
        /// <param name="url">请求Url</param>
        /// <param name="cookieContainer">CookieContainer,如果不需要则设为null</param>
        /// <param name="fileStream">文件流</param>
        /// <param name="encoding"></param>
        /// <param name="timeOut">代理请求超时时间(毫秒)</param>
        /// <param name="checkValidationResult">验证服务器证书回调自动验证</param>
        /// <returns></returns>
        public static T PostGetJson <T>(string url, CookieContainer cookieContainer = null, Stream fileStream = null, Encoding encoding = null, int timeOut = Config.TIME_OUT, bool checkValidationResult = false)
        {
            string returnText = RequestUtility.HttpPost(url, cookieContainer, fileStream, null, null, encoding, timeOut: timeOut, checkValidationResult: checkValidationResult);

            WeixinTrace.SendLog(url, returnText);

            var result = GetResult <T>(returnText);

            return(result);
        }
Пример #20
0
        /// <summary>
        /// 【异步方法】PostGetJson的异步版本
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="url"></param>
        /// <param name="cookieContainer"></param>
        /// <param name="fileStream"></param>
        /// <param name="encoding"></param>
        /// <param name="cer">证书,如果不需要则保留null</param>
        /// <param name="useAjax">是否使用Ajax请求</param>
        /// <param name="timeOut"></param>
        /// <param name="checkValidationResult"></param>
        /// <returns></returns>
        public static async Task <T> PostGetJsonAsync <T>(string url, CookieContainer cookieContainer = null, Stream fileStream = null, Encoding encoding = null, X509Certificate2 cer = null, bool useAjax = false, int timeOut = Config.TIME_OUT, bool checkValidationResult = false)
        {
            string returnText = await RequestUtility.HttpPostAsync(url, cookieContainer, fileStream, null, null, encoding, cer, useAjax, timeOut, checkValidationResult);

            WeixinTrace.SendApiLog(url, returnText);

            var result = GetResult <T>(returnText);

            return(result);
        }
Пример #21
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="message"></param>
        /// <param name="inner"></param>
        /// <param name="jsonResult"></param>
        /// <param name="url"></param>
        public ErrorJsonResultException(string message, Exception inner, WxJsonResult jsonResult, string url = null)
            : base(message, inner)
        {
            JsonResult = jsonResult;
            Url        = url;

            Log4NetLog.Logger.Error("ErrorJsonResultException", this);

            WeixinTrace.ErrorJsonResultExceptionLog(this);
        }
Пример #22
0
        public ActionResult GetPrepayid(string sessionId)
        {
            try
            {
                var sessionBag = SessionContainer.GetSession(sessionId);
                var openId = sessionBag.OpenId;


                //生成订单10位序列号,此处用时间和随机数生成,商户根据自己调整,保证唯一
                var sp_billno = string.Format("{0}{1}{2}", Config.SenparcWeixinSetting.TenPayV3_MchId /*10位*/, SystemTime.Now.ToString("yyyyMMddHHmmss"),
                        TenPayV3Util.BuildRandomStr(6));

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

                var body = "小程序微信支付Demo";
                var price = 1;//单位:分
                var xmlDataInfo = new TenPayV3UnifiedorderRequestData(WxOpenAppId, Config.SenparcWeixinSetting.TenPayV3_MchId, body, sp_billno,
                    price, Request.UserHostAddress, Config.SenparcWeixinSetting.TenPayV3_WxOpenTenpayNotify, TenPay.TenPayV3Type.JSAPI, openId, Config.SenparcWeixinSetting.TenPayV3_Key, nonceStr);

                var result = TenPayV3.Unifiedorder(xmlDataInfo);//调用统一订单接口

                WeixinTrace.SendCustomLog("统一订单接口调用结束", "请求:" + xmlDataInfo.ToJson() + "\r\n\r\n返回结果:" + result.ToJson());

                var packageStr = "prepay_id=" + result.prepay_id;

                //记录到缓存

                var cacheStrategy = CacheStrategyFactory.GetObjectCacheStrategyInstance();
                cacheStrategy.Set($"WxOpenUnifiedorderRequestData-{openId}", xmlDataInfo, TimeSpan.FromDays(4));//3天内可以发送模板消息
                cacheStrategy.Set($"WxOpenUnifiedorderResultData-{openId}", result, TimeSpan.FromDays(4));//3天内可以发送模板消息

                return Json(new
                {
                    success = true,
                    prepay_id = result.prepay_id,
                    appId = Config.SenparcWeixinSetting.WxOpenAppId,
                    timeStamp,
                    nonceStr,
                    package = packageStr,
                    //signType = "MD5",
                    paySign = TenPayV3.GetJsPaySign(WxOpenAppId, timeStamp, nonceStr, packageStr, Config.SenparcWeixinSetting.TenPayV3_Key)
                });
            }
            catch (Exception ex)
            {
                return Json(new
                {
                    success = false,
                    msg = ex.Message
                });
            }

        }
Пример #23
0
 public void ConfigOnWeixinExceptionFunc(WeixinException ex)
 {
     try
     {
         string desc    = "发生错误" + ex.GetType().Name;
         string message = ex.Message;
         WeixinTrace.SendCustomLog(desc, desc);
     }
     catch (Exception e)
     {
         WeixinTrace.SendCustomLog("OnWeixinExceptionFunc过程错误", e.Message);
     }
 }
Пример #24
0
        /// <summary>
        /// OAuthScope.snsapi_base方式回调
        /// </summary>
        /// <param name="code"></param>
        /// <param name="returnUrl">用户最初尝试进入的页面</param>
        /// <returns></returns>
        public ActionResult BaseCallback(string code, string returnUrl)
        {
            try
            {
                if (string.IsNullOrEmpty(code))
                {
                    return(Content("您拒绝了授权!"));
                }

                //通过,用code换取access_token
                var result = OAuthApi.GetAccessToken(appId, appSecret, code);
                if (result.errcode != ReturnCode.请求成功)
                {
                    return(Content("错误:" + result.errmsg));
                }

                //下面2个数据也可以自己封装成一个类,储存在数据库中(建议结合缓存)
                //如果可以确保安全,可以将access_token存入用户的cookie中,每一个人的access_token是不一样的
                HttpContext.Session.SetString("OAuthAccessTokenStartTime", SystemTime.Now.ToString());
                HttpContext.Session.SetString("OAuthAccessToken", result.ToJson());

                //因为这里还不确定用户是否关注本微信,所以只能试探性地获取一下
                OAuthUserInfo userInfo = null;
                try
                {
                    //已关注,可以得到详细信息
                    userInfo = OAuthApi.GetUserInfo(result.access_token, result.openid);

                    if (!string.IsNullOrEmpty(returnUrl))
                    {
                        return(Redirect(returnUrl));
                    }


                    ViewData["ByBase"] = true;
                    return(View("UserInfoCallback", userInfo));
                }
                catch (ErrorJsonResultException ex)
                {
                    //未关注,只能授权,无法得到详细信息
                    //这里的 ex.JsonResult 可能为:"{\"errcode\":40003,\"errmsg\":\"invalid openid\"}"
                    return(Content("用户已授权,授权Token:" + result, "text/html", Encoding.UTF8));
                }
            }
            catch (Exception ex)
            {
                WeixinTrace.SendCustomLog("BaseCallback 发生错误", ex.ToString());
                return(Content("发生错误:" + ex.ToString()));
            }
        }
Пример #25
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));
        }
Пример #26
0
        public override IResponseMessageBase OnUnknownTypeRequest(RequestMessageUnknownType requestMessage)
        {
            /*
             * 此方法用于应急处理SDK没有提供的消息类型,
             * 原始XML可以通过requestMessage.RequestDocument(或this.RequestDocument)获取到。
             * 如果不重写此方法,遇到未知的请求类型将会抛出异常(v14.8.3 之前的版本就是这么做的)
             */
            var msgType         = Senparc.NeuChar.Helpers.MsgTypeHelper.GetRequestMsgTypeString(requestMessage.RequestDocument);
            var responseMessage = this.CreateResponseMessage <ResponseMessageText>();

            responseMessage.Content = "未知消息类型:" + msgType;

            WeixinTrace.SendCustomLog("未知请求消息类型", requestMessage.RequestDocument.ToString());//记录到日志中

            return(responseMessage);
        }
        public override async Task OnMessageReceiced(WebSocketHelper webSocketHandler, ReceivedMessage receivedMessage, string originalData)
        {
            if (receivedMessage == null || string.IsNullOrEmpty(receivedMessage.Message))
            {
                return;
            }

            var message = receivedMessage.Message;

            await webSocketHandler.SendMessage("originalData:" + originalData, webSocketHandler.WebSocket.Clients.Caller);

            await webSocketHandler.SendMessage("您发送了文字:" + message, webSocketHandler.WebSocket.Clients.Caller);

            await webSocketHandler.SendMessage("正在处理中(反转文字)...", webSocketHandler.WebSocket.Clients.Caller);

            await Task.Delay(1000);

            //处理文字
            var result = string.Concat(message.Reverse());
            await webSocketHandler.SendMessage(result, webSocketHandler.WebSocket.Clients.Caller);

            var appId = Config.SenparcWeixinSetting.WxOpenAppId;//与微信小程序账号后台的AppId设置保持一致,区分大小写。

            try
            {
                var sessionBag = SessionContainer.GetSession(receivedMessage.SessionId);

                //临时演示使用固定openId
                var openId = sessionBag != null ? sessionBag.OpenId : "onh7q0DGM1dctSDbdByIHvX4imxA";// "用户未正确登陆";

                //await webSocketHandler.SendMessage("OpenId:" + openId, webSocketHandler.WebSocket.Clients.Caller);
                //await webSocketHandler.SendMessage("FormId:" + formId);

                //群发
                await webSocketHandler.SendMessage($"[群发消息] [来自 OpenId:***{openId.Substring(openId.Length - 10, 10)},昵称:{sessionBag.DecodedUserInfo?.nickName}]:{message}", webSocketHandler.WebSocket.Clients.All);
            }
            catch (Exception ex)
            {
                var msg = ex.Message + "\r\n\r\n" + originalData + "\r\n\r\nAPPID:" + appId;

                await webSocketHandler.SendMessage(msg, webSocketHandler.WebSocket.Clients.Caller); //VS2017以下如果编译不通过,可以注释掉这一行

                WeixinTrace.SendCustomLog("WebSocket OnMessageReceiced()过程出错", msg);
            }
        }
Пример #28
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;
            }
        }
Пример #29
0
        public ActionResult Index()
        {
            var guid = Guid.NewGuid().ToString("n");

            ViewData["Guid"] = guid;

            var configHelper = new ConfigHelper();

            int qrCodeId = 0;
            CreateQrCodeResult qrResult = null;

            try
            {
                //chm二维码
                qrCodeId = configHelper.GetQrCodeId();
                qrResult = MP.AdvancedAPIs.QrCodeApi.Create(appId, 10000, qrCodeId, QrCode_ActionName.QR_SCENE);

                var qrCodeUrl = MP.AdvancedAPIs.QrCodeApi.GetShowQrCodeUrl(qrResult.ticket);
                ViewData["QrCodeUrl"] = qrCodeUrl;
            }
            catch (Exception e)
            {
                WeixinTrace.SendCustomLog("Document发生appsecret错误!", e.ToString());
                var accessTokenBags = AccessTokenContainer.GetAllItems();

                WeixinTrace.SendCustomLog("当前AccessToken信息", accessTokenBags.ToJson());
            }
            finally
            {
                ConfigHelper.CodeCollection[guid] = new CodeRecord()
                {
                    Key          = guid,
                    QrCodeId     = qrCodeId,
                    QrCodeTicket = qrResult
                };//添加对应关系

                //下载版本
                var config = configHelper.GetConfig();
                ViewData["Versions"]      = config.Versions;
                ViewData["WebVersions"]   = config.WebVersions;
                ViewData["DownloadCount"] = config.DownloadCount.ToString("##,###");
            }
            return(View());
        }
Пример #30
0
        /// <summary>
        /// 事件之发送模板消息返回结果
        /// </summary>
        /// <param name="requestMessage"></param>
        /// <returns></returns>
        public override IResponseMessageBase OnEvent_TemplateSendJobFinishRequest(RequestMessageEvent_TemplateSendJobFinish requestMessage)
        {
            switch (requestMessage.Status)
            {
            case "success":
                //发送成功

                break;

            case "failed:user block":
                //送达由于用户拒收(用户设置拒绝接收公众号消息)而失败
                break;

            case "failed: system failed":
                //送达由于其他原因失败
                break;

            default:
                throw new WeixinException("未知模板消息状态:" + requestMessage.Status);
            }

            //注意:此方法内不能再发送模板消息,否则会造成无限循环!

            try
            {
                var msg = @"已向您发送模板消息
状态:{0}
MsgId:{1}
(这是一条来自MessageHandler的客服消息)".FormatWith(requestMessage.Status, requestMessage.MsgID);
                CustomApi.SendText(appId, OpenId, msg);//发送客服消息
            }
            catch (Exception e)
            {
                WeixinTrace.SendCustomLog("模板消息发送失败", e.ToString());
            }


            //无需回复文字内容
            //return requestMessage
            //    .CreateResponseMessage<ResponseMessageNoResponse>();
            return(null);
        }