public void Cancel(string email, int buyId) { var user = UserBusiness.GetValidUser(email); var buy = BuyBusiness.Get(buyId); if (buy == null || buy.UserId != user.Id || buy.ExpirationDate.HasValue) { throw new ArgumentException("Invalid purchase."); } if (buy.LastTransaction.TransactionStatus == TransactionStatus.Pending.Value) { if (string.IsNullOrEmpty(buy.LastTransaction.TransactionHash)) { TransactionBusiness.Process(buy.LastTransaction, TransactionStatus.Cancel); } else { try { var transaction = Web3.Web3Business.CheckTransaction(buy.LastTransaction.TransactionHash); throw new ArgumentException(transaction.BlockNumber.HasValue ? "The transaction is already minted." : "Pending transaction cannot be canceled."); } catch (DomainObjects.Web3.Web3Exception ex) { if (ex.Code == 404) { TransactionBusiness.Process(buy.LastTransaction, TransactionStatus.Cancel); } else { throw; } } } } else if (buy.LastTransaction.TransactionStatus == TransactionStatus.Error.Value) { using (var transaction = new TransactionalDapperCommand()) { var trans = TransactionBusiness.SetCanceled(user.Id); transaction.Insert(trans); var buyTrans = BuyTransactionBusiness.SetNew(buyId, trans.Id); transaction.Insert(buyTrans); transaction.Commit(); } } else { throw new ArgumentException("Invalid transaction status."); } }
public async Task CheckTransactionsAsync() { var pendingTransactions = Data.ListPendingTransactions(); foreach (var pending in pendingTransactions) { try { var transaction = Web3.Web3Business.CheckTransaction(pending.Transaction.TransactionHash); if (transaction.BlockNumber.HasValue) { if (transaction.Status.Value == 1) { TransactionBusiness.Process(pending.Transaction, TransactionStatus.Success); } else { TransactionBusiness.Process(pending.Transaction, TransactionStatus.Error); await Email.SendErrorEmailAsync($"Error on escrow result transaction {pending.TransactionId}, with hash {pending.Transaction.TransactionHash}."); } } } catch (DomainObjects.Web3.Web3Exception ex) { if (ex.Code == 404 && TransactionBusiness.TransactionCanBeConsideredLost(pending.Transaction)) { HandleLostTransaction(pending.Transaction, pending.Transaction.UserId, pending.EscrowResultId); } else { throw; } } catch (Exception ex) { Logger.LogCritical(ex, $"Exception on check escrow result transaction {pending.TransactionId}"); } } }
private TransactionStatus CheckAndProcessTransaction(Transaction buyTransaction, int buyId) { TransactionStatus status = TransactionStatus.Pending; try { var transaction = Web3.Web3Business.CheckTransaction(buyTransaction.TransactionHash, "Escrow(address,uint256)"); if (transaction.Status.HasValue) { if (transaction.Status.Value == 1) { if (transaction.EventData != null && transaction.EventData.Length == 2 && !string.IsNullOrEmpty(transaction.EventData[0]) && !string.IsNullOrEmpty(transaction.EventData[1])) { var wallet = WalletBusiness.GetByUser(buyTransaction.UserId); if (transaction.EventData[0].ToLower().Trim() != wallet.Address) { status = TransactionStatus.Fraud; } else { var purchase = BuyBusiness.GetSimple(buyId); var escrowedValue = Util.Util.ConvertBigNumber(transaction.EventData[1], 18); if (purchase.Price > escrowedValue) { status = TransactionStatus.Fraud; } else { var transactions = ListByUserAndHash(buyTransaction.UserId, buyTransaction.TransactionHash); if (transactions.Count > 1 && (transactions.Any(c => c.BuyId != buyId) || transactions.Any(c => c.Transaction.TransactionStatus != TransactionStatus.Pending.Value))) { status = TransactionStatus.Fraud; } else { status = TransactionStatus.Success; using (var trans = new TransactionalDapperCommand()) { purchase.ExpirationDate = DateTime.UtcNow.Date.AddDays(purchase.Days); trans.Update(purchase); buyTransaction.TransactionStatus = status.Value; buyTransaction.ProcessedDate = DateTime.UtcNow; trans.Update(buyTransaction); trans.Commit(); } } } } } else { status = TransactionStatus.Fraud; } } else { status = TransactionStatus.Error; } if (status != TransactionStatus.Success) { TransactionBusiness.Process(buyTransaction, status); } } } catch (DomainObjects.Web3.Web3Exception ex) { if (ex.Code == 404 && TransactionBusiness.TransactionCanBeConsideredLost(buyTransaction)) { HandleLostTransaction(buyTransaction, buyTransaction.UserId, buyId, null); } else { throw; } } return(status); }