/// <summary> /// 检查支付状态 /// </summary> public override void CheckPayState(PayParameter parameter) { try { WxPayConfig config = new WxPayAPI.WxPayConfig(PayFactory.GetInterfaceXmlConfig(PayInterfaceType.WeiXinScanQRCode, parameter.TradeID)); WxPayData queryOrderInput = new WxPayData(); queryOrderInput.SetValue("out_trade_no", parameter.TradeID); WxPayData result = WxPayApi.OrderQuery(queryOrderInput, config); string xml = result.ToXml(); PayFactory.OnLog(parameter.TradeID, xml); if (result.GetValue("return_code").ToString() == "SUCCESS" && result.GetValue("result_code").ToString() == "SUCCESS") { //支付成功 if (result.GetValue("trade_state").ToString() == "SUCCESS") { //触发回调函数 PayFactory.OnPaySuccessed(parameter.TradeID, xml); return; } else if (result.GetValue("trade_state").ToString() == "NOTPAY") { //这是一开始生成二维码后,会是这个状态 return; } } } catch { } }
public virtual RefoundResult Refound(RefoundParameter parameter) { WxPayConfig config = new WxPayAPI.WxPayConfig(PayFactory.GetInterfaceXmlConfig(PayInterfaceType.WeiXinBarcode, parameter.TradeID)); WxPayData data = new WxPayData(); data.SetValue("out_trade_no", parameter.TradeID); data.SetValue("total_fee", (int)(parameter.TotalAmount * 100)); //订单总金额 data.SetValue("refund_fee", (int)(parameter.Amount * 100)); //退款金额 data.SetValue("out_refund_no", Guid.NewGuid().ToString()); //随机生成商户退款单号 data.SetValue("op_user_id", config.MCHID); //操作员,默认为商户号 WxPayData result = WxPayApi.Refund(data, config); //提交退款申请给API,接收返回数据 string err = result.GetValue("err_code_des") as string; RefoundResult finallyResult = new RefoundResult(); if (result.GetValue("return_code").ToString() == "SUCCESS" && result.GetValue("result_code").ToString() == "SUCCESS") { //退款成功 finallyResult.Result = RefoundResult.ResultEnum.SUCCESS; } else { finallyResult.Result = RefoundResult.ResultEnum.FAIL; } finallyResult.Error = err; finallyResult.ServerMessage = result.ToXml(); return(finallyResult); }
/// <summary> /// 检查订单状态 /// </summary> public virtual void CheckPayState(PayParameter parameter) { try { WxPayConfig config = new WxPayAPI.WxPayConfig(PayFactory.GetInterfaceXmlConfig(PayInterfaceType.WeiXinBarcode, parameter.TradeID)); checkPayStateByConfig(parameter, config); } catch { } }
private void handleNotify() { using (CLog log = new CLog("weixin scan handleNotify ")) { WxPayData notifyData = GetNotifyData(); string json = notifyData.ToJson(); log.Log("xml:{0}", json); string out_trade_no = notifyData.GetValue("out_trade_no").ToString(); PayFactory.OnLog(out_trade_no, json); WxPayConfig config = new WxPayAPI.WxPayConfig(PayFactory.GetInterfaceXmlConfig(PayInterfaceType.WeiXinScanQRCode, out_trade_no)); try { notifyData.CheckSign(config); } catch (WxPayException ex) { log.Log("签名错误"); //若签名错误,则立即返回结果给微信支付后台 WxPayData res = new WxPayData(); res.SetValue("return_code", "FAIL"); res.SetValue("return_msg", ex.Message); Response.Write(res.ToXml()); Response.End(); } string result_code = notifyData.GetValue("result_code").ToString(); string return_code = notifyData.GetValue("return_code").ToString(); //out_trade_no result_code return_code if (result_code == "SUCCESS" && return_code == "SUCCESS") { PayFactory.OnPaySuccessed(out_trade_no, json); WxPayData data = new WxPayData(); data.SetValue("return_code", "SUCCESS"); data.SetValue("return_msg", "OK"); data.SetValue("appid", config.APPID); data.SetValue("mch_id", config.MCHID); data.SetValue("result_code", "SUCCESS"); data.SetValue("err_code_des", "OK"); data.SetValue("sign", data.MakeSign(config)); //log.Log("write to weixin:{0}", data.ToJson()); Response.Write(data.ToXml()); } } }
/** * * 获取收货地址js函数入口参数,详情请参考收货地址共享接口:http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_9 * @return string 共享收货地址js函数需要的参数,json格式可以直接做参数使用 */ public string GetEditAddressParameters() { string parameter = ""; try { string host = page.Request.Url.Host; string path = page.Request.Path; string queryString = page.Request.Url.Query; //这个地方要注意,参与签名的是网页授权获取用户信息时微信后台回传的完整url string url = "http://" + host + path + queryString; //构造需要用SHA1算法加密的数据 WxPayData signData = new WxPayData(); signData.SetValue("appid", WxPayConfig.GetConfig().GetAppID()); signData.SetValue("url", url); signData.SetValue("timestamp", WxPayApi.GenerateTimeStamp()); signData.SetValue("noncestr", WxPayApi.GenerateNonceStr()); signData.SetValue("accesstoken", "ACCESS_TOKEN"); string param = signData.ToUrl(); Log.Debug(this.GetType().ToString(), "SHA1 encrypt param : " + param); //SHA1加密 string addrSign = FormsAuthentication.HashPasswordForStoringInConfigFile(param, "SHA1"); Log.Debug(this.GetType().ToString(), "SHA1 encrypt result : " + addrSign); //获取收货地址js函数入口参数 WxPayData afterData = new WxPayData(); afterData.SetValue("appId", WxPayConfig.GetConfig().GetAppID()); afterData.SetValue("scope", "jsapi_address"); afterData.SetValue("signType", "sha1"); afterData.SetValue("addrSign", addrSign); afterData.SetValue("timeStamp", signData.GetValue("timestamp")); afterData.SetValue("nonceStr", signData.GetValue("noncestr")); //转为json格式 parameter = afterData.ToJson(); Log.Debug(this.GetType().ToString(), "Get EditAddressParam : " + parameter); } catch (Exception ex) { Log.Error(this.GetType().ToString(), ex.ToString()); throw new WxPayException(ex.ToString()); } return(parameter); }
/** * 提交被扫支付API * 收银员使用扫码设备读取微信用户刷卡授权码以后,二维码或条码信息传送至商户收银台, * 由商户收银台或者商户后台调用该接口发起支付。 * @param WxPayData inputObj 提交给被扫支付API的参数 * @param int timeOut 超时时间 * @throws WxPayException * @return 成功时返回调用结果,其他抛异常 */ public static WxPayData Micropay(WxPayData inputObj, int timeOut = 10) { string url = "https://api.mch.weixin.qq.com/pay/micropay"; //检测必填参数 if (!inputObj.IsSet("body")) { throw new WxPayException("提交被扫支付API接口中,缺少必填参数body!"); } else if (!inputObj.IsSet("out_trade_no")) { throw new WxPayException("提交被扫支付API接口中,缺少必填参数out_trade_no!"); } else if (!inputObj.IsSet("total_fee")) { throw new WxPayException("提交被扫支付API接口中,缺少必填参数total_fee!"); } else if (!inputObj.IsSet("auth_code")) { throw new WxPayException("提交被扫支付API接口中,缺少必填参数auth_code!"); } inputObj.SetValue("spbill_create_ip", WxPayConfig.GetConfig().GetIp()); //终端ip inputObj.SetValue("appid", WxPayConfig.GetConfig().GetAppID()); //公众账号ID inputObj.SetValue("mch_id", WxPayConfig.GetConfig().GetMchID()); //商户号 inputObj.SetValue("nonce_str", Guid.NewGuid().ToString().Replace("-", "")); //随机字符串 inputObj.SetValue("sign_type", WxPayData.SIGN_TYPE_MD5); //签名类型 inputObj.SetValue("sign", inputObj.MakeSign()); //签名 string xml = inputObj.ToXml(); var start = DateTime.Now;//请求开始时间 Log.Debug("WxPayApi", "MicroPay request : " + xml); string response = HttpService.Post(xml, url, false, timeOut);//调用HTTP通信接口以提交数据到API Log.Debug("WxPayApi", "MicroPay response : " + response); var end = DateTime.Now; int timeCost = (int)((end - start).TotalMilliseconds);//获得接口耗时 //将xml格式的结果转换为对象以返回 WxPayData result = new WxPayData(); result.FromXml(response); ReportCostTime(url, timeCost, result);//测速上报 return(result); }
/** * * 申请退款 * @param WxPayData inputObj 提交给申请退款API的参数 * @param int timeOut 超时时间 * @throws WxPayException * @return 成功时返回接口调用结果,其他抛异常 */ public static WxPayData Refund(WxPayData inputObj, WxPayConfig config, int timeOut = 6) { string url = "https://api.mch.weixin.qq.com/secapi/pay/refund"; //检测必填参数 if (!inputObj.IsSet("out_trade_no") && !inputObj.IsSet("transaction_id")) { throw new WxPayException("退款申请接口中,out_trade_no、transaction_id至少填一个!"); } else if (!inputObj.IsSet("out_refund_no")) { throw new WxPayException("退款申请接口中,缺少必填参数out_refund_no!"); } else if (!inputObj.IsSet("total_fee")) { throw new WxPayException("退款申请接口中,缺少必填参数total_fee!"); } else if (!inputObj.IsSet("refund_fee")) { throw new WxPayException("退款申请接口中,缺少必填参数refund_fee!"); } else if (!inputObj.IsSet("op_user_id")) { throw new WxPayException("退款申请接口中,缺少必填参数op_user_id!"); } inputObj.SetValue("appid", config.APPID); //公众账号ID inputObj.SetValue("mch_id", config.MCHID); //商户号 inputObj.SetValue("nonce_str", Guid.NewGuid().ToString().Replace("-", "")); //随机字符串 inputObj.SetValue("sign", inputObj.MakeSign(config)); //签名 string xml = inputObj.ToXml(); var start = DateTime.Now; string response = HttpService.Post(config, xml, url, true, timeOut);//调用HTTP通信接口提交数据到API var end = DateTime.Now; int timeCost = (int)((end - start).TotalMilliseconds);//获得接口耗时 //将xml格式的结果转换为对象以返回 WxPayData result = new WxPayData(); result.FromXml(response); result.CheckSign(config); ReportCostTime(config, url, timeCost, result);//测速上报 return(result); }
/// <summary> /// 申请退款 /// </summary> /// <param name="config">微信支付设置</param> /// <param name="inputObj">提交给申请退款API的参数</param> /// <param name="timeOut">超时时间</param> /// <returns></returns> public static WxPayData Refund( WxPayConfig config, WxPayData inputObj, int timeOut = 6) { string url = "https://api.mch.weixin.qq.com/secapi/pay/refund"; // 检测必填参数 if (!inputObj.IsSet("out_trade_no") && !inputObj.IsSet("transaction_id")) { throw new WxPayException("退款申请接口中,out_trade_no、transaction_id至少填一个!"); } else if (!inputObj.IsSet("out_refund_no")) { throw new WxPayException("退款申请接口中,缺少必填参数out_refund_no!"); } else if (!inputObj.IsSet("total_fee")) { throw new WxPayException("退款申请接口中,缺少必填参数total_fee!"); } else if (!inputObj.IsSet("refund_fee")) { throw new WxPayException("退款申请接口中,缺少必填参数refund_fee!"); } else if (!inputObj.IsSet("op_user_id")) { throw new WxPayException("退款申请接口中,缺少必填参数op_user_id!"); } inputObj.SetValue("appid", config.APPID); // 公众账号ID inputObj.SetValue("mch_id", config.MCHID); // 商户号 inputObj.SetValue("nonce_str", GenerateNonceStr()); // 随机字符串 inputObj.SetValue("sign", inputObj.MakeSign(config)); // 签名 string xml = inputObj.ToXml(); var logManager = Application.Ioc.Resolve <LogManager>(); logManager.LogDebug("WxPay Refund request: " + xml); string response = WxPayHttpService.Post(config, xml, url, true, timeOut); logManager.LogDebug("WxPay Refund response: " + response); // 将xml格式的结果转换为对象以返回 var result = new WxPayData(); result.FromXml(config, response); return(result); }
/** * @values格式化成能在Web页面上显示的结果(因为web页面上不能直接输出xml格式的字符串) */ public string ToPrintStr(WxPayConfig config) { string str = ""; foreach (KeyValuePair <string, object> pair in m_values) { if (pair.Value == null) { Log.Error(this.GetType().ToString(), "WxPayData内部含有值为null的字段!", config); throw new WxPayException("WxPayData内部含有值为null的字段!"); } str += string.Format("{0}={1}<br>", pair.Key, pair.Value.ToString()); } Log.Debug(this.GetType().ToString(), "Print in Web Page : " + str, config); return(str); }
/** * * 测速上报接口实现 * @param WxPayData inputObj 提交给测速上报接口的参数 * @param int timeOut 测速上报接口超时时间 * @throws WxPayException * @return 成功时返回测速上报接口返回的结果,其他抛异常 */ public static WxPayData Report(WxPayData inputObj, int timeOut = 1) { string url = "https://api.mch.weixin.qq.com/payitil/report"; //检测必填参数 if (!inputObj.IsSet("interface_url")) { throw new WxPayException("接口URL,缺少必填参数interface_url!"); } if (!inputObj.IsSet("return_code")) { throw new WxPayException("返回状态码,缺少必填参数return_code!"); } if (!inputObj.IsSet("result_code")) { throw new WxPayException("业务结果,缺少必填参数result_code!"); } if (!inputObj.IsSet("user_ip")) { throw new WxPayException("访问接口IP,缺少必填参数user_ip!"); } if (!inputObj.IsSet("execute_time_")) { throw new WxPayException("接口耗时,缺少必填参数execute_time_!"); } inputObj.SetValue("appid", WxPayConfig.GetConfig().GetAppID()); //公众账号ID inputObj.SetValue("mch_id", WxPayConfig.GetConfig().GetMchID()); //商户号 inputObj.SetValue("user_ip", WxPayConfig.GetConfig().GetIp()); //终端ip inputObj.SetValue("time", DateTime.Now.ToString("yyyyMMddHHmmss")); //商户上报时间 inputObj.SetValue("nonce_str", GenerateNonceStr()); //随机字符串 inputObj.SetValue("sign_type", WxPayData.SIGN_TYPE_MD5); //签名类型 inputObj.SetValue("sign", inputObj.MakeSign()); //签名 string xml = inputObj.ToXml(); Log.Info("WxPayApi", "Report request : " + xml); string response = HttpService.Post(xml, url, false, timeOut); Log.Info("WxPayApi", "Report response : " + response); WxPayData result = new WxPayData(); result.FromXml(response); return(result); }
//查询订单 private bool QueryOrder(string transaction_id, WxPayConfig config) { WxPayData req = new WxPayData(); req.SetValue("transaction_id", transaction_id); WxPayData res = WxPayApi.OrderQuery(req, config); if (res.GetValue("return_code").ToString() == "SUCCESS" && res.GetValue("result_code").ToString() == "SUCCESS") { return(true); } else { return(false); } }
/** * 生成扫描支付模式一URL * @param productId 商品ID * @return 模式一URL */ public string GetPrePayUrl(string productId, WxPayConfig config) { Log.Info(this.GetType().ToString(), "Native pay mode 1 url is producing...", config); WxPayData data = new WxPayData(); data.SetValue("appid", config.APPID); //公众帐号id data.SetValue("mch_id", config.MCHID); //商户号 data.SetValue("time_stamp", WxPayApi.GenerateTimeStamp()); //时间戳 data.SetValue("nonce_str", WxPayApi.GenerateNonceStr()); //随机字符串 data.SetValue("product_id", productId); //商品ID data.SetValue("sign", data.MakeSign(config)); //签名 string str = ToUrlParams(data.GetValues()); //转换为URL串 string url = "weixin://wxpay/bizpayurl?" + str; Log.Info(this.GetType().ToString(), "Get native pay mode 1 url : " + url, config); return(url); }
/** * * 测速上报接口实现 * @param WxPayData inputObj 提交给测速上报接口的参数 * @param int timeOut 测速上报接口超时时间 * @throws WxPayException * @return 成功时返回测速上报接口返回的结果,其他抛异常 */ public static WxPayData Report(WxPayData inputObj, WxPayConfig config, int timeOut = 1) { string url = "https://api.mch.weixin.qq.com/payitil/report"; //检测必填参数 if (!inputObj.IsSet("interface_url")) { throw new WxPayException("接口URL,缺少必填参数interface_url!"); } if (!inputObj.IsSet("return_code")) { throw new WxPayException("返回状态码,缺少必填参数return_code!"); } if (!inputObj.IsSet("result_code")) { throw new WxPayException("业务结果,缺少必填参数result_code!"); } if (!inputObj.IsSet("user_ip")) { throw new WxPayException("访问接口IP,缺少必填参数user_ip!"); } if (!inputObj.IsSet("execute_time_")) { throw new WxPayException("接口耗时,缺少必填参数execute_time_!"); } inputObj.SetValue("appid", config.APPID); //公众账号ID inputObj.SetValue("mch_id", config.MCHID); //商户号 inputObj.SetValue("user_ip", config.IP); //终端ip inputObj.SetValue("time", DateTime.Now.ToString("yyyyMMddHHmmss")); //商户上报时间 inputObj.SetValue("nonce_str", GenerateNonceStr()); //随机字符串 inputObj.SetValue("sign", inputObj.MakeSign(config)); //签名 string xml = inputObj.ToXml(); string response = HttpService.Post(config, xml, url, false, timeOut); WxPayData result = new WxPayData(); result.FromXml(response); result.CheckSign(config); return(result); }
/// <summary> /// 通过code换取网页授权access_token和openid的返回数据 /// </summary> /// <remarks> /// access_token可用于获取共享收货地址 /// openid是微信支付jsapi支付接口统一下单时必须的参数 /// 正确时返回的JSON数据包如下: /// { /// "access_token":"ACCESS_TOKEN", /// "expires_in":7200, /// "refresh_token":"REFRESH_TOKEN", /// "openid":"OPENID", /// "scope":"SCOPE", /// "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" /// } /// 更详细的说明请参考网页授权获取用户基本信息:http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html /// </remarks> /// <param name="code"></param> /// <returns></returns> public JsonData GetOpenidAndAccessTokenFromCode(string code) { try { //构造获取openid及access_token的url WxPayData data = new WxPayData(); data.SetValue("appid", WxPayConfig.GetConfig().GetAppID()); data.SetValue("secret", WxPayConfig.GetConfig().GetAppSecret()); data.SetValue("code", code); data.SetValue("grant_type", "authorization_code"); string url = "https://api.weixin.qq.com/sns/oauth2/access_token?" + data.ToUrl(); //请求url以获取数据 string result = HttpService.Get(url); Log.Debug(this.GetType().ToString(), "GetOpenidAndAccessTokenFromCode response : " + result); //保存access_token,用于收货地址获取 JsonData jd = JsonMapper.ToObject(result); if (result.Contains("errcode")) { string errmsg = jd["errmsg"].ToString(); Log.Error(this.GetType().ToString(), errmsg); } else { Access_Token = (string)jd["access_token"]; //获取用户openid Openid = (string)jd["openid"]; Log.Debug(this.GetType().ToString(), "Get openid : " + Openid); Log.Debug(this.GetType().ToString(), "Get access_token : " + Access_Token); } return(jd); } catch (Exception ex) { Log.Error(this.GetType().ToString(), ex.ToString()); throw new WxPayException(ex.ToString()); } }
/// <summary> /// 生成签名,详见签名生成算法 /// </summary> /// <returns></returns> public string MakeSign(WxPayConfig config) { // 转url格式 string str = ToUrl(); // 在string后加入API KEY str += "&key=" + config.KEY; // MD5签名 var md5 = MD5.Create(); var bs = md5.ComputeHash(Encoding.UTF8.GetBytes(str)); var sb = new StringBuilder(); foreach (byte b in bs) { sb.Append(b.ToString("x2")); } // 所有字符转为大写 return(sb.ToString().ToUpper()); }
private WxPayData UnifiedOrder(string openId, string productId, WxPayConfig config) { //统一下单 WxPayData req = new WxPayData(); req.SetValue("body", "test"); req.SetValue("attach", "test"); req.SetValue("out_trade_no", WxPayApi.GenerateOutTradeNo(config)); req.SetValue("total_fee", 1); req.SetValue("time_start", DateTime.Now.ToString("yyyyMMddHHmmss")); req.SetValue("time_expire", DateTime.Now.AddMinutes(10).ToString("yyyyMMddHHmmss")); req.SetValue("goods_tag", "test"); req.SetValue("trade_type", "NATIVE"); req.SetValue("openid", openId); req.SetValue("product_id", productId); WxPayData result = WxPayApi.UnifiedOrder(req, config); return(result); }
/// <summary> /// 构造网页授权获取code的URL /// </remarks> public string GetRedirectURL() { //构造网页授权获取code的URL string host = _httpContext.HttpContext.Request.Host.Host; string path = _httpContext.HttpContext.Request.Path; string redirect_uri = HttpUtility.UrlEncode("http://" + host + path); WxPayData data = new WxPayData(); data.SetValue("appid", WxPayConfig.GetConfig().GetAppID()); data.SetValue("redirect_uri", redirect_uri); data.SetValue("response_type", "code"); data.SetValue("scope", "snsapi_base"); data.SetValue("state", "STATE" + "#wechat_redirect"); string url = "https://open.weixin.qq.com/connect/oauth2/authorize?" + data.ToUrl(); Log.Debug(this.GetType().ToString(), "Will Redirect to URL : " + url); return(url); }
/// <summary> /// 提交被扫支付API /// 收银员使用扫码设备读取微信用户刷卡授权码以后,二维码或条码信息传送至商户收银台, /// 由商户收银台或者商户后台调用该接口发起支付。 /// </summary> /// <param name="config">微信支付设置</param> /// <param name="inputObj">提交给被扫支付API的参数</param> /// <param name="timeOut">超时时间</param> /// <returns></returns> public static WxPayData Micropay( WxPayConfig config, WxPayData inputObj, int timeOut = 10) { string url = "https://api.mch.weixin.qq.com/pay/micropay"; // 检测必填参数 if (!inputObj.IsSet("body")) { throw new WxPayException("提交被扫支付API接口中,缺少必填参数body!"); } else if (!inputObj.IsSet("out_trade_no")) { throw new WxPayException("提交被扫支付API接口中,缺少必填参数out_trade_no!"); } else if (!inputObj.IsSet("total_fee")) { throw new WxPayException("提交被扫支付API接口中,缺少必填参数total_fee!"); } else if (!inputObj.IsSet("auth_code")) { throw new WxPayException("提交被扫支付API接口中,缺少必填参数auth_code!"); } inputObj.SetValue("spbill_create_ip", config.IP); // 终端ip inputObj.SetValue("appid", config.APPID); // 公众账号ID inputObj.SetValue("mch_id", config.MCHID); // 商户号 inputObj.SetValue("nonce_str", GenerateNonceStr()); // 随机字符串 inputObj.SetValue("sign", inputObj.MakeSign(config)); // 签名 string xml = inputObj.ToXml(); var logManager = Application.Ioc.Resolve <LogManager>(); logManager.LogDebug("WxPay Micropay request: " + xml); string response = WxPayHttpService.Post(config, xml, url, false, timeOut); logManager.LogDebug("WxPay Micropay response: " + response); // 将xml格式的结果转换为对象以返回 var result = new WxPayData(); result.FromXml(config, response); return(result); }
public override void ProcessNotify(WxPayConfig config) { WxPayData notifyData = GetNotifyData(config); Log.Info(this.GetType().ToString(), "The Pay ResultXml:" + notifyData.ToXml(config)); //检查支付结果中transaction_id是否存在 if (!notifyData.IsSet("transaction_id")) { //若transaction_id不存在,则立即返回结果给微信支付后台 WxPayData res = new WxPayData(); res.SetValue("return_code", "FAIL"); res.SetValue("return_msg", "支付结果中微信订单号不存在"); Log.Error(this.GetType().ToString(), "The Pay result is error : " + res.ToXml(config), config); page.Response.Write(res.ToXml(config)); page.Response.End(); } string transaction_id = notifyData.GetValue("transaction_id").ToString(); //查询订单,判断订单真实性 if (!QueryOrder(transaction_id, config)) { //若订单查询失败,则立即返回结果给微信支付后台 WxPayData res = new WxPayData(); res.SetValue("return_code", "FAIL"); res.SetValue("return_msg", "订单查询失败"); Log.Error(this.GetType().ToString(), "Order query failure : " + res.ToXml(config), config); page.Response.Write(res.ToXml(config)); page.Response.End(); } //查询订单成功 else { WxPayData res = new WxPayData(); res.SetValue("return_code", "SUCCESS"); res.SetValue("return_msg", "OK"); Log.Info(this.GetType().ToString(), "order query success : " + res.ToXml(config), config); page.Response.Write(res.ToXml(config)); page.Response.End(); } }
/** * * 通过code换取网页授权access_token和openid的返回数据,正确时返回的JSON数据包如下: * { * "access_token":"ACCESS_TOKEN", * "expires_in":7200, * "refresh_token":"REFRESH_TOKEN", * "openid":"OPENID", * "scope":"SCOPE", * "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" * } * 其中access_token可用于获取共享收货地址 * openid是微信支付jsapi支付接口统一下单时必须的参数 * 更详细的说明请参考网页授权获取用户基本信息:http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html * @失败时抛异常WxPayException */ public void GetOpenidAndAccessTokenFromCode(string code, string city) { try { //构造获取openid及access_token的url WxPayData data = new WxPayData(); data.SetValue("appid", WxPayConfig.APPID(city)); data.SetValue("secret", WxPayConfig.APPSECRET(city)); //data.SetValue("code", code); data.SetValue("js_code", code); //data.SetValue("scope", "snsapi_userinfo"); data.SetValue("grant_type", "authorization_code"); //string url = "https://api.weixin.qq.com/sns/oauth2/access_token?" + data.ToUrl(); string url = "https://api.weixin.qq.com/sns/jscode2session?" + data.ToUrl(); //请求url以获取数据 string result = HttpService.Get(url); Log.Debug(this.GetType().ToString(), "GetOpenidAndAccessTokenFromCode response : " + result); //保存access_token,用于收货地址获取 JsonData jd = JsonMapper.ToObject(result); try { this.access_token = (string)jd["access_token"]; } catch { } //获取用户openid this.openid = (string)jd["openid"]; Log.Debug(this.GetType().ToString(), "Get openid : " + openid); Log.Debug(this.GetType().ToString(), "Get access_token : " + access_token); } catch (Exception ex) { Log.Error(this.GetType().ToString(), ex.ToString()); throw new WxPayException(ex.ToString()); } }
/// <summary> /// 接收从微信支付后台发送过来的数据 /// </summary> /// <param name="config">微信支付设置</param> /// <param name="xml">微信发来的xml内容</param> /// <returns>微信支付后台返回的数据</returns> public static WxPayData GetNotifyData(WxPayConfig config, string xml) { // 接收从微信后台POST过来的数据 var logManager = Application.Ioc.Resolve <LogManager>(); logManager.LogDebug($"WxPay receive notify: {xml}"); // 转换数据格式并验证签名 WxPayData data = new WxPayData(); try { data.FromXml(config, xml); } catch (WxPayException) { // 若签名错误,则立即返回结果给微信支付后台 var msg = $"WxPay sign check error: {xml}"; logManager.LogDebug(msg); throw new WxPayException(msg); } logManager.LogDebug($"WxPay check sign success"); return(data); }
/** * @Dictionary格式转化成url参数格式 * @ return url格式串, 该串不包含sign字段值 */ public string ToUrl(WxPayConfig config) { string buff = ""; foreach (KeyValuePair <string, object> pair in m_values) { if (pair.Value == null) { Log.Error(this.GetType().ToString(), "WxPayData内部含有值为null的字段!", config); throw new WxPayException("WxPayData内部含有值为null的字段!"); } if (pair.Key != "sign" && pair.Value.ToString() != "") { buff += pair.Key + "=" + pair.Value + "&"; } } buff = buff.Trim('&'); return(buff); }
/// <summary> /// 接收从微信支付后台发送过来的数据并验证签名 /// </summary> /// <returns>微信支付后台返回的数据</returns> public WxPayData GetNotifyData(WxPayConfig config) { //接收从微信后台POST过来的数据 System.IO.Stream s = page.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(); Log.Info(this.GetType().ToString(), "Receive data from WeChat : " + builder.ToString(), config); //转换数据格式并验证签名 WxPayData data = new WxPayData(); try { data.FromXml(builder.ToString(), config); } catch (WxPayException ex) { //若签名错误,则立即返回结果给微信支付后台 WxPayData res = new WxPayData(); res.SetValue("return_code", "FAIL"); res.SetValue("return_msg", ex.Message); Log.Error(this.GetType().ToString(), "Sign check error : " + res.ToXml(config), config); page.Response.Write(res.ToXml(config)); page.Response.End(); } Log.Info(this.GetType().ToString(), "Check sign success", config); return(data); }
/** * 下载对账单 * @param WxPayData inputObj 提交给下载对账单API的参数 * @param int timeOut 接口超时时间 * @throws WxPayException * @return 成功时返回,其他抛异常 */ public static WxPayData DownloadBill(WxPayData inputObj, int tid, int timeOut = 6) { string url = "https://api.mch.weixin.qq.com/pay/downloadbill"; //检测必填参数 if (!inputObj.IsSet("bill_date")) { throw new WxPayException("对账单接口中,缺少必填参数bill_date!"); } WxPayConfig wx = new WxPayConfig(tid); inputObj.SetValue("appid", wx.APPID); //公众账号ID inputObj.SetValue("mch_id", wx.MCHID); //商户号 inputObj.SetValue("nonce_str", GenerateNonceStr()); //随机字符串 inputObj.SetValue("sign", inputObj.MakeSign(tid)); //签名 string xml = inputObj.ToXml(); Log.Debug("WxPayApi", "DownloadBill request : " + xml); string response = HttpService.Post(xml, url, false, timeOut);//调用HTTP通信接口以提交数据到API Log.Debug("WxPayApi", "DownloadBill result : " + response); WxPayData result = new WxPayData(); //若接口调用失败会返回xml格式的结果 if (response.Substring(0, 5) == "<xml>") { result.FromXml(response, tid); } //接口调用成功则返回非xml格式的数据 else { result.SetValue("result", response); } return(result); }
/** * @生成签名,详见签名生成算法 * @return 签名, sign字段不参加签名 */ public string MakeSign(int tid) { try { //转url格式 string str = ToUrl(); //在string后加入API KEY WxPayConfig wx = new WxPayConfig(tid); str += "&key=" + wx.KEY; //MD5加密 var md5 = MD5.Create(); var bs = md5.ComputeHash(Encoding.UTF8.GetBytes(str)); var sb = new StringBuilder(); foreach (byte b in bs) { sb.Append(b.ToString("x2")); } //所有字符转为大写 return(sb.ToString().ToUpper()); } catch { return(""); } }
/// <summary> /// 检测签名是否正确 /// </summary> /// <returns></returns> public void CheckSign(WxPayConfig config) { // 如果没有设置签名,则跳过检测 if (!IsSet("sign")) { throw new WxPayException("WxPayData签名不存在!"); } // 如果设置了签名但是签名为空,则抛异常 else if (GetValue("sign") == null || GetValue("sign").ToString() == "") { throw new WxPayException("WxPayData签名存在但不合法!"); } // 获取接收到的签名 string return_sign = GetValue("sign").ToString(); // 在本地计算新的签名 string cal_sign = MakeSign(config); if (cal_sign != return_sign) { throw new WxPayException("WxPayData签名验证错误!"); } }
/// <summary> /// 下载对账单 /// </summary> /// <param name="config">微信支付设置</param> /// <param name="inputObj">提交给下载对账单API的参数</param> /// <param name="timeOut">接口超时时间</param> /// <returns></returns> public static WxPayData DownloadBill( WxPayConfig config, WxPayData inputObj, int timeOut = 6) { string url = "https://api.mch.weixin.qq.com/pay/downloadbill"; // 检测必填参数 if (!inputObj.IsSet("bill_date")) { throw new WxPayException("对账单接口中,缺少必填参数bill_date!"); } inputObj.SetValue("appid", config.APPID); // 公众账号ID inputObj.SetValue("mch_id", config.MCHID); // 商户号 inputObj.SetValue("nonce_str", GenerateNonceStr()); // 随机字符串 inputObj.SetValue("sign", inputObj.MakeSign(config)); // 签名 string xml = inputObj.ToXml(); var logManager = Application.Ioc.Resolve <LogManager>(); logManager.LogDebug("WxPay DownloadBill request: " + xml); string response = WxPayHttpService.Post(config, xml, url, false, timeOut); logManager.LogDebug("WxPay DownloadBill response: " + response); WxPayData result = new WxPayData(); // 若接口调用失败会返回xml格式的结果 // 接口调用成功则返回非xml格式的数据 if (response.Substring(0, 5) == "<xml>") { result.FromXml(config, response); } else { result.SetValue("result", response); } return(result); }
/** * 下载对账单 * @param WxPayData inputObj 提交给下载对账单API的参数 * @param int timeOut 接口超时时间 * @throws WxPayException * @return 成功时返回,其他抛异常 */ public static WxPayData DownloadBill(WxPayData inputObj, int timeOut = 60) { string url = "https://api.mch.weixin.qq.com/sandboxnew/pay/downloadbill"; //检测必填参数 if (!inputObj.IsSet("bill_date")) { throw new WxPayException("对账单接口中,缺少必填参数bill_date!"); } inputObj.SetValue("appid", WxPayConfig.GetConfig().GetAppID()); //公众账号ID inputObj.SetValue("mch_id", WxPayConfig.GetConfig().GetMchID()); //商户号 inputObj.SetValue("nonce_str", GenerateNonceStr()); //随机字符串 inputObj.SetValue("sign_type", WxPayData.SIGN_TYPE_HMAC_SHA256); //签名类型 inputObj.SetValue("sign", inputObj.MakeSign(WxPayData.SIGN_TYPE_MD5, GetSandboxSignkey())); string xml = inputObj.ToXml(); Log.Debug("WxPayApi", "DownloadBill request : " + xml); string response = HttpService.Post(xml, url, false, timeOut);//调用HTTP通信接口以提交数据到API Log.Debug("WxPayApi", "DownloadBill result : " + response); WxPayData result = new WxPayData(); //若接口调用失败会返回xml格式的结果 if (response.Substring(0, 5) == "<xml>") { result.FromXml(response); } //接口调用成功则返回非xml格式的数据 else { result.SetValue("result", response); } return(result); }
/** * * 查询退款 * 提交退款申请后,通过该接口查询退款状态。退款有一定延时, * 用零钱支付的退款20分钟内到账,银行卡支付的退款3个工作日后重新查询退款状态。 * out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个 * @param WxPayData inputObj 提交给查询退款API的参数 * @param int timeOut 接口超时时间 * @throws WxPayException * @return 成功时返回,其他抛异常 */ public static WxPayData RefundQuery(WxPayData inputObj, int tid, int timeOut = 6) { string url = "https://api.mch.weixin.qq.com/pay/refundquery"; //检测必填参数 if (!inputObj.IsSet("out_refund_no") && !inputObj.IsSet("out_trade_no") && !inputObj.IsSet("transaction_id") && !inputObj.IsSet("refund_id")) { throw new WxPayException("退款查询接口中,out_refund_no、out_trade_no、transaction_id、refund_id四个参数必填一个!"); } WxPayConfig wx = new WxPayConfig(tid); inputObj.SetValue("appid", wx.APPID); //公众账号ID inputObj.SetValue("mch_id", wx.MCHID); //商户号 inputObj.SetValue("nonce_str", GenerateNonceStr()); //随机字符串 inputObj.SetValue("sign", inputObj.MakeSign(tid)); //签名 string xml = inputObj.ToXml(); var start = DateTime.Now; //请求开始时间 Log.Debug("WxPayApi", "RefundQuery request : " + xml); string response = HttpService.Post(xml, url, false, timeOut);//调用HTTP通信接口以提交数据到API Log.Debug("WxPayApi", "RefundQuery response : " + response); var end = DateTime.Now; int timeCost = (int)((end - start).TotalMilliseconds);//获得接口耗时 //将xml格式的结果转换为对象以返回 WxPayData result = new WxPayData(); result.FromXml(response, tid); ReportCostTime(url, timeCost, result, tid); //测速上报 return(result); }
/** * * 查询订单 * @param WxPayData inputObj 提交给查询订单API的参数 * @param int timeOut 超时时间 * @throws WxPayException * @return 成功时返回订单查询结果,其他抛异常 */ public static WxPayData OrderQuery(WxPayData inputObj, int timeOut = 6) { string url = "https://api.mch.weixin.qq.com/pay/orderquery"; //检测必填参数 if (!inputObj.IsSet("out_trade_no") && !inputObj.IsSet("transaction_id")) { throw new WxPayException("订单查询接口中,out_trade_no、transaction_id至少填一个!"); } inputObj.SetValue("appid", WxPayConfig.GetConfig().GetAppID()); //公众账号ID inputObj.SetValue("mch_id", WxPayConfig.GetConfig().GetMchID()); //商户号 inputObj.SetValue("nonce_str", WxPayApi.GenerateNonceStr()); //随机字符串 inputObj.SetValue("sign_type", WxPayData.SIGN_TYPE_MD5); //签名类型 inputObj.SetValue("sign", inputObj.MakeSign()); //签名 string xml = inputObj.ToXml(); var start = DateTime.Now; Log.Debug("WxPayApi", "OrderQuery request : " + xml); string response = HttpService.Post(xml, url, false, timeOut);//调用HTTP通信接口提交数据 Log.Debug("WxPayApi", "OrderQuery response : " + response); var end = DateTime.Now; int timeCost = (int)((end - start).TotalMilliseconds);//获得接口耗时 //将xml格式的数据转化为对象以返回 WxPayData result = new WxPayData(); result.FromXml(response); ReportCostTime(url, timeCost, result);//测速上报 return(result); }