/// <summary> /// 退款通知地址 /// </summary> /// <returns></returns> public async Task <IActionResult> RefundNotifyUrl() { WeixinTrace.SendCustomLog("RefundNotifyUrl被访问", "IP" + HttpContext.UserHostAddress()?.ToString()); NotifyReturnData returnData = new(); try { var resHandler = new TenPayNotifyHandler(HttpContext); var refundNotifyJson = await resHandler.AesGcmDecryptGetObjectAsync <RefundNotifyJson>(); WeixinTrace.SendCustomLog("跟踪RefundNotifyUrl信息", refundNotifyJson.ToJson()); string refund_status = refundNotifyJson.refund_status; if (/*refundNotifyJson.VerifySignSuccess == true &*/ refund_status == "SUCCESS") { returnData.code = "SUCCESS"; returnData.message = "OK"; //获取接口中需要用到的信息 例 string transaction_id = refundNotifyJson.transaction_id; string out_trade_no = refundNotifyJson.out_trade_no; string refund_id = refundNotifyJson.refund_id; string out_refund_no = refundNotifyJson.out_refund_no; int total_fee = refundNotifyJson.amount.payer_total; int refund_fee = refundNotifyJson.amount.refund; //填写逻辑 WeixinTrace.SendCustomLog("RefundNotifyUrl被访问", "验证通过"); } else { returnData.code = "FAILD"; returnData.message = "验证失败"; WeixinTrace.SendCustomLog("RefundNotifyUrl被访问", "验证失败"); } //进行后续业务处理 } catch (Exception ex) { returnData.code = "FAILD"; returnData.message = ex.Message; WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex)); } //https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay3_3.shtml return(Json(returnData)); }
/// <summary> /// JS-SDK支付回调地址(在下单接口中设置的 notify_url) /// </summary> /// <returns></returns> public async Task <IActionResult> PayNotifyUrl() { try { //获取微信服务器异步发送的支付通知信息 var resHandler = new TenPayNotifyHandler(HttpContext); var orderReturnJson = await resHandler.AesGcmDecryptGetObjectAsync <OrderReturnJson>(); //记录日志 Senparc.Weixin.WeixinTrace.SendCustomLog("PayNotifyUrl 接收到消息", orderReturnJson.ToJson(true)); //演示记录 transaction_id,实际开发中需要记录到数据库,以便退款和后续跟踪 TradeNumberToTransactionId[orderReturnJson.out_trade_no] = orderReturnJson.transaction_id; //获取支付状态 string trade_state = orderReturnJson.trade_state; //验证请求是否从微信发过来(安全) NotifyReturnData returnData = new(); //验证可靠的支付状态 if (orderReturnJson.VerifySignSuccess == true && trade_state == "SUCCESS") { returnData.code = "SUCCESS";//正确的订单处理 /* 提示: * 1、直到这里,才能认为交易真正成功了,可以进行数据库操作,但是别忘了返回规定格式的消息! * 2、上述判断已经具有比较高的安全性以外,还可以对访问 IP 进行判断进一步加强安全性。 * 3、下面演示的是发送支付成功的模板消息提示,非必须。 */ #region 发送支付成功模板消息提醒 try { string appId = Config.SenparcWeixinSetting.TenPayV3_AppId;//与微信公众账号后台的AppId设置保持一致,区分大小写。 string openId = orderReturnJson.payer.openid; var templateData = new WeixinTemplate_PaySuccess("https://weixin.senparc.com", "微信支付 V3 购买商品", "状态:" + trade_state); Senparc.Weixin.WeixinTrace.SendCustomLog("TenPayV3 支付成功模板消息参数", "AppId:" + appId + " ,openId: " + openId); var result = await MP.AdvancedAPIs.TemplateApi.SendTemplateMessageAsync(appId, openId, templateData); } catch (Exception ex) { Senparc.Weixin.WeixinTrace.SendCustomLog("TenPayV3 支付成功模板消息", ex.ToString()); } #endregion } else { returnData.code = "FAILD";//错误的订单处理 returnData.message = "验证失败"; //此处可以给用户发送支付失败提示等 } #region 记录日志(也可以记录到数据库审计日志中) var logDir = ServerUtility.ContentRootMapPath(string.Format("~/App_Data/TenPayNotify/{0}", SystemTime.Now.ToString("yyyyMMdd"))); if (!Directory.Exists(logDir)) { Directory.CreateDirectory(logDir); } var logPath = Path.Combine(logDir, string.Format("{0}-{1}-{2}.txt", SystemTime.Now.ToString("yyyyMMdd"), SystemTime.Now.ToString("HHmmss"), Guid.NewGuid().ToString("n").Substring(0, 8))); using (var fileStream = System.IO.File.OpenWrite(logPath)) { var notifyJson = orderReturnJson.ToString(); await fileStream.WriteAsync(Encoding.Default.GetBytes(notifyJson), 0, Encoding.Default.GetByteCount(notifyJson)); fileStream.Close(); } #endregion //https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_5.shtml return(Json(returnData)); } catch (Exception ex) { WeixinTrace.WeixinExceptionLog(new WeixinException(ex.Message, ex)); throw; } }