用户支付之后,微信会给之前预留的接口(接口不能带参数)发消息, 网站在收到消息后进行验证和确认,确定之后再给微信发一个消息。详细参数和文档请看
这里还是把demo中的方法稍作改动放到了控制器里面:
public ActionResult ResultNotify() { //接收从微信后台POST过来的数据 Stream s = 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(); Logger.Info(this.GetType()+ "Receive data from WeChat : " + builder); //转换数据格式并验证签名 WxPayData data = new WxPayData(); try { data.FromXml(builder.ToString()); } 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()); Response.Write(res.ToXml()); Response.End(); } Logger.Info(this.GetType()+ "Check sign success"); ProcessNotify(data); return View(); } public void ProcessNotify(WxPayData data) { WxPayData notifyData = data; //检查支付结果中transaction_id是否存在 if (!notifyData.IsSet("transaction_id")) { //若transaction_id不存在,则立即返回结果给微信支付后台 WxPayData res = new WxPayData(); res.SetValue("return_code", "FAIL"); res.SetValue("return_msg", "支付结果中微信订单号不存在"); Logger.Error(this.GetType()+"The Pay result is error : " + res.ToXml()); Response.Write(res.ToXml()); Response.End(); } string transaction_id = notifyData.GetValue("transaction_id").ToString(); //查询订单,判断订单真实性 if (!QueryOrder(transaction_id)) { //若订单查询失败,则立即返回结果给微信支付后台 WxPayData res = new WxPayData(); res.SetValue("return_code", "FAIL"); res.SetValue("return_msg", "订单查询失败"); Logger.Error(this.GetType()+"Order query failure : " + res.ToXml()); Response.Write(res.ToXml()); Response.End(); } //查询订单成功 else { WxPayData res = new WxPayData(); res.SetValue("return_code", "SUCCESS"); res.SetValue("return_msg", "OK"); Logger.Info(this.GetType()+"order query success : " + res.ToXml()); SetPaymentResult(data.GetValue("out_trade_no").ToString(), PaymentStatus.Paid); Response.Write(res.ToXml()); Response.End(); } }
收到确认后,我们要更新订单的状态:
public void SetPaymentResult(string tradeno, PaymentStatus status) { Logger.Info("订单号:"+tradeno); var order = _orderService.GetOrderByTradeNumber(tradeno); if (order != null) { order.PaymentStatus = status; if (status == PaymentStatus.Paid) { order.PaidDate = DateTime.Now; } _orderService.UpdateOrder(order); Logger.Info("订单:"+tradeno+"成功更新状态为"+status); } }
然后在页面上检测订单的状态,确定成功后,跳转页面。
在商户平台的后台,我们可以查询到:
小结:主要过程就是这样,因为不能本地调试,打日志调试比较耗时,希望对你有帮助。接下来研究下退款(需要证书)。