public bool FiatWithdrawToCustomer(ApplicationUser brokerUser, BrokerOrder order) { var asset = order.AssetReceive; var amount = order.AmountReceive; var wallet = _walletProvider.GetFiat(asset); if (wallet == null) { _logger.LogError($"No fiat wallet for {asset}"); return(false); } var via = new ViaJsonRpc(_settings.AccessHttpUrl); var balance = via.BalanceQuery(brokerUser.Exchange.Id, asset); // validate amount var amountInt = wallet.AmountToLong(amount); var availableInt = wallet.StringToAmount(balance.Available); if (amountInt > availableInt) { _logger.LogError("broker available balance is too small"); return(false); } if (amountInt <= 0) { _logger.LogError("amount must be greather then or equal to 0"); return(false); } using (var dbtx = wallet.BeginDbTransaction()) { // register withdrawal with wallet var acct = new BankAccount { AccountNumber = order.Recipient }; var tx = wallet.RegisterPendingWithdrawal(brokerUser.Id, amountInt, acct); if (tx == null) { _logger.LogError($"Failed to create fiat withdrawal ('{order.Token}')"); return(false); } wallet.Save(); var businessId = tx.Id; try { // link pending withdrawal to broker order var bow = new BrokerOrderFiatWithdrawal { BrokerOrderId = order.Id, DepositCode = tx.DepositCode }; _context.BrokerOrderFiatWithdrawals.Add(bow); // we save changes here so that we a broker order cannot be processed twice(BrokerOrderChainWithdrawal.BrokerOrderId is unique) _context.SaveChanges(); } catch { _logger.LogError($"unable to create BrokerOrderChainWithdrawal object ({order.Id}, {tx.DepositCode}"); throw; } // register withdrawal with the exchange backend var negativeAmount = -amount; try { via.BalanceUpdateQuery(brokerUser.Exchange.Id, asset, "withdraw", businessId, negativeAmount.ToString(), null); } catch (ViaJsonException ex) { _logger.LogError(ex, "Failed to update (withdraw) user balance (xch id: {0}, asset: {1}, businessId: {2}, amount {3}", brokerUser.Exchange.Id, asset, businessId, negativeAmount); if (ex.Err == ViaError.BALANCE_UPDATE__BALANCE_NOT_ENOUGH) { dbtx.Rollback(); _logger.LogError("balance not enough"); return(false); } throw; } dbtx.Commit(); } return(true); }