/// <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); }
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); }
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 ? "通过" : "不通过")}" })); }
/// <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")); }
/// <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); }
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); }
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)); } }
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; } }
/// <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())); } }
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; } }
/// <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); } }
/// <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); }
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)); }
/// <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; } }
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("您已取消授权!")); } }
/// <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); } }
/// <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); } }
/// <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); }
/// <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); }
/// <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); }
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 }); } }
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); } }
/// <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())); } }
/// <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)); }
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); } }
//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; } }
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()); }
/// <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); }