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); }
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); }
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 })); }
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."))); }
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" }); } }
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)); } }
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() }); }
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) )); }