Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        private MerchantWithdrawal WithdrawalToOutside(MerchantWallet fromWallet, MerchantWithdrawal fromWithdraw, Cryptocurrency cryptocurrency,
                                                       MerchantAccount account, decimal amount, decimal fee, string address, string tag, string clientIP)
        {
            var actualAmount = amount - fee;

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

            using (var scope = new TransactionScope())
            {
                try
                {
                    fromWithdraw.Status = TransactionStatus.UnSubmit;
                    fromWithdraw        = new MerchantWithdrawalDAC().Create(fromWithdraw);
                    var fromWithdrawFee = new MerchantWithdrawalFee
                    {
                        Amount       = amount,
                        Fee          = fee,
                        Timestamp    = DateTime.UtcNow,
                        WithdrawalId = fromWithdraw.Id
                    };
                    new MerchantWithdrawalFeeDAC().Create(fromWithdrawFee);
                    new MerchantWalletDAC().Freeze(fromWallet.Id, amount);

                    //var requestInfo = new FiiiFinanceAgent().TryCreateWithdraw(requestModel);

                    //new MerchantWithdrawalDAC().UpdateTransactionId(fromWithdraw.Id, requestInfo.RequestID,
                    //    requestInfo.TransactionId);

                    scope.Complete();
                }
                catch (CommonException)
                {
                    throw;
                }
                catch (Exception ex)
                {
                    _logger.Info($"Withdraw ApplyWithdrawal faild.WithdrawID:{fromWithdraw.Id},OrderNo:{fromWithdraw.OrderNo}.request Parameter - . Error message:{ex.Message}");
                    throw;
                }
            }
            var requestModel = new CreateWithdrawModel
            {
                AccountID        = account.Id,
                AccountType      = AccountTypeEnum.Merchant,
                CryptoName       = cryptocurrency.Code,
                ReceivingAddress = address,
                DestinationTag   = tag,
                Amount           = actualAmount,
                IPAddress        = clientIP,
                TransactionFee   = fee,
                WithdrawalId     = fromWithdraw.Id
            };

            RabbitMQSender.SendMessage("WithdrawSubmit", requestModel);

            return(fromWithdraw);
        }
Ejemplo n.º 3
0
 public async Task <IWriterResult <int> > CreateWithdraw(string userId, CreateWithdrawModel model)
 {
     return(await WithdrawService.QueueWithdraw(new CreateWithdraw
     {
         IsApi = false,
         UserId = userId,
         Address = model.Address,
         Amount = model.Amount,
         ConfirmationToken = model.ConfirmationToken,
         CurrencyId = model.CurrencyId
     }));
 }
Ejemplo n.º 4
0
        public async Task <ActionResult> Create(CreateWithdrawModel model)
        {
            if (model.TwoFactorType == TwoFactorType.None)
            {
                // If there is no tfa remove the Data field validation.
                ModelState.Remove("Data");
            }

            if (!ModelState.IsValid)
            {
                return(View("CreateWithdrawModal", model));
            }

            var user = await UserManager.FindByIdAsync(User.Id());

            if (user == null)
            {
                return(Unauthorized());
            }

            // Verify TwoFactor code.
            if (!await UserManager.VerifyUserTwoFactorCodeAsync(TwoFactorComponentType.Withdraw, user.Id, model.Data))
            {
                ModelState.AddModelError("Data", "Invalid TwoFactor code.");
                return(View("CreateWithdrawModal", model));
            }

            // Create withdraw
            var twoFactortoken = await UserManager.GenerateUserTwoFactorTokenAsync(TwoFactorTokenType.WithdrawConfirm, user.Id);

            model.ConfirmationToken = twoFactortoken;
            var result = await WithdrawWriter.CreateWithdraw(user.Id, model);

            if (!ModelState.IsWriterResultValid(result))
            {
                return(View("CreateWithdrawModal", model));
            }

            int withdrawId = result.Data;

            // Send confirmation email
            await SendConfirmationEmail(user, twoFactortoken, withdrawId, model);

            return(ViewMessageModal(new ViewMessageModel(ViewMessageType.Success, "Withdraw Success", "Your withdraw request has been sucessfully submitted, A confirmation email has been sent to your registered email address.")));
        }
Ejemplo n.º 5
0
        public async Task <CreateWithdrawResponseModel> CreateWithdraw(string userId, CreateWithdrawModel model, bool isApi)
        {
            try
            {
                var estimatedPrice = await BalanceEstimationService.GetNZDPerCoin(model.CurrencyId).ConfigureAwait(false);

                var estimatedTotal     = model.Amount * estimatedPrice;
                var verificationResult = await UserVerificationReader.GetVerificationStatus(userId);

                if (verificationResult.Level != VerificationLevel.Legacy && (verificationResult.Current + estimatedTotal) > verificationResult.Limit)
                {
                    return new CreateWithdrawResponseModel {
                               Error = $"Withdraw exceeds daily limit of ${verificationResult.Limit:F2} NZD."
                    }
                }
                ;

                using (var tradeService = CreateService())
                {
                    var response = await tradeService.SubmitWithdrawAsync(new SubmitWithdrawRequest
                    {
                        Address        = model.Address,
                        Amount         = model.Amount,
                        CurrencyId     = model.CurrencyId,
                        TwoFactorToken = model.TwoFactorToken,
                        Type           = model.Type,
                        UserId         = new Guid(userId),
                        EstimatedPrice = estimatedTotal,
                        IsApi          = isApi
                    }).ConfigureAwait(false);

                    return(new CreateWithdrawResponseModel
                    {
                        Error = response.Error,
                        WithdrawId = response.WithdrawId
                                     //	Notifications = await ProcessNotifications(response),
                    });
                }
            }
            catch (Exception)
            {
                return(new CreateWithdrawResponseModel {
                    Error = "An Error occurred creating withdraw request, if problem persist please contact Cryptopia Support"
                });
            }
        }
Ejemplo n.º 6
0
        public async Task <IWriterResult <int> > CreateWithdraw(string userId, CreateWithdrawModel model)
        {
            var currentUser = new Guid(userId);
            var currency    = await CurrencyReader.GetCurrency(model.CurrencyId);

            if (currency == null)
            {
                return(new WriterResult <int>(false, $"Currency not available for withdraw, Status: Not Found"));
            }

            using (var context = ExchangeDataContextFactory.CreateContext())
            {
                var user = await context.Users.FirstOrDefaultAsync(x => x.Id == currentUser).ConfigureAwait(false);

                if (user == null || string.IsNullOrEmpty(model.TwoFactorToken))
                {
                    return(new WriterResult <int>(false, "Unauthorized."));
                }

                var balance = await context.Balance.FirstOrDefaultAsync(x => x.UserId == user.Id && x.CurrencyId == model.CurrencyId).ConfigureAwait(false);

                if (balance == null || model.Amount > balance.Available)
                {
                    return(new WriterResult <int>(false, "Insufficient funds."));
                }

                if (currency.Status == CurrencyStatus.Maintenance || currency.Status == CurrencyStatus.Offline || currency.Status == CurrencyStatus.NoConnections)
                {
                    return(new WriterResult <int>(false, $"Currency not available for withdraw, Status: {currency.Status}"));
                }

                if (model.Amount < currency.WithdrawMin || model.Amount >= currency.WithdrawMax)
                {
                    return(new WriterResult <int>(false, "Withdrawal amount must be between {0} and {1} {2}", currency.WithdrawMin, currency.WithdrawMax, currency.Symbol));
                }

                // Check address is in whitelist if whitelist enabled
                var safeAddressExists =
                    await
                    context.AddressBook.AnyNoLockAsync(
                        x => x.UserId == user.Id && x.CurrencyId == balance.CurrencyId && x.Address == model.Address && x.IsEnabled)
                    .ConfigureAwait(false);

                if (!user.IsUnsafeWithdrawEnabled && !safeAddressExists)
                {
                    return(new WriterResult <int>(false, "Address does not exist in your secure Withdraw Address Book."));
                }

                // Validate the address
                if (!await DepositService.ValidateAddress(balance.CurrencyId, model.Address).ConfigureAwait(false))
                {
                    return(new WriterResult <int>(false, "Invalid {0} address.", currency.Symbol));
                }

                var response = await TradeService.CreateWithdraw(userId, new CreateWithdrawModel
                {
                    Address        = model.Address,
                    Amount         = Math.Max(0, model.Amount),
                    CurrencyId     = balance.CurrencyId,
                    TwoFactorToken = model.TwoFactorToken,
                    Type           = model.Type
                }).ConfigureAwait(false);

                if (response.IsError)
                {
                    return(new WriterResult <int>(false, response.Error));
                }

                return(new WriterResult <int>(true, response.WithdrawId));
            }
        }
Ejemplo n.º 7
0
        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()
            });
        }
Ejemplo n.º 8
0
        private async Task <bool> SendConfirmationEmail(User user, string confirmToken, int withdrawId, CreateWithdrawModel model)
        {
            var cancelWithdrawToken = await UserManager.GenerateUserTwoFactorTokenAsync(TwoFactorTokenType.WithdrawCancel, user.Id);

            var confirmlink = Url.Action("ConfirmWithdraw", "Withdraw", new { username = user.UserName, secureToken = confirmToken, withdrawid = withdrawId }, protocol: Request.Url.Scheme);
            var cancellink  = Url.Action("CancelWithdraw", "Withdraw", new { username = user.UserName, secureToken = cancelWithdrawToken, withdrawid = withdrawId }, protocol: Request.Url.Scheme);

            return(await EmailService.Send(EmailType.WithdrawConfirmation, user, Request.GetIPAddress()
                                           , new EmailParam("[CONFIRMLINK]", confirmlink)
                                           , new EmailParam("[CANCELLINK]", cancellink)
                                           , new EmailParam("[WITHDRAWID]", withdrawId)
                                           , new EmailParam("[CURRENCY]", model.Symbol)
                                           , new EmailParam("[AMOUNT]", model.Amount)
                                           , new EmailParam("[ADDRESS]", model.Address)
                                           , new EmailParam("[FEE]", model.Fee)
                                           ));
        }