public async Task <IActionResult> Post([FromBody] OrderViewModel model) { try { if (ModelState.IsValid) { var newOrder = mapper.Map <OrderViewModel, Order>(model); if (newOrder.OrderDate == DateTime.MinValue) { newOrder.OrderDate = DateTime.Now; } var currentUser = await userManager.FindByNameAsync(User.Identity.Name); newOrder.User = currentUser; if (newOrder.BitcoinPrice == 0) { logger.LogError($"BtcPrice is not correctly set modelPrice: {model.BtcPrice} newOrderPrice: {newOrder.BitcoinPrice}"); throw new Exception($"BtcPrice is not correctly set modelPrice: {model.BtcPrice} newOrderPrice: {newOrder.BitcoinPrice}"); } var subtotal = newOrder.Items.Sum(i => i.Quantity * i.UnitPrice); newOrder.OrderTotalInUSD = subtotal; newOrder.OrderTotalInBitcoin = Math.Round(subtotal / newOrder.BitcoinPrice, 8); RPCCredentialString cred = new RPCCredentialString(); cred.UserPassword = new NetworkCredential(config["NodeCredentials:RPCUser"], config["NodeCredentials:RPCPassword"]); RPCClient client = new RPCClient(cred, Network.TestNet); var address = await client.GetNewAddressAsync(); newOrder.BitcoinAddress = address.ToString(); repo.AddOrder(newOrder); if (repo.SaveAll()) { logger.LogInformation("New order created"); return(Created($"/api/orders/{newOrder.Id}", mapper.Map <Order, OrderViewModel>(newOrder))); } } else { logger.LogInformation("Order creation failed"); return(BadRequest(ModelState)); } } catch (Exception ex) { logger.LogError($"Failed to save new order: {ex}"); return(BadRequest($"Failed to save new order prvi")); } return(BadRequest("Failed to save new order drugi")); }
public async Task GetAsync(string id) //id is blockId { logger.LogInformation("New block has been mined"); RPCCredentialString cred = new RPCCredentialString(); cred.UserPassword = new NetworkCredential(config["NodeCredentials:RPCUser"], config["NodeCredentials:RPCPassword"]); RPCClient client = new RPCClient(cred, Network.TestNet); var unspent = client.ListUnspent(); foreach (var order in repo.GetAllOrders()) { if (order.DisregardOrder || order.OrderTransactionsConfirmed) { continue; } if (order.OrderDate.AddMinutes(15) < DateTime.Now && order.ReceivedValue < order.OrderTotalInBitcoin) //15 minutes or more has passed since order has been placed and payment did not met the requirements { order.DisregardOrder = true; } if (!order.OrderTransactionsConfirmed && order.ReceivedValue > 0) // if there are unconfirmed txes { bool confirmed = true; foreach (var unspentOutput in unspent.Where(tx => tx.Address.ToString() == order.BitcoinAddress)) { if (unspentOutput.Confirmations < 6) // one of transactions of order has less than 6 confirmations { confirmed = false; // transactions for this order have not been confirmed break; } } if (confirmed == true) // all transactions are confirmed and there has been at least some payment { order.OrderTransactionsConfirmed = true; await mailService.SendEmailAsync( order.User.Email, "Your Transactions have been confirmed!", $"Accordion Fair is pleased to inform you that your transactions for order {order.OrderNumber} have been confirmed." ); repo.SaveAll(); } } } }
public async Task GetAsync(string id) //id is txid { RPCCredentialString cred = new RPCCredentialString(); cred.UserPassword = new NetworkCredential(config["NodeCredentials:RPCUser"], config["NodeCredentials:RPCPassword"]); RPCClient client = new RPCClient(cred, Network.TestNet); var transaction = await client.GetRawTransactionAsync(uint256.Parse(id), false); Order order = null; BitcoinAddress orderAddress = null; foreach (var output in transaction.Outputs) // looping through tx outputs and searching for address that has an order { order = repo.GetOrderByBitcoinAddress(output.ScriptPubKey.GetDestinationAddress(Network.TestNet).ToString()); if (order != null) { logger.LogInformation("Found order for received transaction. " + System.DateTime.Now); orderAddress = output.ScriptPubKey.GetDestinationAddress(Network.TestNet); break; } } if (order == null) { logger.LogInformation($"Could not find order for received transaction. " + System.DateTime.Now); return; } if (order.Transactions != null) { foreach (var tx in order.Transactions.ToList()) { if (tx.TransactionId == id) { logger.LogInformation("That transaction hass been added to order already. " + System.DateTime.Now); return; } } } else { order.Transactions = new List <OrderTransaction>(); } var subtotal = order.Items.Sum(i => i.Quantity * i.UnitPrice); var totrecbyadr = await client.GetReceivedByAddressAsync(orderAddress, 0); // 0 confirmations var totalReceivedFromAddress = (double)totrecbyadr.ToDecimal(MoneyUnit.BTC); var receivedInThisTransaction = Math.Round(totalReceivedFromAddress - order.ReceivedValue, 8); order.ReceivedValue = totalReceivedFromAddress; order.Transactions.Add( new OrderTransaction { TransactionId = id, Amount = receivedInThisTransaction }); logger.LogInformation("transaction for order has been added. " + System.DateTime.Now); if (totalReceivedFromAddress * order.BitcoinPrice == subtotal) { order.OrderPaymentValid = true; } else if (totalReceivedFromAddress * order.BitcoinPrice > subtotal) { order.OrderPaymentValid = true; order.MoreThanNecessary = true; } var receivedAmountToUSD = receivedInThisTransaction * order.BitcoinPrice; if (receivedAmountToUSD >= subtotal) { order.OrderPaymentValid = true; } if (receivedAmountToUSD > subtotal) { order.MoreThanNecessary = true; } if (!repo.SaveAll()) // saveChanges is zero, save all didnt save anything { logger.LogError("Nothing has been saved " + System.DateTime.Now); } logger.LogInformation($"Transaction with ID: {id} was called for address {orderAddress.ToString()} with {receivedInThisTransaction} btc"); await hub.Clients.Group(order.User.UserName).SendAsync("ReceiveNotification", id, receivedInThisTransaction, totalReceivedFromAddress); }