微信支付后回调方法实现过程中遇到的问题记录

[WebMethod(Description = "微信回调方法")]
//参考http://blog.csdn.net/chaishen10000/article/details/52134328
public void SaveWXPayInfo()
{
  string resultFromWx = getPostStr(); //1.获取微信通知的参数  主要是获取微信那边传过来的的参数

  string phoneNumber = "";
  int ChargeMoney = 0;

  //将xml格式的数据转化为对象以返回
  WxPayData wp = new WxPayData();
  if (!string.IsNullOrEmpty(resultFromWx))
  {
    wp.FromXml(resultFromWx);
  }

  //设置支付参数
  RequestHandler paySignReqHandler = new RequestHandler(null);

  if (wp.GetValue("return_code").ToString() == "SUCCESS")
  {
    //通信成功
    if (wp.GetValue("result_code").ToString() == "SUCCESS")
    {
      //交易成功

      var service_url = System.Configuration.ConfigurationManager.AppSettings["SERVICE_URL"].ToString();

      if (wp.GetValues().Count > 0)
      {
        string appId = wp.GetValue("appid").ToString();
        string mchId = wp.GetValue("mch_id").ToString();
        string out_order_no = wp.GetValue("out_trade_no").ToString();
        string transactionId = wp.GetValue("transaction_id").ToString();
        ChargeMoney = Convert.ToInt32(wp.GetValue("total_fee").ToString());
        phoneNumber = wp.GetValue("attach").ToString();

        //验证微信支付消息真实性
        bool wxResult = checkWechatPay(transactionId, out_order_no, appId, mchId, wp.GetValue("sign").ToString(), wp.GetValue("nonce_str").ToString());

        if (wxResult)
        {
          //微信支付为真
          //调用业务逻辑方法http://10.168.1.203:7082/Service1.asmx/BuyMoney?customer_telphone=string&buyMoney=string&chargeWay=string;

          var postData = "customer_telphone=" + phoneNumber + "&buyMoney=" + ChargeMoney + "&chargeWay=微信充值";

          //调用webservice服务方法
          var res = HttpConnectToServer(service_url, postData);

          if (!string.IsNullOrEmpty(res))
          {
            var resObj = JObject.Parse(res);
            if (resObj["RESCODE"].ToString() == "1")
            {
              paySignReqHandler.SetParameter("return_code", "SUCCESS");
              paySignReqHandler.SetParameter("return_msg", "OK");
              result = "SUCCESS";
            }
            else
            {
              paySignReqHandler.SetParameter("return_code", "FAIL");
              paySignReqHandler.SetParameter("return_msg", "");
            }

          }
          else
          {
            paySignReqHandler.SetParameter("return_code", "FAIL");
            paySignReqHandler.SetParameter("return_msg", "");
          }

        }
        else
        {
          //微信支付为假(有人直接调用该服务)
          paySignReqHandler.SetParameter("return_code", "FAIL");
          paySignReqHandler.SetParameter("return_msg", "");
        }

      }
    }
    else
    {
      paySignReqHandler.SetParameter("return_code", "FAIL");
      paySignReqHandler.SetParameter("return_msg", "交易失败");
    }
  }
  else
  {
    paySignReqHandler.SetParameter("return_code", "FAIL");
    paySignReqHandler.SetParameter("return_msg", "签名失败");
  }

  //将处理结果反馈给微信
  string data = paySignReqHandler.ParseXML();
  //var resultPay = TenPayV3.Unifiedorder(data);//发送给微信服务器

  

  //下面的步骤可以防止该回调方法多次回调(通知微信服务器已处理 )

  //只要data中有SUCCESS就可以终止后续调用(防止回调方法多次执行没有的会会执行10次)

  HttpContext.Current.Response.Charset = "GB2312";
  HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");//GB2312
  HttpContext.Current.Response.Write(data);
  HttpContext.Current.Response.End();
}

 

//获得Post过来的数据
public string getPostStr()
{
  Int32 intLen = Convert.ToInt32(HttpContext.Current.Request.InputStream.Length);
  byte[] b = new byte[intLen];
  HttpContext.Current.Request.InputStream.Read(b, 0, intLen);
  return System.Text.Encoding.UTF8.GetString(b);
}

 

 

/// <summary>
/// 发送消息到服务器
/// </summary>
/// <param name="ServerPage">url</param>
/// <param name="postData"></param>
/// <returns></returns>
public string HttpConnectToServer(string ServerPage, string postData)
{
  //string postData = "strXml=" + strXml + "&strData=" + strData;

  byte[] dataArray = System.Text.Encoding.UTF8.GetBytes(postData);
  //创建请求
  HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(ServerPage);
  request.Method = "POST";
  request.ContentLength = dataArray.Length;
  request.ContentType = "application/x-www-form-urlencoded";
  //创建输入流
  Stream dataStream = null;
  try
  {
    dataStream = request.GetRequestStream();
  }
  catch (Exception)
  {
    return null;//连接服务器失败
  }

  //发送请求
  dataStream.Write(dataArray, 0, dataArray.Length);
  dataStream.Close();
  //读取返回消息
  string res = string.Empty;
  try
  {
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
    res = reader.ReadToEnd();
    reader.Close();
  }
  catch (Exception ex)
  {
    return null;//连接服务器失败
  }
  return res;
}

 

 

//验证微信支付消息真实性
public bool checkWechatPay(string transaction_id, string out_trade_no, string APPID, string MCHID)
{
  var res = false;
  int timeOut = 6;
  WxPayData data = new WxPayData();
  if (!string.IsNullOrEmpty(transaction_id))//如果微信订单号存在,则以微信订单号为准
  {
    data.SetValue("transaction_id", transaction_id);
  }
  else//微信订单号不存在,才根据商户订单号去查单
  {
    data.SetValue("out_trade_no", out_trade_no);
  }

  string url = "https://api.mch.weixin.qq.com/pay/orderquery";
  //检测必填参数
  if (!data.IsSet("out_trade_no") && !data.IsSet("transaction_id"))
  {
    throw new WxPayException("订单查询接口中,out_trade_no、transaction_id至少填一个!");
  }

  data.SetValue("appid", APPID);//公众账号ID
  data.SetValue("mch_id", MCHID);//商户号

  //这个地方我犯了一个错误  就是我直接使用微信支付结果通知中返回的sign和nonce_str 导致报了一个签名错误 浪费了比较久的时间 应该直接自己生成

  //微信支付结果通知 https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_7&index=3 
  data.SetValue("nonce_str", GenerateNonceStr());//随机字符串
  data.SetValue("sign", data.MakeSign());//签名   只掉调用微信api(WxPayAPI) 中的的方法

  string xml = data.ToXml();

  string response = HttpService.Post(xml, url, false, timeOut);//调用HTTP通信接口提交数据

  //将xml格式的数据转化为对象以返回
  WxPayData result = new WxPayData();
  result.FromXml(response);

  //ReportCostTime(url, timeCost, result);//测速上报

  if (result.GetValue("return_code").ToString() == "SUCCESS")
  {
    if (result.GetValue("trade_state").ToString() == "SUCCESS") {
      res = true;
    }
  }

  return res;
}

 

 

/**
* 生成随机串,随机串包含字母或数字
* @return 随机串
*/
public static string GenerateNonceStr()
{
  return Guid.NewGuid().ToString().Replace("-", "");
}

 

 

////////////////////////////////////////////////////////////////////////

 下面是HttpService服务中的post和get方法  做个笔记

/////////////////////////////////////////////////////////////////////////

//HttpService.Post (HttpService服务中的post方法)

public static string Post(string xml, string url, bool isUseCert, int timeout)
{
  System.GC.Collect();//垃圾回收,回收没有正常关闭的http连接

  string result = "";//返回结果

  HttpWebRequest request = null;
  HttpWebResponse response = null;
  Stream reqStream = null;

  try
  {
    //设置最大连接数
    ServicePointManager.DefaultConnectionLimit = 200;
    //设置https验证方式
    if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
    {
      ServicePointManager.ServerCertificateValidationCallback =
      new RemoteCertificateValidationCallback(CheckValidationResult);
    }

    /***************************************************************
    * 下面设置HttpWebRequest的相关属性
    * ************************************************************/
    request = (HttpWebRequest)WebRequest.Create(url);

    request.Method = "POST";
    request.Timeout = timeout * 1000;

    //设置代理服务器
    //WebProxy proxy = new WebProxy(); //定义一个网关对象
    //proxy.Address = new Uri(WxPayConfig.PROXY_URL); //网关服务器端口:端口
    //request.Proxy = proxy;

    //设置POST的数据类型和长度
    request.ContentType = "text/xml";
    byte[] data = System.Text.Encoding.UTF8.GetBytes(xml);
    request.ContentLength = data.Length;

    //这个在Post的时候,一定要加上,如果服务器返回错误,他还会继续再去请求,不会使用之前的错误数据,做返回数据
    request.ServicePoint.Expect100Continue = false;

    //是否使用证书
    if (isUseCert)
    {
      string path = HttpContext.Current.Request.PhysicalApplicationPath;
      X509Certificate2 cert = new X509Certificate2(path + WxPayConfig.SSLCERT_PATH, WxPayConfig.SSLCERT_PASSWORD);
      request.ClientCertificates.Add(cert);
      Log.Debug("WxPayApi", "PostXml used cert");
    }

    //往服务器写入数据
    reqStream = request.GetRequestStream();
    reqStream.Write(data, 0, data.Length);
    reqStream.Close();

    //获取服务端返回
    response = (HttpWebResponse)request.GetResponse();

    //获取服务端返回数据
    StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
    result = sr.ReadToEnd().Trim();
    sr.Close();
  }
  catch (System.Threading.ThreadAbortException e)
  {
    Log.Error("HttpService", "Thread - caught ThreadAbortException - resetting.");
    Log.Error("Exception message: {0}", e.Message);
    System.Threading.Thread.ResetAbort();
  }
  catch (WebException e)
  {
    Log.Error("HttpService", e.ToString());
    if (e.Status == WebExceptionStatus.ProtocolError)
    {
      Log.Error("HttpService", "StatusCode : " + ((HttpWebResponse)e.Response).StatusCode);
      Log.Error("HttpService", "StatusDescription : " + ((HttpWebResponse)e.Response).StatusDescription);
    }
    throw new WxPayException(e.ToString());
  }
  catch (Exception e)
  {
    Log.Error("HttpService", e.ToString());
    throw new WxPayException(e.ToString());
  }
  finally
  {
    //关闭连接和流
    if (response != null)
    {
      response.Close();
    }
    if(request != null)
    {
      request.Abort();
    }
  }
  return result;
}

 

//HttpService.Get(HttpService服务中的get方法)

public static string Get(string url)
{
  System.GC.Collect();
  string result = "";

  HttpWebRequest request = null;
  HttpWebResponse response = null;

  //请求url以获取数据
  try
  {
    //设置最大连接数
    ServicePointManager.DefaultConnectionLimit = 200;
    //设置https验证方式
    if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
    {
      ServicePointManager.ServerCertificateValidationCallback =
        new RemoteCertificateValidationCallback(CheckValidationResult);
    }

    /***************************************************************
    * 下面设置HttpWebRequest的相关属性
    * ************************************************************/
    request = (HttpWebRequest)WebRequest.Create(url);

    request.Method = "GET";

    //设置代理
    //WebProxy proxy = new WebProxy();
    //proxy.Address = new Uri(WxPayConfig.PROXY_URL);
    //request.Proxy = proxy;

    //获取服务器返回
    response = (HttpWebResponse)request.GetResponse();

    //获取HTTP返回数据
    StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
    result = sr.ReadToEnd().Trim();
    sr.Close();
  }
  catch (System.Threading.ThreadAbortException e)
  {
    Log.Error("HttpService","Thread - caught ThreadAbortException - resetting.");
    Log.Error("Exception message: {0}", e.Message);
    System.Threading.Thread.ResetAbort();
  }
  catch (WebException e)
  {
    Log.Error("HttpService", e.ToString());
    if (e.Status == WebExceptionStatus.ProtocolError)
    {
      Log.Error("HttpService", "StatusCode : " + ((HttpWebResponse)e.Response).StatusCode);
      Log.Error("HttpService", "StatusDescription : " + ((HttpWebResponse)e.Response).StatusDescription);
    }
    throw new WxPayException(e.ToString());
  }
  catch (Exception e)
  {
    Log.Error("HttpService", e.ToString());
    throw new WxPayException(e.ToString());
  }
  finally
  {
    //关闭连接和流
    if (response != null)
    {
      response.Close();
    }
    if (request != null)
    {
      request.Abort();
    }
  }
  return result;
}

 

posted @ 2017-08-15 15:17  我叫阿良❤善良的良  阅读(1609)  评论(0)    收藏  举报