public async Task Business_Checking_AuthCapture_Successfully_Debit_Test() { var services = new ServiceCollection(); services.AddSingleton(_configuration); services.AddLogging(b => b.AddXunit(_output)); services.AddAuthorizeNet(); var sp = services.BuildServiceProvider(); var client = sp.GetRequiredService <ITransactionClient>(); var options = sp.GetRequiredService <IOptions <AuthorizeNetOptions> >(); var randomAccountNumber = new Random().Next(10000, int.MaxValue); var request = new CreateTransactionRequest { TransactionRequest = new TransactionRequestType { TransactionType = Enum.GetName(typeof(TransactionTypeEnum), TransactionTypeEnum.AuthCaptureTransaction), Amount = 13.01m, Payment = new PaymentType { BankAccount = new BankAccountType { BankName = "Bank of China", AccountType = BankAccountTypeEnum.BusinessChecking, RoutingNumber = "125008547", AccountNumber = randomAccountNumber.ToString(), // CheckNumber = "", NameOnAccount = "Biden", EcheckType = EcheckTypeEnum.CCD }, }, CustomerIP = options.Value.IpAddress, Order = new OrderType { InvoiceNumber = "BC-Invoice-789", Description = "Business Checking e-Check purchase" }, }, }; var response = await client.CreateAsync(request); _output.WriteLine($"{response.TransactionResponse.ResponseCode} - {response.TransactionResponse.TransId}"); Assert.Equal(MessageTypeEnum.Ok, response.Messages.ResultCode); var code = response.Messages.Message[0].Code; var text = response.Messages.Message[0].Text; Assert.Equal("I00001", code); Assert.Equal("Successful.", text); var tcode = response.TransactionResponse.Messages[0].Code; var ttext = response.TransactionResponse.Messages[0].Description; Assert.Equal("1", tcode); Assert.Equal("This transaction has been approved.", ttext); // 1 success Assert.Equal("1", response.TransactionResponse.ResponseCode); Assert.True(!string.IsNullOrEmpty(response.TransactionResponse.TransId)); Assert.False(response.TransactionResponse.Errors.Any()); }
public Task CreatePaymentTransactionAsync(CreateTransactionRequest request) { return(_runner.RunWithDefaultErrorHandlingAsync(() => _payInternalApi.CreatePaymentTransactionAsync(request))); }
public async Task ExecuteAsync() { IEnumerable <WalletState> cacheState = await _cacheMaintainer.GetAsync(); foreach (var walletState in cacheState) { if (walletState.Blockchain != BlockchainType.Bitcoin) { continue; } BalanceModel balance; try { balance = await _qBitNinjaClient.GetBalance(BitcoinAddress.Create(walletState.Address)); } catch (Exception ex) { _log.Error(ex, "Getting balance from ninja", walletState.ToDetails()); continue; } IEnumerable <PaymentBcnTransaction> bcnTransactions = GetIncomingPaymentOperations(balance, walletState.Address)?.ToList() ?? new List <PaymentBcnTransaction>(); IEnumerable <PaymentBcnTransaction> cacheTransactions = walletState.Transactions; IEnumerable <DiffResult <PaymentBcnTransaction> > diff = _diffService.Diff(cacheTransactions, bcnTransactions); // catching case when ninja returns no transactions but should if (cacheTransactions.Any() && !bcnTransactions.Any()) { _log.Info("There are no transactions from ninja, but there are transactions in cache", $"wallet: {walletState.Address}, walletState: {walletState.ToJson()}"); } // catching case when there are any differences between ninja state and local cache state if (diff.Any()) { _log.Info("The difference between cache state and ninja detected", $"wallet: {walletState.Address}, old txs: {walletState.Transactions.ToJson()}, new txs: {bcnTransactions.ToJson()}"); } // approach to exit loop with switch statement inside bool isSyncError = false; foreach (var diffResult in diff) { var tx = diffResult.Object; switch (diffResult.CompareState) { case DiffState.New: CreateTransactionRequest createRequest = null; try { var txDetails = await _qBitNinjaClient.GetTransaction(new uint256(tx.Id)); createRequest = tx.ToCreateRequest(txDetails, _bitcoinNetwork); _log.Info("New transaction detected", $"wallet: {walletState.Address}, Hash: {tx.Id}, FirstSeen: {txDetails.FirstSeen}"); await _log.LogPayInternalExceptionIfAny(() => _payInternalClient.CreatePaymentTransactionAsync(createRequest)); } catch (Exception ex) { _log.Error(ex, context: createRequest.ToDetails()); isSyncError = true; } break; case DiffState.Updated: UpdateTransactionRequest updateRequest = null; try { updateRequest = tx.ToUpdateRequest(); _log.Info("Transaction update detected", $"wallet: {walletState.Address}, new tx state: {tx.ToJson()}"); await _log.LogPayInternalExceptionIfAny(() => _payInternalClient.UpdateTransactionAsync(updateRequest)); } catch (Exception ex) { _log.Error(ex, context: updateRequest.ToDetails()); isSyncError = true; } break; default: throw new Exception("Unknown transactions diff state"); } // stop changes processing in case there is PayInternal sync error if (isSyncError) { break; } } if (bcnTransactions.Any()) { walletState.Transactions = bcnTransactions; } // will sync internal cache with blockchain only if there were no errors while processing changes // otherwise the changes will be processed again in the next job cycle // WARNING: the approach will work only for single transactions update if (!isSyncError) { try { await _cacheMaintainer.SetItemAsync(walletState); } catch (Exception ex) { _log.Error(ex, "Updating wallets cache", walletState.ToDetails()); continue; } } } }
public CreateTransactionCommand(Guid id, CreateTransactionRequest transaction) : base(id) { Transaction = transaction; }