public MerchantWithdrawal Withdrawal(Guid accountId, decimal amount, int cryptoId, string address, string tag, string clientIP)
        {
            SecurityVerify.Verify <WithdrawVerify>(new CustomVerifier("MerchantWithdraw"), SystemPlatform.FiiiPOS, accountId.ToString(), (model) =>
            {
                return(model.PinVerified && model.CombinedVerified);
            });

            var cryptocurrency = new CryptocurrencyDAC().GetById(cryptoId);

            CryptoAddressValidation.ValidateAddress(cryptocurrency.Code, address);

            if (!string.IsNullOrEmpty(tag))
            {
                CryptoAddressValidation.ValidateTag(cryptocurrency.Code, tag);
            }

            var account = new MerchantAccountDAC().GetById(accountId);

            if (!new ProfileComponent().ValidateLv1(accountId))
            {
                throw new CommonException(ReasonCode.NOT_VERIFY_LV1, Resources.需要Lv1认证才能使用相关功能);
            }

            if (!account.IsAllowWithdrawal)
            {
                throw new CommonException(ReasonCode.Not_Allow_Withdrawal, Resources.禁止提币);
            }

            if (!cryptocurrency.Status.HasFlag(CryptoStatus.Withdrawal))
            {
                throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, Resources.CurrencyForbidden);
            }

            if (cryptocurrency.Enable == (byte)CurrencyStatus.Forbidden)
            {
                throw new CommonException(ReasonCode.CURRENCY_FORBIDDEN, Resources.CurrencyForbidden);
            }

            var fromWallet = new MerchantWalletDAC().GetByAccountId(accountId, cryptoId);

            if (fromWallet == null)
            {
                throw new CommonException(ReasonCode.Not_Allow_Withdrawal, Resources.禁止提币);
            }

            if (fromWallet.Balance < amount)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.余额不足);
            }

            var profileAgent = new MerchantProfileAgent();
            var profile      = profileAgent.GetMerchantProfile(accountId);

            int level = profile.L2VerifyStatus == VerifyStatus.Certified ? 2 : profile.L1VerifyStatus == VerifyStatus.Certified ? 1 : 0;

            var masterSetting = GetMerchantWithdrawalMasterSettingWithCrypto(cryptocurrency, level);

            if (amount > masterSetting.PerTxLimit)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.能高于单次提币量);
            }
            var     dac             = new MerchantWithdrawalDAC();
            var     today           = DateTime.UtcNow.Date;
            decimal dailyWithdrawal = dac.DailyWithdrawal(accountId, cryptoId, today);

            if (amount > masterSetting.PerDayLimit - dailyWithdrawal)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.今日提币达到限额);
            }
            decimal monthlyWithdrawal = dac.MonthlyWithdrawal(accountId, cryptoId, new DateTime(today.Year, today.Month, 1));

            if (amount > masterSetting.PerMonthLimit - monthlyWithdrawal)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.本月提币达到限额);
            }

            var fromWithdraw = new MerchantWithdrawal
            {
                MerchantAccountId = accountId,
                MerchantWalletId  = fromWallet.Id,
                Address           = address,
                Tag        = tag,
                Amount     = amount,
                Status     = TransactionStatus.UnSubmit,
                Timestamp  = DateTime.UtcNow,
                OrderNo    = NumberGenerator.GenerateUnixOrderNo(),
                CryptoId   = fromWallet.CryptoId,
                CryptoCode = fromWallet.CryptoCode
            };

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

            //是否是商户地址
            var toMerchantWallet = merchantWalletDac.GetByAddress(address, cryptocurrency.NeedTag ? tag : null);

            if (toMerchantWallet != null)
            {
                //if (toMerchantWallet.CryptoId != cryptoId)
                //    throw new CommonException(10000, string.Format(Resources.提币地址不是有效的地址, cryptocurrency.Code));
                //if (toMerchantWallet.MerchantAccountId == accountId)
                //    throw new CommonException(ReasonCode.CANNOT_TRANSFER_TO_YOURSELF, Resources.提币地址不能是自己账户的地址);
                //return WithdrawalToMerchantAccount(fromWallet, fromWithdraw, toMerchantWallet);
                // 042018
                throw new CommonException(ReasonCode.CAN_NOT_WITHDRAW_TO_FiiiPOS, Resources.FiiiPOSCantWithdrawToFiiiPOS);
            }

            //是否是用户地址
            var toUserWallet = userWalletDac.GetByAddressAndCrypto(cryptoId, address, cryptocurrency.NeedTag ? tag : null);

            if (toUserWallet != null)
            {
                if (toUserWallet.CryptoId != cryptoId)
                {
                    throw new CommonException(ReasonCode.GENERAL_ERROR, FiiiPay.Framework.Component.Properties.GeneralResources.EMInvalidAddress);
                }

                if (amount < masterSetting.ToUserMinAmount)
                {
                    throw new CommonException(10000, Resources.能低于最低提币量);
                }

                var fee = (fromWithdraw.Amount * masterSetting.ToUserHandleFeeTier).ToSpecificDecimal(cryptocurrency.DecimalPlace);
                if (amount <= fee)
                {
                    throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.到账数量不能为零或者负数);
                }

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

            //平台内提币如果tag不对,创建一条失败记录
            if (cryptocurrency.NeedTag && (userWalletDac.IsUserWalletAddress(address) || merchantWalletDac.IsMerchantWalletAddress(address)))
            {
                return(CancelWithdrawal(fromWithdraw));
            }

            //如果都不是,提币到场外
            if (amount < masterSetting.ToOutsideMinAmount)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.能低于最低提币量);
            }

            var baseFee  = cryptocurrency.Withdrawal_Fee ?? 0;
            var tier     = cryptocurrency.Withdrawal_Tier ?? 0;
            var fee1     = (amount * tier).ToSpecificDecimal(cryptocurrency.DecimalPlace);
            var totalFee = baseFee + fee1;

            if (amount <= totalFee)
            {
                throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.到账数量不能为零或者负数);
            }

            return(WithdrawalToOutside(fromWallet, fromWithdraw, cryptocurrency, account, amount, totalFee, address, tag, clientIP));
        }