public async Task ShouldSetEnumStatus() { var tableName = "integration"; await _sut.DeleteTableAsync(tableName); await _sut.CreateTableAsync(tableName); var userId = 123; var rowKey = (DateTime.MaxValue.Ticks - DateTime.UtcNow.Ticks).ToString(); var userWithDrawalEntity = await _sut.Retrieve <UserWithdrawal>(tableName, userId.ToString(), rowKey); Assert.IsNull(userWithDrawalEntity); userWithDrawalEntity = new UserWithdrawal(userId) { RowKey = rowKey, State = WithdrawalState.Failed, StartDate = DateTime.UtcNow, Timestamp = DateTimeOffset.UtcNow }; await _sut.InsertOrMergeEntity(tableName, userWithDrawalEntity); var userWithdrawal = await _sut.Retrieve <UserWithdrawal>(tableName, userId.ToString(), rowKey); Assert.IsNotNull(userWithdrawal); Assert.AreEqual(userWithdrawal.State, userWithDrawalEntity.State); }
public long Create(UserWithdrawal UserWithdrawal) { const string sql = @"INSERT INTO [dbo].[UserWithdrawals] ([UserAccountId], [UserWalletId], [Address],[Tag], [Amount], [Status], [Timestamp], [Remark], [OrderNo], [TransactionId], [SelfPlatform],[RequestId],[CryptoId],[CryptoCode]) VALUES (@UserAccountId, @UserWalletId, @Address,@Tag, @Amount, @Status, @Timestamp, @Remark, @OrderNo, @TransactionId, @SelfPlatform,@RequestId,@CryptoId,@CryptoCode); SELECT SCOPE_IDENTITY()"; using (var conn = WriteConnection()) { return(conn.ExecuteScalar <long>(sql, UserWithdrawal)); } }
public async Task <UserWithdrawal> GetLastWithdrawal() { UserWithdrawal result = null; var request = GetRequest("api/Withdrawal/GetLastWithdrawal"); var response = await Client.SendAsync(request); if (response.StatusCode == HttpStatusCode.OK) { var responseText = await response.Content.ReadAsStringAsync(); result = JSSerializer.Deserialize <UserWithdrawal>(responseText); } return(result); }
private async Task SetWithdrawalState(bool isSuccess, UserWithdrawal userWithdrawal, long chatId, int chatUserId, double amount, string transactionId) { if (!isSuccess) { userWithdrawal.State = WithdrawalState.Failed; await _withdrawalRepository.AddOrUpdate(userWithdrawal); await _botService.SendTextMessage(chatId, ReplyConstants.UnableToWithdraw); } else { await SetWithdrawalSuccess(userWithdrawal, chatId, chatUserId, amount, transactionId); } }
private async Task SetWithdrawalSuccess(UserWithdrawal userWithdrawal, long chatId, int chatUserId, double amount, string transactionId) { var userBalance = await _userBalanceRepository.Get(chatUserId); userBalance.Balance -= amount; await _userBalanceRepository.Update(userBalance); if (userBalance.Balance < 0) { _logger.LogError($"Balance for {chatUserId} is below 0 after withdrawal transaction {transactionId}"); } userWithdrawal.State = WithdrawalState.Completed; await _withdrawalRepository.AddOrUpdate(userWithdrawal); await _botService.SendTextMessage(chatId, ReplyConstants.WithdrawalSuccess); }
//private WithdrawOM WithdrawalToMerchantAccount(UserWallet fromWallet, UserWithdrawal fromWithdraw, UserWithdrawalFee fromWithdrawFee, MerchantWallet toWallet, Cryptocurrency cryptocurrency) //{ // var mastSettings = new MasterSettingDAC().SelectByGroup("UserWithdrawal"); // using (var scope = new TransactionScope()) // { // //提币 // fromWithdraw.Status = Framework.Enums.TransactionStatus.Confirmed; // fromWithdraw.TransactionId = toWallet.MerchantAccountId.ToString("N"); // fromWithdraw.SelfPlatform = true;//平台内提币 // fromWithdraw.Id = new UserWithdrawalDAC().Create(fromWithdraw); // fromWithdrawFee.WithdrawalId = fromWithdraw.Id; // fromWithdrawFee.Fee = fromWithdraw.Amount * Convert.ToDecimal(mastSettings.First(e => e.Name == "UserWithdrawal_ToMerchant").Value); // fromWithdrawFee.Fee = fromWithdrawFee.Fee.ToSpecificDecimal(cryptocurrency.DecimalPlace); // new UserWithdrawalFeeDAC().Create(fromWithdrawFee); // new UserWalletDAC().Decrease(fromWallet.Id, fromWithdraw.Amount); // new UserWalletStatementDAC().Insert(new UserWalletStatement // { // WalletId = fromWallet.Id, // Action = MerchantWalletStatementAction.Withdrawal, // Amount = -fromWithdraw.Amount, // Balance = fromWallet.Balance - fromWithdraw.Amount, // Timestamp = DateTime.UtcNow // }); // //充币 // var amount = fromWithdraw.Amount - fromWithdrawFee.Fee; // if (amount <= 0) // { // throw new CommonException(ReasonCode.GENERAL_ERROR, Resources.到账数量不能为零或者负数); // } // var deposit = new MerchantDepositDAC().Insert(new MerchantDeposit // { // MerchantAccountId = toWallet.MerchantAccountId, // MerchantWalletId = toWallet.Id, // FromAddress = fromWallet.Address, // ToAddress = toWallet.Address, // Amount = fromWithdraw.Amount - fromWithdrawFee.Fee, // Status = Framework.Enums.TransactionStatus.Confirmed, // Timestamp = DateTime.UtcNow, // OrderNo = CreateOrderno(), // TransactionId = fromWallet.UserAccountId.ToString("N"), // SelfPlatform = true // }); // new MerchantWalletDAC().Increase(toWallet.Id, amount); // new MerchantWalletStatementDAC().Insert(new MerchantWalletStatement // { // WalletId = toWallet.Id, // Action = MerchantWalletStatementAction.Deposit, // Amount = amount, // Balance = toWallet.Balance + amount, // Timestamp = DateTime.UtcNow // }); // new FiiiPayPushComponent().PushWithdrawCompleted(fromWithdraw.Id); // scope.Complete(); // UserMSMQ.PubMerchantDeposit(deposit.Id, 0); // } // return new WithdrawOM // { // OrderId = fromWithdraw.Id, // OrderNo = fromWithdraw.OrderNo, // Timestamp = fromWithdraw.Timestamp.ToUnixTime().ToString() // }; //} private WithdrawOM CancelWithdrawal(UserWithdrawal fromWithdraw) { fromWithdraw.Status = TransactionStatus.Cancelled; fromWithdraw.TransactionId = Guid.NewGuid().ToString("N"); fromWithdraw.SelfPlatform = true;//平台内提币 using (var scope = new TransactionScope()) { fromWithdraw.Id = new UserWithdrawalDAC().Create(fromWithdraw); 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 }); var fromWithdrawFee = new UserWithdrawalFee { Amount = fromWithdraw.Amount, Fee = 0, Timestamp = DateTime.UtcNow, WithdrawalId = fromWithdraw.Id }; new UserWithdrawalFeeDAC().Create(fromWithdrawFee); scope.Complete(); } UserMSMQ.PubUserWithdrawReject(fromWithdraw.Id, 0); return(new WithdrawOM { OrderId = fromWithdraw.Id, OrderNo = fromWithdraw.OrderNo, Timestamp = fromWithdraw.Timestamp.ToUnixTime().ToString() }); }
public void InitTransactionId(UserWithdrawal withdrawal) { const string sql = @"UPDATE [dbo].[UserWithdrawals] SET [TransactionId] = @TransactionId WHERE UserAccountId=@UserAccountId AND UserWalletId=@UserWalletId AND RequestId=@RequestId"; using (var conn = ReadConnection()) { conn.Execute(sql, new { UserAccountId = withdrawal.UserAccountId, UserWalletId = withdrawal.UserWalletId, RequestId = withdrawal.RequestId.Value, withdrawal.TransactionId }); } }
private async Task <bool> VerifyTx(string transactionId, UserWithdrawal userWithdrawal) { try { var txResponse = await _mhcHttpClient.GetTx(transactionId); if (txResponse.TxResult?.Transaction?.Status == "ok") { userWithdrawal.State = WithdrawalState.Completed; await _withdrawalRepository.AddOrUpdate(userWithdrawal); return(true); } } catch (Exception ex) { _logger.LogError($"Could not verify transaction {transactionId}", ex); } return(false); }
public async Task <ActionResult <string> > MakeWithdrawal(int reqId, string status, string counts, [FromBody] Withdrawal withdrawal) { if (ModelState.IsValid && withdrawal != null && reqId > 0) { Request request = _context.Request.Where(r => r.Id == reqId).FirstOrDefault <Request>(); if (request == null) { return(NotFound("User not found")); } User user = _context.User.Where(u => u.Id == _context.Request.Where(r => r.Id == request.Id).FirstOrDefault <Request>().User.Id).FirstOrDefault <User>(); if (user == null) { return(NotFound("User not found")); } withdrawal.DateTime = DateTime.Now; // get current date and time; UserWithdrawal userWithdrawal = new UserWithdrawal() { Withdrawal = withdrawal, User = user }; if (status.Contains("E0")) { request.Response = "Withdrawal successful"; } else { request.Response = "Withdrawal status: " + status; } string strV = "" + counts[0] + "" + counts[1]; int c100 = int.Parse(strV); strV = "" + counts[2] + "" + counts[3]; int c50 = int.Parse(strV); if (c100 + c50 <= 0) { request.isCompleted = true; request.Counts = counts; _context.Request.Update(request); await _context.SaveChangesAsync(); return(request.Response); } Safe safe = _context.Safe.FirstOrDefault <Safe>(); safe.Bill100 = safe.Bill100 - c100; safe.Bill50 = safe.Bill50 - c50; withdrawal.Value = c100 * 100 + c50 * 50; request.isCompleted = true; request.Counts = counts; _context.Request.Update(request); _context.Withdrawal.Add(withdrawal); _context.UserWithdrawal.Add(userWithdrawal); _context.Safe.Update(safe); await _context.SaveChangesAsync(); int deposits = (int)new CreditsController(_context).GetUserTotalCredit(user.Id).Result.Value; int withdrawals = (int)GetUserTotalWithdrawal(user.Id).Result.Value; int balance = deposits - withdrawals; return(request.Response); } else { return(BadRequest("inavlid withdrawal request details")); } }
private WithdrawOM WithdrawalToUserAccount(UserWallet fromWallet, UserWithdrawal fromWithdraw, UserWallet toWallet) { var mastSettings = new MasterSettingDAC().SelectByGroup("UserWithdrawal"); UserDeposit model = new UserDeposit(); using (var scope = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(0, 0, 1, 30))) { fromWithdraw.Status = TransactionStatus.Confirmed; fromWithdraw.TransactionId = toWallet.UserAccountId.ToString("N"); fromWithdraw.SelfPlatform = true;//平台内提币 fromWithdraw.Id = new UserWithdrawalDAC().Create(fromWithdraw); new UserTransactionDAC().Insert(new UserTransaction { Id = Guid.NewGuid(), AccountId = fromWithdraw.UserAccountId, CryptoId = fromWallet.CryptoId, CryptoCode = fromWallet.CryptoCode, Type = UserTransactionType.Withdrawal, DetailId = fromWithdraw.Id.ToString(), Status = (byte)fromWithdraw.Status, Timestamp = fromWithdraw.Timestamp, Amount = fromWithdraw.Amount, OrderNo = fromWithdraw.OrderNo }); var fromWithdrawFee = new UserWithdrawalFee { Amount = fromWithdraw.Amount, WithdrawalId = fromWithdraw.Id, Fee = fromWithdraw.Amount * Convert.ToDecimal(mastSettings.First(e => e.Name == "UserWithdrawal_ToUser").Value), Timestamp = DateTime.UtcNow }; new UserWithdrawalFeeDAC().Create(fromWithdrawFee); new UserWalletDAC().Decrease(fromWallet.Id, fromWithdraw.Amount); new UserWalletStatementDAC().Insert(new UserWalletStatement { WalletId = fromWallet.Id, Action = MerchantWalletStatementAction.Withdrawal, Amount = -fromWithdraw.Amount, Balance = fromWallet.Balance - fromWithdraw.Amount, FrozenAmount = 0, FrozenBalance = fromWallet.FrozenBalance, Timestamp = DateTime.UtcNow }); //充币 var amount = fromWithdraw.Amount - fromWithdrawFee.Fee; if (amount <= 0) { throw new CommonException(ReasonCode.GENERAL_ERROR, MessageResources.ArrivalAmountError); } new UserWalletDAC().Increase(toWallet.Id, amount); new UserWalletStatementDAC().Insert(new UserWalletStatement { WalletId = toWallet.Id, Action = UserWalletStatementAction.Deposit, Amount = amount, Balance = toWallet.Balance + amount, FrozenAmount = 0, FrozenBalance = toWallet.FrozenBalance, Timestamp = DateTime.UtcNow }); model = new UserDepositDAC().Insert(new UserDeposit { UserAccountId = toWallet.UserAccountId, UserWalletId = toWallet.Id, FromAddress = fromWallet.Address, FromTag = fromWallet.Tag, ToAddress = toWallet.Address, ToTag = toWallet.Tag, Amount = amount, Status = TransactionStatus.Confirmed, Timestamp = DateTime.UtcNow, OrderNo = IdentityHelper.OrderNo(), TransactionId = fromWallet.UserAccountId.ToString("N"), SelfPlatform = true, CryptoCode = fromWallet.CryptoCode }); new UserTransactionDAC().Insert(new UserTransaction { Id = Guid.NewGuid(), AccountId = model.UserAccountId, CryptoId = fromWallet.CryptoId, CryptoCode = fromWallet.CryptoCode, Type = UserTransactionType.Deposit, DetailId = model.Id.ToString(), Status = (byte)model.Status, Timestamp = model.Timestamp, Amount = model.Amount, OrderNo = model.OrderNo }); scope.Complete(); } UserMSMQ.PubUserWithdrawCompleted(fromWithdraw.Id, 0); UserMSMQ.PubUserDeposit(model.Id, 0); return(new WithdrawOM { OrderId = fromWithdraw.Id, OrderNo = fromWithdraw.OrderNo, Timestamp = fromWithdraw.Timestamp.ToUnixTime().ToString() }); }
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() }); }
public async Task Handle(Chat chat, int chatUserId, double amount) { var walletUser = GetWallet(chatUserId); var userBalance = await _userBalanceRepository.Get(chatUserId); if (userBalance.Balance < amount) { await _botService.SendTextMessage(chat.Id, string.Format(ReplyConstants.InsufficientBalance, userBalance.Balance.RoundMetahashHash(), amount.RoundMetahashHash())); } else { if (walletUser != null) { var walletAddress = walletUser.PartitionKey; try { // get previous withdrawals and see if they completed. We do this in case the network sends a failed transaction and would still complete after 10 minutes. var lastWithdrawal = _withdrawalRepository.GetByUserId(walletUser.GetUserId().GetValueOrDefault()); if (lastWithdrawal != null && lastWithdrawal.StartDate > DateTime.UtcNow.AddMinutes(-15) && lastWithdrawal.State != WithdrawalState.Completed) { _logger.LogInformation($"Retrying to verify Tx {lastWithdrawal.TxId}"); var isSuccess = await VerifyTx(lastWithdrawal.TxId, lastWithdrawal); _logger.LogInformation($"Verify Tx {lastWithdrawal.TxId} result is {isSuccess}"); await SetWithdrawalState(isSuccess, lastWithdrawal, chat.Id, chatUserId, amount, lastWithdrawal.TxId); } else { if (lastWithdrawal != null && lastWithdrawal.StartDate > DateTime.UtcNow.AddHours(-4)) { _logger.LogInformation($"Withdrawal denied for user {chatUserId}. Only 1 withdrawal is allowed every 4h."); await _botService.SendTextMessage(chat.Id, ReplyConstants.WithdrawLimit); } else { var userWithdrawal = new UserWithdrawal(chatUserId) { WalletAddress = walletAddress, Amount = amount, State = WithdrawalState.Created, StartDate = DateTime.UtcNow }; await _withdrawalRepository.AddOrUpdate(userWithdrawal); var transactionId = await _nodeExecutionService.Withdraw(walletAddress, amount); if (!string.IsNullOrEmpty(transactionId)) { userWithdrawal.TxId = transactionId; userWithdrawal.State = WithdrawalState.Verification; await _withdrawalRepository.AddOrUpdate(userWithdrawal); await _botService.SendTextMessage(chat.Id, ReplyConstants.WithdrawVerification); // make sure network is up to date System.Threading.Thread.Sleep(5000); if (!await VerifyTx(transactionId, userWithdrawal)) { await _botService.SendTextMessage(chat.Id, ReplyConstants.WithdrawVerificationLonger); // make sure network is up to date System.Threading.Thread.Sleep(20000); var isSuccess = await VerifyTx(transactionId, userWithdrawal); await SetWithdrawalState(isSuccess, userWithdrawal, chat.Id, chatUserId, amount, transactionId); } else { await SetWithdrawalSuccess(userWithdrawal, chat.Id, chatUserId, amount, transactionId); } } else { userWithdrawal.State = WithdrawalState.Failed; await _withdrawalRepository.AddOrUpdate(userWithdrawal); } } } } catch (Exception ex) { _logger.LogCritical( $"Withdrawal failed for userId: {chatUserId} and wallet: {walletAddress} for amount: {amount}", ex); await _botService.SendTextMessage(chat.Id, ReplyConstants.UnableToWithdraw); } } } }
public async Task AddOrUpdate(UserWithdrawal transaction) { await _tableStorageService.InsertOrMergeEntity(TableName, transaction); }