public NormalResult <CreatePayOrderResult> DonationPay(DonationPayArgs args, AuthorizerPayConfig config)
        {
            //创建支付信息
            CreatePayOrderArgs createPayOrderArgs = new CreatePayOrderArgs();

            createPayOrderArgs.MemberId       = args.MemberId;
            createPayOrderArgs.OpenId         = args.OpenId;
            createPayOrderArgs.Fee            = args.Fee;
            createPayOrderArgs.SpbillCreateIp = args.SpbillCreateIp;

            createPayOrderArgs.OrderType  = EnumPayOrderType.Donation;
            createPayOrderArgs.Body       = "在线捐款";
            createPayOrderArgs.OutTradeNo = Guid.NewGuid().ToString().Replace("-", "");
            NormalResult <CreatePayOrderResult> result = _payManager.CreatePayOrder(createPayOrderArgs, config);

            //捐款记录
            Campaign_DonationLogEntity log = new Campaign_DonationLogEntity();

            log.CampaignId  = args.CampaignId;
            log.Domain      = args.DomainId;
            log.PayOrder    = result.Data.PayOrderId;
            log.Member      = args.MemberId;
            log.CreateTime  = DateTime.Now;
            log.Name        = args.Name;
            log.Contact     = args.Contact;
            log.Description = args.Description;
            _campaignManager.DataBase.Insert(log);

            return(result);
        }
Пример #2
0
        public AuthorizerPayConfig GetAuthorizerPayConfig(Guid domainId, string appId)
        {
            AuthorizerPayConfig config = new AuthorizerPayConfig();

            config.Domain = domainId;
            config.AppId  = appId;

            if (_dataBase.Fill <AuthorizerPayConfig>(config))
            {
                return(config);
            }
            else
            {
                return(null);
            }
        }
Пример #3
0
        public NormalResult ClosePayOrder(string outTradeNo, AuthorizerPayConfig config)
        {
            NormalResult result = new NormalResult();

            if (config == null)
            {
                result.Success = false;
                result.Message = "当前公众号没有微信支付所需配置信息。";
                return(result);
            }

            WeixinPayCloseOrderArgs closeOrderArgs = new WeixinPayCloseOrderArgs();

            closeOrderArgs.AppId      = config.AppId;
            closeOrderArgs.MchId      = config.MchId;
            closeOrderArgs.OutTradeNo = outTradeNo;

            WxPayArgs wxPayArgs = config.GetWxPayArgs(false);

            RequestPayApiResult <WeixinPayCloseOrderResult> closeOrderResult =
                WxPayApi.CloseOrder(closeOrderArgs, wxPayArgs);

            if (closeOrderResult.Success == false)
            {
                _log.Write("CloseOrder 失败",
                           closeOrderResult.Message + "\r\n"
                           + JsonHelper.Serializer(closeOrderArgs) + " "
                           + JsonHelper.Serializer(closeOrderResult),
                           TraceEventType.Warning);

                result.Success = false;
                result.Message = closeOrderResult.Message;
                return(result);
            }

            result.Success = true;
            return(result);
        }
        /// <summary>
        /// 发起订单支付
        /// 0 支付成功 1 积分不足 2 账户余额不足(小于想使用的金额)
        /// 3 需要微信支付,微信支付下单成功(返回微支付订单号需转入微信支付画面)
        /// 4 订单状态不是待支付 5 订单已经过期 6 订单不存在 7 微信支付下单失败
        /// 8 已经有待支付的微信支付订单了且微信支付金额同这次一样(返回微支付订单号需转入微信支付画面)
        /// </summary>
        /// <returns></returns>
        public NormalResult <PointCommodityOrderPayResult> OrderPay(PointCommodityOrderPayArgs args, AuthorizerPayConfig config)
        {
            NormalResult <PointCommodityOrderPayResult> result = new NormalResult <PointCommodityOrderPayResult>(false);

            //判断订单状态
            PointCommodityOrderEntity order = GetOrder(args.OrderId);

            if (order == null)
            {
                result.Reason = 6;
                return(result);
            }

            if (order.Status != PointCommodityOrderStatus.NoPayment)
            {
                result.Reason = 4;
                InsertOrderLog(order, 4);
                return(result);
            }

            //判断订单是否已经过期
            if (order.ExpireTime <= DateTime.Now)
            {
                result.Reason = 5;
                InsertOrderLog(order, 5);
                return(result);
            }

            //积分是否足够在前端提交时就判断了,到这里后不会再次判断
            //在存储过程中判断即可

            //判断账户余额是否足够,是否大于想使用的金额
            //这里初步判断,存储过程中还要判断(行锁定)
            int cashAccount = _memberManager.GetMemberCashAccountBalances(args.MemberId);

            if (cashAccount < args.CashAccountFee)
            {
                result.Reason = 2;
                InsertOrderLog(order, 2);
                return(result);
            }

            //判断是否已经有待支付的微信支付订单了
            //如果有,但已过期,则关闭原订单
            //如果有,但金额和这次不一样,则关闭原订单
            //如果有,且未过期且金额与本次一致,返回微支付订单号需转入微信支付画面
            string outTradeNo = args.OrderId.ToString().Replace("-", "");
            List <PayOrderEntity> existPayOrderList = _payManager.GetPayOrderByOutTradeNo(outTradeNo);

            foreach (PayOrderEntity existPayOrder in existPayOrderList)
            {
                if (existPayOrder.TimeExpire <= DateTime.Now)
                {
                    _payManager.ClosePayOrder(existPayOrder.OutTradeNo, config);
                    continue;
                }

                if (existPayOrder.TotalFee != args.WeixinPayFee)
                {
                    _payManager.ClosePayOrder(existPayOrder.OutTradeNo, config);
                    continue;
                }

                result.Reason          = 8;
                result.Data            = new PointCommodityOrderPayResult();
                result.Data.PayOrderId = existPayOrder.Id;
                result.Success         = true;
                return(result);
            }

            //判断是否需要微信支付,如果需要则直接生成微信支付订单并返回订单号到前端跳转
            //订单的完成在支付成功的回调中处理
            //微信支付成功后,还是先把钱存到账户余额,然后再从余额中下帐成单
            if (args.WeixinPayFee > 0)
            {
                #region 创建微信支付定单

                CreatePayOrderArgs createPayOrderArgs = new CreatePayOrderArgs();

                createPayOrderArgs.MemberId       = args.MemberId;
                createPayOrderArgs.OpenId         = args.OpenId;
                createPayOrderArgs.Fee            = args.WeixinPayFee;
                createPayOrderArgs.SpbillCreateIp = args.SpbillCreateIp;

                createPayOrderArgs.OrderType  = EnumPayOrderType.PointCommodity;
                createPayOrderArgs.Body       = order.OrderNumber;
                createPayOrderArgs.OutTradeNo = outTradeNo;
                NormalResult <CreatePayOrderResult> createPayOrderResult = _payManager.CreatePayOrder(createPayOrderArgs, config);

                if (createPayOrderResult.Success == false)
                {
                    InsertOrderLog(order, 7, createPayOrderResult.Message);
                    result.Reason  = 7;
                    result.Message = createPayOrderResult.Message;
                    return(result);
                }

                InsertOrderLog(order, 3);
                result.Reason          = 3;
                result.Data            = new PointCommodityOrderPayResult();
                result.Data.PayOrderId = createPayOrderResult.Data.PayOrderId;
                result.Success         = true;
                return(result);

                #endregion
            }

            //如果不需要微信支付,则转到存储过程开始处理
            NormalResult checkoutResult = Checkout(order);
            result.Reason = checkoutResult.Reason;

            if (result.Reason == 0)
            {
                result.Success = true;
            }

            return(result);
        }
Пример #5
0
        public NormalResult RefreshPayOrder(string outTradeNo, AuthorizerPayConfig config)
        {
            NormalResult result = new NormalResult();

            if (config == null)
            {
                result.Success = false;
                result.Message = "当前公众号没有微信支付所需配置信息。";
                return(result);
            }

            WeixinPayOrderQueryArgs orderQueryArgs = new WeixinPayOrderQueryArgs();

            orderQueryArgs.AppId      = config.AppId;
            orderQueryArgs.MchId      = config.MchId;
            orderQueryArgs.OutTradeNo = outTradeNo;

            WxPayArgs wxPayArgs = config.GetWxPayArgs(false);

            RequestPayApiResult <WeixinPayOrderQueryResult> orderQueryResult =
                WxPayApi.OrderQuery(orderQueryArgs, wxPayArgs);

            if (orderQueryResult.Success == false)
            {
                _log.Write("OrderQuery 失败",
                           orderQueryResult.Message + "\r\n"
                           + JsonHelper.Serializer(orderQueryArgs) + " "
                           + JsonHelper.Serializer(orderQueryResult),
                           TraceEventType.Warning);

                result.Success = false;
                result.Message = orderQueryResult.Message;
                return(result);
            }

            WeixinPayOrderQueryResult orderQuery = orderQueryResult.ApiResult;

            Guid payOrderId;

            if (Guid.TryParse(orderQuery.Attach, out payOrderId) == false)
            {
                string attacth = String.Empty;
                if (orderQuery.Attach != null)
                {
                    attacth = orderQuery.Attach;
                }
                _log.Write("Attach 无法转为本地订单Id" + attacth, orderQuery.OutTradeNo, TraceEventType.Verbose);
                result.Success = false;
                result.Message = "Attach 无法转为本地订单Id。" + attacth;
                return(result);
            }

            PayOrderEntity payOrder = GetPayOrder(payOrderId);

            SqlStructureBuild sqlBuild = new SqlStructureBuild();

            sqlBuild.Table = "PayOrder";
            sqlBuild.Type  = SqlExpressionType.Update;
            sqlBuild.AddParameter("Id", payOrderId, true);
            sqlBuild.AddParameter("TradeState", EnumHelper.GetEnumFieldByValue <EnumPayTradeState>(orderQuery.TradeState));
            sqlBuild.AddParameter("TradeStateDesc", orderQuery.TradeStateDesc);
            sqlBuild.AddParameter("BankType", orderQuery.BankType);
            sqlBuild.AddParameter("FeeType", orderQuery.FeeType);
            sqlBuild.AddParameter("CouponFee", orderQuery.CouponFee);
            sqlBuild.AddParameter("CouponCount", orderQuery.CouponCount);
            sqlBuild.AddParameter("TransactionId", orderQuery.TransactionId);
            if (orderQuery.TimeEnd != null)
            {
                sqlBuild.AddParameter("TimeEnd", WeixinApiHelper.ConvertStringToDateTime(orderQuery.TimeEnd));
            }
            sqlBuild.AddParameter("Notify_ReturnCode", orderQuery.ReturnCode);
            sqlBuild.AddParameter("Notify_ReturnMsg", orderQuery.ReturnMsg);
            sqlBuild.AddParameter("Notify_ResultCode", orderQuery.ResultCode);
            sqlBuild.AddParameter("Notify_ErrCode", orderQuery.ErrCode);
            sqlBuild.AddParameter("Notify_ErrCodeDes", orderQuery.ErrCodeDes);
            int affectedRowCount = _dataBase.ExcuteSqlExpression(sqlBuild.GetSqlExpression());

            if (affectedRowCount == 0)
            {
                _log.Write("本地订单不存在", orderQuery.OutTradeNo, TraceEventType.Warning);
                result.Success = false;
                result.Message = "本地订单不存在。";
                return(result);
            }

            if (orderQuery.CouponCount > 0)
            {
                List <CommandParameter> parameterList = new List <CommandParameter>();
                parameterList.Add(new CommandParameter("@payOrderId", payOrder.Id));

                _dataBase.ExecuteNonQuery(
                    "DELETE FROM [PayOrderCoupon] WHERE [PayOrderId] = @payOrderId", parameterList);

                foreach (WeixinPayOrderQueryResult_Coupon coupon in orderQuery.CouponList)
                {
                    coupon.PayOrderId = payOrder.Id;
                    _dataBase.Insert(coupon);
                }
            }

            result.Success = true;
            return(result);
        }
Пример #6
0
        /// <summary>
        /// 通过微信支付充值
        /// </summary>
        /// <param name="args"></param>
        /// <param name="config"></param>
        /// <returns></returns>
        public NormalResult <CreatePayOrderResult> Deposit(CashAccountDepositArgs args, AuthorizerPayConfig config)
        {
            CreatePayOrderArgs createPayOrderArgs = new CreatePayOrderArgs();

            createPayOrderArgs.MemberId       = args.MemberId;
            createPayOrderArgs.OpenId         = args.OpenId;
            createPayOrderArgs.Fee            = args.Fee;
            createPayOrderArgs.SpbillCreateIp = args.SpbillCreateIp;

            createPayOrderArgs.OrderType  = EnumPayOrderType.Deposit;
            createPayOrderArgs.Body       = "会员充值";
            createPayOrderArgs.OutTradeNo = Guid.NewGuid().ToString().Replace("-", "");
            NormalResult <CreatePayOrderResult> result = CreatePayOrder(createPayOrderArgs, config);

            return(result);
        }
Пример #7
0
        public NormalResult Notify(string xml, AuthorizerPayConfig config)
        {
            _log.Write("收到支付结果通知", xml, TraceEventType.Verbose);

            NormalResult result = new NormalResult();

            WxPayArgs wxPayArgs = config.GetWxPayArgs(false);

            RequestPayApiResult <WeixinPayNotify> notifyResult = WxPayApi.Notify(xml, wxPayArgs);

            if (notifyResult.Success == false)
            {
                _log.Write("支付结果通知显示失败", notifyResult.Message, TraceEventType.Verbose);

                result.Success = false;
                result.Message = notifyResult.Message;
                return(result);
            }

            WeixinPayNotify notify = notifyResult.ApiResult;

            Guid payOrderId;

            if (Guid.TryParse(notify.Attach, out payOrderId) == false)
            {
                string attacth = String.Empty;
                if (notify.Attach != null)
                {
                    attacth = notify.Attach;
                }
                _log.Write("Attach 无法转为本地订单Id" + attacth, notify.OutTradeNo, TraceEventType.Verbose);
                result.Success = false;
                result.Message = "Attach 无法转为本地订单Id。" + attacth;
                return(result);
            }

            bool updateNotifyStatus = UpdateNotifyStatus(payOrderId);

            if (updateNotifyStatus == false)
            {
                //已经处理过了
                //处理过的还是返回true,防止微信服务器反复推送通知
                //微信文档上说通知频率为15/15/30/180/1800/1800/1800/1800/3600,单位:秒
                //但是实测支付成功后连续推送通知过来
                result.Success = true;
                result.Message = "已经接收到过此订单的支付通知。";
                return(result);
            }

            SqlStructureBuild sqlBuild = new SqlStructureBuild();

            sqlBuild.Table = "PayOrder";
            sqlBuild.Type  = SqlExpressionType.Update;
            sqlBuild.AddParameter("Id", payOrderId, true);
            sqlBuild.AddParameter("Notify", true);
            if (notify.ReturnCode == "SUCCESS" && notify.ResultCode == "SUCCESS")
            {
                sqlBuild.AddParameter("TradeState", EnumPayTradeState.SUCCESS);
            }
            else
            {
                sqlBuild.AddParameter("TradeState", EnumPayTradeState.PAYERROR);
            }
            sqlBuild.AddParameter("BankType", notify.BankType);
            sqlBuild.AddParameter("FeeType", notify.FeeType);
            sqlBuild.AddParameter("CouponFee", notify.CouponFee);
            sqlBuild.AddParameter("CouponCount", notify.CouponCount);
            sqlBuild.AddParameter("TransactionId", notify.TransactionId);
            sqlBuild.AddParameter("TimeEnd", WeixinApiHelper.ConvertStringToDateTime(notify.TimeEnd));
            sqlBuild.AddParameter("Notify_ReturnCode", notify.ReturnCode);
            sqlBuild.AddParameter("Notify_ReturnMsg", notify.ReturnMsg);
            sqlBuild.AddParameter("Notify_ResultCode", notify.ResultCode);
            sqlBuild.AddParameter("Notify_ErrCode", notify.ErrCode);
            sqlBuild.AddParameter("Notify_ErrCodeDes", notify.ErrCodeDes);
            int affectedRowCount = _dataBase.ExcuteSqlExpression(sqlBuild.GetSqlExpression());

            if (affectedRowCount == 0)
            {
                _log.Write("本地订单不存在", notify.OutTradeNo, TraceEventType.Verbose);
                result.Success = false;
                result.Message = "本地订单不存在。";
                return(result);
            }

            PayOrderEntity payOrder = GetPayOrder(payOrderId);

            if (notify.CouponCount > 0)
            {
                foreach (WeixinPayNotify_Coupon coupon in notify.CouponList)
                {
                    coupon.PayOrderId = payOrder.Id;
                    _dataBase.Insert(coupon);
                }
            }

            if (notify.ReturnCode == "SUCCESS" && notify.ResultCode == "SUCCESS")
            {
                switch (payOrder.Type)
                {
                case EnumPayOrderType.Unknow:
                    _log.Write("收到支付结果通知", "未知订单类型", TraceEventType.Warning);
                    break;

                case EnumPayOrderType.Deposit:
                    ProcessDepositPayNotify(payOrder);
                    break;

                case EnumPayOrderType.PointCommodity:
                    ProcessPointCommodityPayNotify(payOrder);
                    break;

                case EnumPayOrderType.Donation:
                    ProcessDonationPayNotify(payOrder);
                    break;

                default:
                    _log.Write("收到支付结果通知", "订单类型未处理:" + payOrder.Type.ToString(), TraceEventType.Warning);
                    break;
                }
            }

            //更新一下订单状态
            RefreshPayOrder(payOrder.OutTradeNo, config);

            result.Success = true;
            return(result);
        }
Пример #8
0
        /// <summary>
        /// 创建一个微信支付订单
        /// 默认在2小时后过期
        /// </summary>
        /// <param name="args"></param>
        /// <param name="config"></param>
        /// <returns></returns>
        public NormalResult <CreatePayOrderResult> CreatePayOrder(CreatePayOrderArgs args, AuthorizerPayConfig config)
        {
            NormalResult <CreatePayOrderResult> result = new NormalResult <CreatePayOrderResult>(false);

            if (config == null)
            {
                result.Message = "当前公众号没有微信支付所需配置信息。";
                return(result);
            }

            //TODO:这里只判断了 Deposit
            if (ExistUnfinishedOrder(config.Domain, config.AppId, args.MemberId, EnumPayOrderType.Deposit))
            {
                result.Message = "存在尚未结束的订单,请先完成当前订单的支付或将其关闭。";
                return(result);
            }

            //string outTradeNo =Guid.NewGuid().ToString().Replace("-", "");
            DateTime timeStart  = DateTime.Now;
            DateTime timeExpire = DateTime.Now.AddHours(2);

            Guid payOrderId = Guid.NewGuid();

            WeixinPayUnifiedOrderArgs unifiedOrderArgs = new WeixinPayUnifiedOrderArgs();

            unifiedOrderArgs.AppId      = config.AppId;
            unifiedOrderArgs.MchId      = config.MchId;
            unifiedOrderArgs.DeviceInfo = "WEB";
            unifiedOrderArgs.Body       = args.Body;       //"会员充值";
            unifiedOrderArgs.OutTradeNo = args.OutTradeNo; // outTradeNo;
            unifiedOrderArgs.TotalFee   = (int)args.Fee;

            unifiedOrderArgs.SpbillCreateIp = args.SpbillCreateIp;
            if (unifiedOrderArgs.SpbillCreateIp == "::1")
            {
                unifiedOrderArgs.SpbillCreateIp = "127.0.0.1";
            }

            unifiedOrderArgs.TimeStart  = timeStart.ToString("yyyyMMddHHmmss");
            unifiedOrderArgs.TimeExpire = timeExpire.ToString("yyyyMMddHHmmss");
            unifiedOrderArgs.NotifyUrl  = "";
            unifiedOrderArgs.TradeType  = "JSAPI";
            unifiedOrderArgs.OpenId     = args.OpenId;
            unifiedOrderArgs.NotifyUrl  =
                SettingsManager.Instance.GetClientAddress(config.AppId) + "Api/Pay/PayNotify/" + config.Domain;
            unifiedOrderArgs.Attach = payOrderId.ToString();

            WxPayArgs wxPayArgs = config.GetWxPayArgs(false);

            RequestPayApiResult <WeixinPayUnifiedOrderResult> unifiedOrderResult =
                WxPayApi.UnifiedOrder(unifiedOrderArgs, wxPayArgs);

            if (unifiedOrderResult.Success == false)
            {
                _log.Write("UnifiedOrder 失败",
                           unifiedOrderResult.Message + "\r\n"
                           + JsonHelper.Serializer(unifiedOrderArgs) + " "
                           + JsonHelper.Serializer(unifiedOrderResult),
                           TraceEventType.Warning);

                result.Success = false;
                result.Message = unifiedOrderResult.Message;
                return(result);
            }

            PayOrderEntity orderEntity = new PayOrderEntity();

            orderEntity.Id             = payOrderId;
            orderEntity.Domain         = config.Domain;
            orderEntity.Member         = args.MemberId;
            orderEntity.Type           = args.OrderType;
            orderEntity.AppId          = config.AppId;
            orderEntity.MchId          = config.MchId;
            orderEntity.DeviceInfo     = unifiedOrderArgs.DeviceInfo;
            orderEntity.Body           = unifiedOrderArgs.Body;
            orderEntity.OutTradeNo     = args.OutTradeNo;//outTradeNo;
            orderEntity.TotalFee       = unifiedOrderArgs.TotalFee;
            orderEntity.SpbillCreateIp = unifiedOrderArgs.SpbillCreateIp;
            orderEntity.TimeStart      = timeStart;
            orderEntity.TimeExpire     = timeExpire;
            orderEntity.TradeType      = unifiedOrderArgs.TradeType;
            orderEntity.OpenId         = unifiedOrderArgs.OpenId;

            orderEntity.PrepayId = unifiedOrderResult.ApiResult.PrepayId;

            orderEntity.TradeState = EnumPayTradeState.NOTPAY;

            _dataBase.Insert(orderEntity);

            CreatePayOrderResult depositPayResult = new CreatePayOrderResult();

            depositPayResult.PayOrderId = orderEntity.Id;
            depositPayResult.PrepayId   = unifiedOrderResult.ApiResult.PrepayId;
            result.Data    = depositPayResult;
            result.Success = true;
            return(result);
        }