public WxPayData GetNotifyData() { //接收从微信后台POST过来的数据 System.IO.Stream s = context.Request.InputStream; int count = 0; byte[] buffer = new byte[1024]; StringBuilder builder = new StringBuilder(); while ((count = s.Read(buffer, 0, 1024)) > 0) { builder.Append(Encoding.UTF8.GetString(buffer, 0, count)); } s.Flush(); s.Close(); s.Dispose(); //转换数据格式并验证签名 WxPayData data = new WxPayData(); try { data.FromXml(builder.ToString()); } catch (WxPayException ex) { log4net.LogHelper.WriteError(this.GetType(), new Exception($"微信支付回调签名错误:{ex.Message}")); //若签名错误,则立即返回结果给微信支付后台 WxPayData res = new WxPayData(); res.SetValue("return_code", "FAIL"); res.SetValue("return_msg", ex.Message); context.Response.Write(res.ToXml()); context.Response.End(); } return(data); }
/// <summary> /// 抛弃使用(用GetUnifiedOrderResult) /// </summary> /// <param name="setting"></param> /// <param name="morder"></param> /// <param name="notify_url"></param> /// <returns></returns> public WxPayData GetUnifiedOrderResultByCity(PayCenterSetting setting, CityMorders morder, string notify_url) { //统一下单 string out_trade_no = morder.orderno;//商户订单号 if (string.IsNullOrEmpty(morder.orderno)) { throw new WxPayException("UnifiedOrder response error!"); } string body = string.Empty; if (!string.IsNullOrEmpty(morder.ShowNote)) { body = morder.ShowNote; } else { string paytype = string.Empty; switch (morder.OrderType) { case (int)ArticleTypeEnum.MiniappGoods: paytype = "小程序电商模板订单"; break; case (int)ArticleTypeEnum.MiniappFoodGoods: paytype = "小程序餐饮模板订单"; break; case (int)ArticleTypeEnum.MiniappSaveMoneySet: paytype = "小程序餐饮储值"; break; case (int)ArticleTypeEnum.MiniappBargain: paytype = "小程序砍价"; break; case (int)ArticleTypeEnum.MiniappEnt: paytype = "小程序专业版"; break; case (int)ArticleTypeEnum.MiniappWXDirectPay: paytype = "小程序直接微信转账"; break; case (int)ArticleTypeEnum.PlatChildOrderPay: paytype = "平台子模版支付"; break; case (int)ArticleTypeEnum.PlatChildOrderInPlatPay: paytype = "子模版订单平台支付"; break; } body = string.Format("支付中心,{0}支付{1}元", paytype, (morder.payment_free * 0.01)); //商品描述; } string attach = string.Format("paytype={0}&orderid={1}&orderno={2}&from=city", morder.OrderType, morder.Id, morder.orderno); //自带的信息 //统一下单 WxPayData data = new WxPayData(); data.SetValue("body", body); data.SetValue("attach", attach); data.SetValue("out_trade_no", out_trade_no); data.SetValue("total_fee", total_fee); data.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss")); data.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss")); data.SetValue("goods_tag", "test"); data.SetValue("trade_type", "JSAPI"); data.SetValue("openid", openid); data.SetValue("notify_url", notify_url); WxPayData result = WxPayApi.UnifiedOrder(data, setting); if (result != null && (!result.IsSet("appid") || !result.IsSet("prepay_id") || !result.IsSet("prepay_id"))) { throw new WxPayException(result.ToJson()); } unifiedOrderResult = result; return(result); }
/// <summary> /// 返回是否关闭成功 /// </summary> /// <param name="setting"></param> /// <param name="morder"></param> /// <param name="notify_url"></param> /// <returns></returns> public bool CloseCityMorder(int citymorederId, ref string errorMsg) { CityMorders morder = new CityMordersBLL().GetModel(citymorederId); if (morder == null) { errorMsg = "未找到citymorder订单"; return(false); } PayCenterSetting setting = PayCenterSettingBLL.SingleModel.GetPayCenterSetting(morder.appid); if (setting == null) { errorMsg = "未找到用户的商户配置"; return(false); } string out_trade_no = morder.orderno;//商户订单号 if (string.IsNullOrEmpty(morder.orderno)) { return(false); } WxPayData data = new WxPayData(); data.SetValue("out_trade_no", out_trade_no); WxPayData result = WxPayApi.CloseOrder(data, setting); if (result == null || !result.GetValue("return_code").ToString().Equals("SUCCESS")) { errorMsg = "请求关闭订单失败,原因为:"; switch (data.GetValue("return_code").ToString()) { case "ORDERPAID": errorMsg += "订单已支付,不能发起关单"; break; case "SYSTEMERROR": errorMsg += "系统异常,请重新调用该API"; break; case "ORDERCLOSED": errorMsg += "订单已关闭,无法重复关闭"; break; case "SIGNERROR": errorMsg += "签名错误"; break; case "REQUIRE_POST_METHOD": errorMsg += "未使用post传递参数"; break; case "XML_FORMAT_ERROR": errorMsg += "XML格式错误"; break; } return(false); } return(true); }
/// <summary> /// 统一下单 /// </summary> /// <param name="inputObj">提交给统一下单API的参数</param> /// <param name="timeOut">超时时间</param> /// <returns></returns> public static WxPayData UnifiedOrder(WxPayData inputObj, PayCenterSetting setting, int timeOut = 60, bool livePay = false) { string url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; //检测必填参数 if (!inputObj.IsSet("out_trade_no")) { throw new WxPayException("缺少统一支付接口必填参数out_trade_no!"); } else if (!inputObj.IsSet("body")) { throw new WxPayException("缺少统一支付接口必填参数body!"); } else if (!inputObj.IsSet("total_fee")) { throw new WxPayException("缺少统一支付接口必填参数total_fee!"); } else if (!inputObj.IsSet("trade_type")) { throw new WxPayException("缺少统一支付接口必填参数trade_type!"); } //关联参数 if (inputObj.GetValue("trade_type").ToString() == "JSAPI" && !inputObj.IsSet("openid")) { throw new WxPayException("统一支付接口中,缺少必填参数openid!trade_type为JSAPI时,openid为必填参数!"); } if (inputObj.GetValue("trade_type").ToString() == "NATIVE" && !inputObj.IsSet("product_id")) { throw new WxPayException("统一支付接口中,缺少必填参数product_id!trade_type为JSAPI时,product_id为必填参数!"); } //异步通知url未设置,则使用配置文件中的url if (!inputObj.IsSet("notify_url") || string.IsNullOrEmpty(inputObj.GetValue("notify_url").ToString())) { inputObj.SetValue("notify_url", WxPayConfig.NOTIFY_URL);//异步通知url } if (livePay) { inputObj.SetValue("notify_url", inputObj.GetValue("notify_url").ToString().Replace("/pay/", "/live/"));//异步通知url,直播要跳到直播回调 } string appid = WxPayConfig.APPID; string mch_id = WxPayConfig.MCHID; string key = string.Empty; if (setting != null && setting.Id > 0) { appid = setting.Appid; mch_id = setting.Mch_id; key = setting.Key; } inputObj.SetValue("appid", appid); //公众账号ID inputObj.SetValue("mch_id", mch_id); //商户号 inputObj.SetValue("spbill_create_ip", WxPayConfig.IP); //终端ip inputObj.SetValue("nonce_str", GenerateNonceStr()); //随机字符串 //log4net.LogHelper.WriteInfo(typeof(WxPayApi), inputObj.ToJson()); //签名 inputObj.SetValue("sign", inputObj.MakeSign(key)); string xml = inputObj.ToXml(); string response = WxHelper.Post(xml, url, false, setting, timeOut); //log4net.LogHelper.WriteInfo(typeof(WxPayApi), "UnifiedOrder().response=" + response); WxPayData result = new WxPayData(); result.FromXml(response); return(result); }
/// <summary> /// 企业付款 /// </summary> /// <param name="inputObj">企业付款接口的参数</param> /// <param name="timeOut">企业付款接口超时时间</param> /// <returns></returns> public static WxPayData CompanyPay(WxPayData inputObj, PayCenterSetting setting, int timeOut = 20) { string url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; string appid = WxPayConfig.APPID; string mch_id = WxPayConfig.MCHID; string key = string.Empty; if (setting != null && setting.Id > 0) { appid = setting.Appid; mch_id = setting.Mch_id; key = setting.Key; } inputObj.SetValue("mch_appid", appid); //公众账号ID inputObj.SetValue("mchid", mch_id); //商户号 inputObj.SetValue("spbill_create_ip", WxPayConfig.IP); //IP inputObj.SetValue("nonce_str", GenerateNonceStr()); //随机字符串 inputObj.SetValue("check_name", "NO_CHECK"); //校验用户姓名,不需要校验,必选项,可选类型有: inputObj.SetValue("sign", inputObj.MakeSign(key)); //签名 //NO_CHECK:不校验真实姓名 //FORCE_CHECK:强校验真实姓名(未实名认证的用户会校验失败,无法转账) //OPTION_CHECK:针对已实名认证的用户才校验真实姓名(未实名认证用户不校验,可以转账成功) // log4net.LogHelper.WriteInfo(typeof(CompanyPay), "用户提现请求参数:" + inputObj.ToJson()); DrawcashResult drawresult = new DrawcashResult(); if (setting != null) { drawresult.mch_id = setting.Mch_id; drawresult.appid = setting.Appid; } //检测必填参数 if (!inputObj.IsSet("mch_appid")) { throw new WxPayException("企业付款中,公众账号appID必填!"); } if (!inputObj.IsSet("mchid")) { throw new WxPayException("企业付款中,微信支付分配的商户号mchid必填!"); } if (!inputObj.IsSet("nonce_str")) { throw new WxPayException("企业付款中,随机字符串nonce_str必填!"); } else { drawresult.nonce_str = inputObj.GetValue("nonce_str").ToString(); } if (!inputObj.IsSet("sign")) { throw new WxPayException("企业付款中,签名sign必填!"); } else { drawresult.sign = inputObj.GetValue("sign").ToString(); } if (!inputObj.IsSet("partner_trade_no")) { throw new WxPayException("企业付款中,商户订单号partner_trade_no必填!"); } else { drawresult.partner_trade_no = inputObj.GetValue("partner_trade_no").ToString(); } if (!inputObj.IsSet("openid")) { throw new WxPayException("企业付款中,用户openid必填!"); } else { drawresult.openid = inputObj.GetValue("openid").ToString(); } string error = string.Empty; //if (new DrawBackUserBLL().CheckEnable(0, 0, drawresult.openid)) //{ // throw new WxPayException("黑名单!"); //} if (!inputObj.IsSet("check_name")) { throw new WxPayException("企业付款中,校验用户姓名check_name必填!"); } else { drawresult.check_name = inputObj.GetValue("check_name").ToString(); } if (!inputObj.IsSet("amount")) { throw new WxPayException("企业付款中,金额amount必填!"); } else { drawresult.amount = Convert.ToInt32(inputObj.GetValue("amount").ToString()); } if (!inputObj.IsSet("desc")) { throw new WxPayException("企业付款中,企业付款描述信息desc必填!"); } else { drawresult.desc = inputObj.GetValue("desc").ToString(); if (inputObj.GetValue("desc").ToString().Length >= 50) { inputObj.SetValue("desc", inputObj.GetValue("desc").ToString().Substring(0, 46) + "..."); } } if (!inputObj.IsSet("spbill_create_ip")) { throw new WxPayException("企业付款中,Ip地址spbill_create_ip必填!"); } else { drawresult.spbill_create_ip = inputObj.GetValue("spbill_create_ip").ToString(); } if (inputObj.IsSet("re_user_name")) { drawresult.re_user_name = inputObj.GetValue("re_user_name").ToString(); } string xml = inputObj.ToXml(); drawresult.CreateTime = DateTime.Now; //post之前,增加记录 int id = Convert.ToInt32(DrawcashResultBLL.SingleModel.Add(drawresult)); drawresult.id = id; // try { string response = WxHelper.Post(xml, url, true, setting, 30); if (string.IsNullOrEmpty(response)) { return(null); } WxPayData result = new WxPayData(); result.FromXml(response, false); if (result != null) { drawresult.return_code = result.GetValue("return_code") == null ? "" : result.GetValue("return_code").ToString(); drawresult.return_msg = result.GetValue("return_msg") == null ? "" : result.GetValue("return_msg").ToString(); drawresult.nonce_str = result.GetValue("nonce_str") == null ? "" : result.GetValue("nonce_str").ToString(); drawresult.result_code = result.GetValue("result_code") == null ? "" : result.GetValue("result_code").ToString(); drawresult.err_code = result.GetValue("err_code") == null ? "" : result.GetValue("err_code").ToString(); drawresult.err_code_des = result.GetValue("err_code_des") == null ? "" : result.GetValue("err_code_des").ToString(); drawresult.payment_time = DateTime.Now; drawresult.payment_no = result.GetValue("payment_no") == null ? "" : result.GetValue("payment_no").ToString(); DrawcashResultBLL.SingleModel.Update(drawresult); } return(result); } catch (Exception ex) { log4net.LogHelper.WriteError(typeof(WxPayApi), new Exception("提现出现错误,错误信息:" + ex.Message)); return(null); } }
public override void ProcessNotify() { try { WxPayData notifyData = GetNotifyData(); //检查支付结果中transaction_id是否存在 if (!notifyData.IsSet("transaction_id") || !notifyData.IsSet("appid")) { //若transaction_id不存在,则立即返回结果给微信支付后台 WxPayData res = new WxPayData(); res.SetValue("return_code", "FAIL"); res.SetValue("return_msg", "支付结果中微信订单号不存在"); log4net.LogHelper.WriteError(GetType(), new Exception("transaction_id不存在 : " + res.ToXml())); context.Response.Write(res.ToXml()); context.Response.End(); return; } string transactionId = notifyData.GetValue("transaction_id").ToString(); //别删该日志 log4net.LogHelper.WriteInfo(this.GetType(), $"微信支付回调返回:{transactionId}"); string appid = notifyData.GetValue("appid").ToString(); PayCenterSetting setting = PayCenterSettingBLL.SingleModel.GetPayCenterSetting(appid); //增加重复回调判断 int re = RedisUtil.Get <int>(string.Format(MemCacheKey.ProcessNotify, transactionId)); if (re != 0) { return; } RedisUtil.Set(string.Format(MemCacheKey.ProcessNotify, transactionId), 1, TimeSpan.FromMinutes(30)); //查询订单,判断订单真实性 if (!QueryOrder(transactionId, setting)) { //若订单查询失败,则立即返回结果给微信支付后台 WxPayData res = new WxPayData(); res.SetValue("return_code", "FAIL"); res.SetValue("return_msg", "订单查询失败"); log4net.LogHelper.WriteError(GetType(), new Exception("订单查询失败: " + notifyData.ToJson())); context.Response.Write(res.ToXml()); context.Response.End(); } //查询订单成功 else { //说付款成功:插入记录 //这里要注意,微信通知过来之后,15秒之内没有给微信回复处理状态,微信还会第二次,第三次通知。 //带过来的信息一模一样,所以这要做标志判断,万一处理过程出现问题没有给微信回复。 //在以后多次请求的时候避免多次进行业务处理,插入多条记录 PayResult result = notifyData.ToPayResult(); if (result == null) { return; } int id = Convert.ToInt32(PayResultBLL.SingleModel.Add(result));//插入记录,论坛,直播、有约 result.Id = id; NotifyOper(result); } } catch (Exception ex) { log4net.LogHelper.WriteError(typeof(ResultNotify), ex); } finally { //最后要给微信放回接收成功数据,不然微信会连续多次发送同样请求 WxPayData res = new WxPayData(); res.SetValue("return_code", "SUCCESS"); res.SetValue("return_msg", "OK"); context.Response.Write(res.ToXml()); context.Response.End(); } }