微信支付后回调方法实现过程中遇到的问题记录
[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;
}

浙公网安备 33010602011771号