Пример #1
0
        /// <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));
        }
Пример #2
0
        /// <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;
            }
        }