public bool ManalWithdraw(long id)
        {
            var withdrawalDac = new UserWithdrawalDAC();
            var withdrawal    = withdrawalDac.GetById(id);

            if (withdrawal != null)
            {
                if (withdrawal.Status == TransactionStatus.UnSubmit && withdrawal.RequestId == null)
                {
                    var model = new CreateWithdrawModel
                    {
                        AccountID        = withdrawal.UserAccountId,
                        CryptoName       = withdrawal.CryptoCode,
                        AccountType      = AccountTypeEnum.User,
                        ReceivingAddress = withdrawal.Address,
                        DestinationTag   = withdrawal.Tag,
                        Amount           = withdrawal.Amount,
                        IPAddress        = "207.226.141.205",
                        TransactionFee   = 0,
                        WithdrawalId     = withdrawal.Id
                    };

                    Framework.Queue.RabbitMQSender.SendMessage("WithdrawSubmit", model);
                }
            }

            return(false);
        }
        public void PushWithdrawReject(long id)
        {
            var order  = new UserWithdrawalDAC().GetById(id);
            var wallet = new UserWalletDAC().GetById(order.UserWalletId);
            var coin   = new CryptocurrencyDAC().GetById(wallet.CryptoId);

            var regId = RedisHelper.StringGet($"FiiiPay:Notice:UserId:{order.UserAccountId}");

            var lang        = RedisHelper.StringGet(REDIS_LANGUAGE_DBINDEX, $"FiiiPay:Language:{order.UserAccountId}") ?? "en";
            var titleKey    = "WithdrawalRejectTitle";
            var subTitleKey = "WithdrawalRejectSubTitle";

            if (!(_resourcePropertyNames.Contains(titleKey) && _resourcePropertyNames.Contains(subTitleKey)))
            {
                throw new Exception("没有找到资源");
            }
            var content  = ResourceHelper.FiiiPay.GetFormatResource(titleKey, lang, coin.Code);
            var subTitle = ResourceHelper.FiiiPay.GetResource(subTitleKey, lang);

            string noticeId = "";

            //写MongoDB [提币失败]
            MessagesComponent.AddMessage(order.UserAccountId, UserType.User, order.Id.ToString(), FiiiPayPushType.TYPE_WITHDRAWAL_Reject, titleKey, subTitleKey, coin.Code, content, subTitle, out noticeId);

            RegPush(FiiiPayPushType.TYPE_WITHDRAWAL_Reject, new List <string> {
                regId
            }, order.Id, content, subTitle, noticeId);
            LogHelper.Info($"--------{lang}------{content}----------{subTitle}");
        }
        //private string CreateOrderno()
        //{
        //    return DateTime.Now.ToUnixTime() + new Random().Next(0, 100).ToString("00");
        //}

        public WithdrawDetailOM Detail(UserAccount user, long id, bool isZH)
        {
            var data = new UserWithdrawalDAC().GetById(user.Id, id);
            //var agent = FiiiFinanceFactory.GetByCountryId(user.CountryId.Value);
            //var markPrice = agent.GetMarketPrice(user.FiatCurrency, data.CryptoCode);
            var wallet = new UserWalletDAC().GetById(data.UserWalletId);
            var coin   = new CryptocurrencyDAC().GetById(wallet.CryptoId);

            var fee = new UserWithdrawalFeeDAC().GetByWithdrawalId(id) ?? new UserWithdrawalFee {
                Amount = 0
            };

            data.Amount = data.Amount - fee.Fee;

            var om = new WithdrawDetailOM
            {
                Address      = data.Address,
                Tag          = data.Tag,
                CryptoAmount = data.Amount.ToString(coin.DecimalPlace),
                //FiatAmount = (markPrice.Price * data.Amount.Value).ToString(2),
                Code    = coin.Code,
                NeedTag = coin.NeedTag,
                //FiatCurrency = user.FiatCurrency,
                Id             = data.Id,
                OrderNo        = data.OrderNo,
                StatusStr      = new UserStatementComponent().GetStatusStr(1, (int)data.Status, isZH),
                Status         = data.Status,
                Timestamp      = data.Timestamp.ToUnixTime().ToString(),
                TransactionFee = data.WithdrawalFee.ToString(coin.DecimalPlace),
                Type           = Resources.Withdrawal,
                SelfPlatform   = data.SelfPlatform,
                TransactionId  = data.SelfPlatform ? "-" : data.TransactionId ?? "-",
                Remark         = data.Remark// data.Status == TransactionStatus.Cancelled ? MessageResources.提币失败备注 : null
            };

            bool showCheckTime = coin.Code != "XRP";

            if (showCheckTime && !data.SelfPlatform &&
                om.Status == TransactionStatus.Pending &&
                data.RequestId.HasValue)
            {
                var agent      = new FiiiFinanceAgent();
                var statusInfo = agent.GetStatus(data.RequestId.Value);
                om.CheckTime     = $"{statusInfo.TotalConfirmation}/{statusInfo.MinRequiredConfirmation}";
                om.TransactionId = statusInfo.TransactionID;
            }

            return(om);
        }
Esempio n. 4
0
        public override Withdraw GetByRequestId(Guid accountId, long walletId, long withdrawRequestId)
        {
            var baseWithdraw = new UserWithdrawalDAC().GetByRequestId(accountId, walletId, withdrawRequestId);

            if (baseWithdraw == null)
            {
                return(null);
            }
            return(new Withdraw
            {
                Id = baseWithdraw.Id,
                Amount = baseWithdraw.Amount,
                Status = baseWithdraw.Status,
                TransactionId = baseWithdraw.TransactionId
            });
        }
Esempio n. 5
0
        public void SubmitWithdrawal(CreateWithdrawModel model)
        {
            if (model.AccountType == AccountTypeEnum.Merchant)
            {
                var withdrawalDAC = new MerchantWithdrawalDAC();
                var withdrawal    = withdrawalDAC.GetById(model.WithdrawalId);
                if (withdrawal == null || withdrawal.Status != Entities.Enums.TransactionStatus.UnSubmit)
                {
                    LogHelper.Info("Invalid withdrawal id or invalid withdrawal status");
                    return;
                }

                var agent = new FiiiFinanceAgent();

                try
                {
                    var requestInfo = agent.CreateWithdraw(model);

                    if (requestInfo.Code == 0)
                    {
                        withdrawalDAC.WithdrawalSubmited(model.WithdrawalId, requestInfo.RequestID,
                                                         requestInfo.TransactionId);
                    }
                    else if (requestInfo.Code == 20002 || requestInfo.Code == 300001)
                    {
                        var merchantWalletDac = new MerchantWalletDAC();
                        var merchantWallet    = merchantWalletDac.GetById(withdrawal.MerchantWalletId);
                        using (var scope = new TransactionScope())
                        {
                            try
                            {
                                withdrawalDAC.RejectById(withdrawal.Id, "Invalid address");
                                merchantWalletDac.Unfreeze(merchantWallet.Id, withdrawal.Amount);
                                new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement
                                {
                                    WalletId  = merchantWallet.Id,
                                    Action    = UserWalletStatementAction.Withdrawal,
                                    Amount    = withdrawal.Amount,
                                    Balance   = merchantWallet.Balance + withdrawal.Amount,
                                    Timestamp = DateTime.UtcNow
                                });
                                scope.Complete();
                            }
                            catch (Exception exception)
                            {
                                _log.Error(exception);
                            }
                        }
                    }
                    else
                    {
                        RabbitMQSender.SendMessage("WithdrawSubmit_Delay", model);
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.Error($"UpdateTransactionId erorr, message:{JsonConvert.SerializeObject(model)}", ex);

                    RabbitMQSender.SendMessage("WithdrawSubmit_Delay", model);
                }
            }
            else if (model.AccountType == AccountTypeEnum.User)
            {
                var withdrawalDAC = new UserWithdrawalDAC();
                var withdrawal    = withdrawalDAC.GetById(model.WithdrawalId);
                if (withdrawal == null || withdrawal.Status != Entities.Enums.TransactionStatus.UnSubmit)
                {
                    LogHelper.Info("Invalid withdrawal id or invalid withdrawal status");
                    return;
                }

                var agent = new FiiiFinanceAgent();

                try
                {
                    var requestInfo = agent.CreateWithdraw(model);

                    if (requestInfo.Code == 0)
                    {
                        withdrawalDAC.WithdrawalSubmited(model.WithdrawalId, requestInfo.RequestID, requestInfo.TransactionId);
                    }
                    else if (requestInfo.Code == 20002 || requestInfo.Code == 300001)
                    {
                        var userWalletDac = new UserWalletDAC();
                        var userWallet    = userWalletDac.GetById(withdrawal.UserWalletId);
                        using (TransactionScope scope = new TransactionScope())
                        {
                            try
                            {
                                withdrawalDAC.RejectById(withdrawal.Id, "Invalid address");
                                userWalletDac.Unfreeze(withdrawal.UserWalletId, withdrawal.Amount);

                                new UserWalletStatementDAC().Insert(new Entities.UserWalletStatement
                                {
                                    WalletId      = userWallet.Id,
                                    Action        = Entities.UserWalletStatementAction.Withdrawal,
                                    Amount        = withdrawal.Amount,
                                    Balance       = userWallet.Balance + withdrawal.Amount,
                                    FrozenAmount  = -withdrawal.Amount,
                                    FrozenBalance = userWallet.FrozenBalance - withdrawal.Amount,
                                    Timestamp     = DateTime.UtcNow
                                });

                                scope.Complete();
                            }
                            catch (Exception exception)
                            {
                                _log.Error(exception);
                            }
                        }
                    }
                    else
                    {
                        RabbitMQSender.SendMessage("WithdrawSubmit_Delay", model);
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.Error($"UpdateTransactionId erorr, message:{JsonConvert.SerializeObject(model)}", ex);
                    RabbitMQSender.SendMessage("WithdrawSubmit_Delay", model);
                }
            }
            else
            {
                LogHelper.Info("Invalid AccountType");
            }
        }
        public PreWithdrawOM PreWithdraw(UserAccount user, int cryptoId)
        {
            var crypto = new CryptocurrencyDAC().GetById(cryptoId);

            var exchangeRate = GetMarketPrice(user.CountryId, crypto.Code, "USD");
            var wallet       = new UserWalletDAC().GetByAccountId(user.Id, cryptoId) ?? new UserWalletComponent().GenerateWallet(user.Id, cryptoId);
            //var profile = new UserProfileAgent().GetUserProfile(user.Id);

            var mastSettings = new MasterSettingDAC().SelectByGroup("UserWithdrawal");

            var Withdrawal_PerTx_Limit_User_NotVerified    = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerTx_Limit_User_NotVerified").Value) / exchangeRate;
            var Withdrawal_PerDay_Limit_User_NotVerified   = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerDay_Limit_User_NotVerified").Value) / exchangeRate;
            var Withdrawal_PerMonth_Limit_User_NotVerified = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerMonth_Limit_User_NotVerified").Value) / exchangeRate;

            var Withdrawal_PerTx_Limit_User_Lv1Verified    = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerTx_Limit_User_Lv1Verified").Value) / exchangeRate;
            var Withdrawal_PerDay_Limit_User_Lv1Verified   = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerDay_Limit_User_Lv1Verified").Value) / exchangeRate;
            var Withdrawal_PerMonth_Limit_User_Lv1Verified = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerMonth_Limit_User_Lv1Verified").Value) / exchangeRate;

            var Withdrawal_PerTx_Limit_User_Lv2Verified    = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerTx_Limit_User_Lv2Verified").Value) / exchangeRate;
            var Withdrawal_PerDay_Limit_User_Lv2Verified   = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerDay_Limit_User_Lv2Verified").Value) / exchangeRate;
            var Withdrawal_PerMonth_Limit_User_Lv2Verified = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerMonth_Limit_User_Lv2Verified").Value) / exchangeRate;

            var MinAmount = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_MinAmount").Value) / exchangeRate;

            var om = new PreWithdrawOM();

            om.Lv1Verified = user.L1VerifyStatus == VerifyStatus.Certified;
            om.Lv2Verified = user.L2VerifyStatus == VerifyStatus.Certified;

            om.Code    = crypto.Code;
            om.NeedTag = crypto.NeedTag;

            om.DecimalPlace = crypto.DecimalPlace;

            //余额
            om.UseableBalance = wallet.Balance.ToString(crypto.DecimalPlace);

            //最小提币量
            om.MinAmount = MinAmount.ToString(crypto.DecimalPlace);

            // to fiiipay min withdraw amount
            var toFiiiPayMinWithdrawAmount = GetToFiiiPayMinAmount(Convert.ToDecimal(mastSettings.First(e => e.Name == "UserWithdrawal_ToUser_MinAmount").Value), exchangeRate, crypto.DecimalPlace);

            om.ToFiiiPayMinWithdrawalAmount = toFiiiPayMinWithdrawAmount.ToString(crypto.DecimalPlace);


            var     dac               = new UserWithdrawalDAC();
            var     today             = DateTime.UtcNow.Date;
            decimal dailyWithdrawal   = dac.DailyWithdrawal(user.Id, cryptoId, today);
            decimal monthlyWithdrawal = dac.MonthlyWithdrawal(user.Id, cryptoId, new DateTime(today.Year, today.Month, 1));

            if (user.L1VerifyStatus == VerifyStatus.Certified && user.L2VerifyStatus == VerifyStatus.Certified)
            {
                om.PerTxLimit    = Withdrawal_PerTx_Limit_User_Lv2Verified.ToString(crypto.DecimalPlace);
                om.PerDayLimit   = Withdrawal_PerDay_Limit_User_Lv2Verified.ToString(crypto.DecimalPlace);
                om.PerMonthLimit = Withdrawal_PerMonth_Limit_User_Lv2Verified.ToString(crypto.DecimalPlace);
            }
            else if (user.L1VerifyStatus == VerifyStatus.Certified && user.L2VerifyStatus != VerifyStatus.Certified)
            {
                om.PerTxLimit    = Withdrawal_PerTx_Limit_User_Lv1Verified.ToString(crypto.DecimalPlace);
                om.PerDayLimit   = Withdrawal_PerDay_Limit_User_Lv1Verified.ToString(crypto.DecimalPlace);
                om.PerMonthLimit = Withdrawal_PerMonth_Limit_User_Lv1Verified.ToString(crypto.DecimalPlace);
            }
            else if (user.L1VerifyStatus != VerifyStatus.Certified && user.L2VerifyStatus != VerifyStatus.Certified)
            {
                om.PerTxLimit    = Withdrawal_PerTx_Limit_User_NotVerified.ToString(crypto.DecimalPlace);
                om.PerDayLimit   = Withdrawal_PerDay_Limit_User_NotVerified.ToString(crypto.DecimalPlace);
                om.PerMonthLimit = Withdrawal_PerMonth_Limit_User_NotVerified.ToString(crypto.DecimalPlace);
            }

            om.PerTxUsable = om.PerTxLimit;
            //当月可用限额小于当日可用限额时,当月可用限额更新为当日可用限额。
            decimal dayUsable   = Convert.ToDecimal(om.PerDayLimit) - dailyWithdrawal;
            decimal monthUsable = Convert.ToDecimal(om.PerMonthLimit) - monthlyWithdrawal;

            dayUsable = Math.Min(dayUsable, monthUsable);

            om.PerDayUsable   = Math.Max(0, dayUsable).ToString(crypto.DecimalPlace);
            om.PerMonthUsable = Math.Max(0, monthUsable).ToString(crypto.DecimalPlace);

            om.PerTxLimitIfLv1Veried    = Withdrawal_PerTx_Limit_User_Lv1Verified.ToString(crypto.DecimalPlace);
            om.PerDayLimitIfLv1Veried   = Withdrawal_PerDay_Limit_User_Lv1Verified.ToString(crypto.DecimalPlace);
            om.PerMonthLimitIfLv1Veried = Withdrawal_PerMonth_Limit_User_Lv1Verified.ToString(crypto.DecimalPlace);

            om.PerTxLimitIfLv2Veried    = Withdrawal_PerTx_Limit_User_Lv2Verified.ToString(crypto.DecimalPlace);
            om.PerDayLimitIfLv2Veried   = Withdrawal_PerDay_Limit_User_Lv2Verified.ToString(crypto.DecimalPlace);
            om.PerMonthLimitIfLv2Veried = Withdrawal_PerMonth_Limit_User_Lv2Verified.ToString(crypto.DecimalPlace);

            return(om);
        }
        public WithdrawOM Withdraw(UserAccount user, WithdrawIM im, string clientIP)
        {
            SecurityVerify.Verify <WithdrawVerify>(new CustomVerifier("UserWithdraw"), SystemPlatform.FiiiPay, user.Id.ToString(), (model) =>
            {
                return(model.PinVerified && model.CombinedVerified);
            });


            if (user.L1VerifyStatus != VerifyStatus.Certified)
            {
                throw new CommonException(ReasonCode.NOT_VERIFY_LV1, Resources.EMNeedLV1Verfied);
            }

            var cryptocurrency = new CryptocurrencyDAC().GetById(im.CoinId);

            if (!cryptocurrency.Status.HasFlag(CryptoStatus.Withdrawal) || cryptocurrency.Enable == 0)
            {
                throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, MessageResources.CurrencyForbidden);
            }

            CryptoAddressValidation.ValidateAddress(cryptocurrency.Code, im.Address);
            if (!string.IsNullOrEmpty(im.Tag))
            {
                CryptoAddressValidation.ValidateTag(cryptocurrency.Code, im.Tag);
            }
            //else if (cryptocurrency.NeedTag)
            //{
            //    throw new CommonException(ReasonCode.NEED_INPUT_TAG, GeneralResources.EMNeedInputTag);
            //}

            if (im.Amount <= 0)
            {
                throw new ApplicationException(MessageResources.AmountGreater);
            }

            var IsAllowWithdrawal = user.IsAllowWithdrawal ?? true;

            if (!IsAllowWithdrawal)
            {
                throw new CommonException(ReasonCode.Not_Allow_Withdrawal, MessageResources.WithdrawalDisabled);
            }

            var fromWallet = new UserWalletDAC().GetByAccountId(user.Id, im.CoinId);


            //var profile = new UserProfileAgent().GetUserProfile(user.Id);

            //标准化这个金额,防止超过8位
            im.Amount = im.Amount.ToSpecificDecimal(cryptocurrency.DecimalPlace);

            var mastSettings = new MasterSettingDAC().SelectByGroup("UserWithdrawal");

            var Withdrawal_PerTx_Limit_User_NotVerified    = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerTx_Limit_User_NotVerified").Value);
            var Withdrawal_PerDay_Limit_User_NotVerified   = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerDay_Limit_User_NotVerified").Value);
            var Withdrawal_PerMonth_Limit_User_NotVerified = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerMonth_Limit_User_NotVerified").Value);

            var Withdrawal_PerTx_Limit_User_Lv1Verified    = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerTx_Limit_User_Lv1Verified").Value);
            var Withdrawal_PerDay_Limit_User_Lv1Verified   = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerDay_Limit_User_Lv1Verified").Value);
            var Withdrawal_PerMonth_Limit_User_Lv1Verified = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerMonth_Limit_User_Lv1Verified").Value);

            var Withdrawal_PerTx_Limit_User_Lv2Verified    = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerTx_Limit_User_Lv2Verified").Value);
            var Withdrawal_PerDay_Limit_User_Lv2Verified   = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerDay_Limit_User_Lv2Verified").Value);
            var Withdrawal_PerMonth_Limit_User_Lv2Verified = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_PerMonth_Limit_User_Lv2Verified").Value);

            var MinAmount = Convert.ToDecimal(mastSettings.First(e => e.Name == "Withdrawal_MinAmount").Value);

            var merchantWalletDac = new MerchantWalletDAC();
            var userWalletDac     = new UserWalletDAC();

            var isWithdrawToInside = (merchantWalletDac.IsMerchantWalletAddress(im.Address) || userWalletDac.IsUserWalletAddress(im.Address));

            if (isWithdrawToInside)
            {
                MinAmount = Convert.ToDecimal(mastSettings.First(e => e.Name == "UserWithdrawal_ToUser_MinAmount").Value);
            }

            var exchangeRate = GetMarketPrice(user.CountryId, cryptocurrency.Code, "USD");

            var _minAmount = (MinAmount / exchangeRate).ToSpecificDecimal(cryptocurrency.DecimalPlace);

            if (im.Amount < _minAmount)
            {
                throw new ApplicationException(MessageResources.MinWidrawalError);
            }

            var     withdrawalDAC     = new UserWithdrawalDAC();
            var     today             = DateTime.UtcNow.Date;
            decimal dailyWithdrawal   = withdrawalDAC.DailyWithdrawal(user.Id, im.CoinId, today);
            decimal monthlyWithdrawal = withdrawalDAC.MonthlyWithdrawal(user.Id, im.CoinId, new DateTime(today.Year, today.Month, 1));

            var PerDayLimit   = 0M;
            var PerMonthLimit = 0M;

            if (user.L1VerifyStatus == VerifyStatus.Certified && user.L2VerifyStatus == VerifyStatus.Certified)
            {
                PerDayLimit   = Withdrawal_PerDay_Limit_User_Lv2Verified;
                PerMonthLimit = Withdrawal_PerMonth_Limit_User_Lv2Verified;
            }
            else if (user.L1VerifyStatus == VerifyStatus.Certified && user.L2VerifyStatus != VerifyStatus.Certified)
            {
                PerDayLimit   = Withdrawal_PerDay_Limit_User_Lv1Verified;
                PerMonthLimit = Withdrawal_PerMonth_Limit_User_Lv1Verified;
            }
            else if (user.L1VerifyStatus != VerifyStatus.Certified && user.L2VerifyStatus != VerifyStatus.Certified)
            {
                PerDayLimit   = Withdrawal_PerDay_Limit_User_NotVerified;
                PerMonthLimit = Withdrawal_PerMonth_Limit_User_NotVerified;
            }
            if ((PerDayLimit / exchangeRate - dailyWithdrawal).ToSpecificDecimal(cryptocurrency.DecimalPlace) < im.Amount)
            {
                throw new ApplicationException(MessageResources.TodayWidrawalLimit);
            }
            if ((PerMonthLimit / exchangeRate - monthlyWithdrawal).ToSpecificDecimal(cryptocurrency.DecimalPlace) < im.Amount)
            {
                throw new ApplicationException(MessageResources.MonthWithdrawalLimit);
            }

            var fromWithdraw = new UserWithdrawal
            {
                UserAccountId = user.Id,
                UserWalletId  = fromWallet.Id,
                Address       = im.Address,
                Tag           = im.Tag,
                Amount        = im.Amount,
                Status        = TransactionStatus.UnSubmit,
                Timestamp     = DateTime.UtcNow,
                OrderNo       = IdentityHelper.OrderNo(),
                CryptoCode    = fromWallet.CryptoCode,
                CryptoId      = fromWallet.CryptoId
            };

            //是否是商户地址
            var toMerchantWallet = merchantWalletDac.GetByAddressAndCrypto(im.CoinId, im.Address, im.Tag);

            if (toMerchantWallet != null)
            {
                //if (toMerchantWallet.CryptoId != im.CoinId)
                //    throw new CommonException(ReasonCode.GENERAL_ERROR, GeneralResources.EMInvalidAddress);
                //return WithdrawalToMerchantAccount(fromWallet, fromWithdraw, fromWithdrawFee, toMerchantWallet, cryptocurrency);
                //042018
                throw new CommonException(ReasonCode.CAN_NOT_WITHDRAW_TO_FiiiPOS, MessageResources.FiiiPayCantWithdrawToFiiiPOS);
            }

            //是否是用户地址
            var toUserWallet = userWalletDac.GetByAddressAndCrypto(im.CoinId, im.Address, im.Tag);

            if (toUserWallet != null)
            {
                if (toUserWallet.UserAccountId == user.Id)
                {
                    throw new CommonException(ReasonCode.CANNOT_TRANSFER_TO_YOURSELF, MessageResources.WithdrawalToSelfError);
                }

                var toFiiiPayMinWithdrawAmount = GetToFiiiPayMinAmount(Convert.ToDecimal(mastSettings.First(e => e.Name == "UserWithdrawal_ToUser_MinAmount").Value), exchangeRate, cryptocurrency.DecimalPlace);
                if (im.Amount < toFiiiPayMinWithdrawAmount)
                {
                    throw new CommonException(10000, MessageResources.MinWidrawalError);
                }

                return(WithdrawalToUserAccount(fromWallet, fromWithdraw, toUserWallet));
            }

            var tier = cryptocurrency.Withdrawal_Tier ?? 0;
            var fee  = im.Amount * tier + (cryptocurrency.Withdrawal_Fee ?? 0);

            fee = fee.ToSpecificDecimal(cryptocurrency.DecimalPlace);
            var actualAmount = im.Amount - fee;

            if (fromWallet.Balance < im.Amount)
            {
                throw new CommonException(ReasonCode.INSUFFICIENT_BALANCE, MessageResources.InsufficientBalance);
            }
            if (actualAmount <= 0)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, MessageResources.ArrivalAmountError);
            }

            //地址是FiiiPay的地址,但tag找不到
            if (cryptocurrency.NeedTag && isWithdrawToInside)
            {
                return(CancelWithdrawal(fromWithdraw));
            }

            ILog _logger = LogManager.GetLogger("LogicError");

            //如果都不是,向Finance申请提现

            //var agent = new FiiiFinanceAgent();

            var requestModel = new CreateWithdrawModel
            {
                AccountID        = user.Id,
                AccountType      = AccountTypeEnum.User,
                CryptoName       = cryptocurrency.Code,
                ReceivingAddress = im.Address,
                DestinationTag   = im.Tag,
                Amount           = actualAmount,
                IPAddress        = clientIP,
                TransactionFee   = fee
            };

            using (var scope = new TransactionScope())
            {
                try
                {
                    fromWithdraw.Id = withdrawalDAC.Create(fromWithdraw);
                    var fromWithdrawFee = new UserWithdrawalFee
                    {
                        Amount       = im.Amount,
                        Fee          = fee,
                        Timestamp    = DateTime.UtcNow,
                        WithdrawalId = fromWithdraw.Id
                    };

                    new UserTransactionDAC().Insert(new UserTransaction
                    {
                        Id         = Guid.NewGuid(),
                        AccountId  = fromWithdraw.UserAccountId,
                        CryptoId   = fromWithdraw.CryptoId,
                        CryptoCode = fromWithdraw.CryptoCode,
                        Type       = UserTransactionType.Withdrawal,
                        DetailId   = fromWithdraw.Id.ToString(),
                        Status     = (byte)fromWithdraw.Status,
                        Timestamp  = fromWithdraw.Timestamp,
                        Amount     = fromWithdraw.Amount,
                        OrderNo    = fromWithdraw.OrderNo
                    });

                    new UserWithdrawalFeeDAC().Create(fromWithdrawFee);

                    userWalletDac.Freeze(fromWallet.Id, im.Amount);

                    new UserWalletStatementDAC().Insert(new UserWalletStatement
                    {
                        WalletId      = fromWallet.Id,
                        Action        = UserWalletStatementAction.Withdrawal,
                        Amount        = 0 - im.Amount,
                        Balance       = fromWallet.Balance - im.Amount,
                        FrozenAmount  = im.Amount,
                        FrozenBalance = fromWallet.FrozenBalance + im.Amount,
                        Timestamp     = DateTime.UtcNow
                    });

                    requestModel.WithdrawalId = fromWithdraw.Id;
                    Framework.Queue.RabbitMQSender.SendMessage("WithdrawSubmit", requestModel);

                    scope.Complete();
                }
                catch (CommonException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    _logger.Info($"Withdraw CreateWithdrawRequest faild.WithdrawID:{fromWithdraw.Id},OrderNo:{fromWithdraw.OrderNo}.request Parameter - {requestModel}. Error message:{ex.Message}");
                    throw;
                }
            }

            return(new WithdrawOM
            {
                OrderId = fromWithdraw.Id,
                OrderNo = fromWithdraw.OrderNo,
                Timestamp = fromWithdraw.Timestamp.ToUnixTime().ToString()
            });
        }