public void SetUp() { _request = _fixture.Create <ProcessPaymentCommandRequestModel>(); _processPaymentCommandRequestValidatorMock.Setup(x => x.Validate(_request)) .Returns(Enumerable.Empty <ValidationError>()); _acmeProcessPaymentResult = new AcmeProcessPaymentResult { Id = Guid.NewGuid(), WasSuccessful = true, Error = null }; _acmeBankApiMock.Setup(x => x.ProcessPayment(_request.CreditCardNumber, _request.CVV, _request.ExpiryMonth, _request.ExpiryYear, _request.Amount, _request.Currency, _request.CustomerName)) .ReturnsAsync(() => _acmeProcessPaymentResult); var options = new DbContextOptionsBuilder <PaymentGatewayDatabaseContext>() .UseInMemoryDatabase(Guid.NewGuid().ToString()) .Options; _paymentGatewayDatabaseContext = new PaymentGatewayDatabaseContext(options); _fixture.Inject(_paymentGatewayDatabaseContext); _subject = _fixture.Create <ProcessPaymentCommand>(); }
public async Task Proccess_And_Persist_Payment_When_Acquiring_Bank_Fails_To_Process_Payment() { var someId = Guid.NewGuid().ToString(); var mockPaymentRepository = new Mock <IAggregateStore <Payment> >(); var mockCyptoService = new Mock <ICryptoService>(); var mockBankClient = new Mock <IAquiringBankClient>(); var mockLogger = new Mock <ILogger>(); mockBankClient.Setup(x => x.ProcessPayment(It.IsAny <BankPaymentRequest>())) .ReturnsAsync(new BankPaymentResponse { PaymentIdentifier = someId, PaymentStatus = PaymentStatus.Failed }); mockCyptoService.Setup(x => x.Encrypt(It.IsAny <string>(), It.IsAny <string>())) .Returns("__encripted__"); var sut = new ProcessPaymentCommandHandler(mockPaymentRepository.Object, mockCyptoService.Object, mockBankClient.Object, mockLogger.Object); ProcessPaymentCommand command = new ProcessPaymentCommand { Amount = 100, Currency = "EUR", CardExpiryYear = "24", CardExpiryMonth = "4", CardNumber = "5564876598743467", CVV = "782", }; await sut.Handle(command, new System.Threading.CancellationToken()); mockCyptoService.Verify(x => x.Encrypt(command.CardNumber, It.IsAny <string>()), Times.Once); mockPaymentRepository.Verify(x => x.AppendChanges(It.Is <Payment>(y => y.CardNumber == "__encripted__")), Times.Once); mockPaymentRepository.Verify(x => x.AppendChanges(It.Is <Payment>(y => y.BankPaymentIdentifier == someId)), Times.Once); mockPaymentRepository.Verify(x => x.AppendChanges(It.Is <Payment>(y => y.PaymentStatus == PaymentStatus.Failed)), Times.Once); }
public async Task <Result <long> > Handle(ProcessPaymentCommand request, CancellationToken cancellationToken) { var isPaymentCaptured = await capturePaymentAsync(request); var paymentState = isPaymentCaptured ? PaymentState.Processed : PaymentState.Failed; var payment = new PaymentRequest() { Amount = request.Amount, Card = new Domain.ValueObjects.CreditCard() { CardHolderName = request.CardHolderName, ExpirationDate = request.ExpirationDate, Number = request.CardNumber, SecurityCode = request.SecurityCode }, CurrentState = paymentState, IsDeleted = false, }; payment.States.Add(new PaymentRequestState() { Request = payment, State = paymentState, At = DateTimeOffset.Now, }); _dataContext.Payments.Add(payment); await _dataContext.SaveChangesAsync(cancellationToken); return(Result.Ok(payment.Id)); }
public async Task ProcessPayment_ReturnsPayment() { //Arrange var request = new ProcessPaymentRequest { Amount = 100, Currency = "EUR", FullName = "Dmitriy Purtseladze", CardNumber = "5555-5555-5555-5555", Cvv = 123, Expiry = "08/22" }; _bankService.ProcessPaymentAsync(request).Returns(new BankServiceResponse { IsSuccessHttpStatusCode = true, HttpMessage = "success", HttpStatusCode = HttpStatusCode.OK, PaymentStatus = "success", PaymentId = Guid.NewGuid().ToString() }); const string encryptedCardNumber = "encrypted-card-number"; const string decryptedCardNumber = "5555-5555-5555-5555"; _aesHelper.Encrypt(decryptedCardNumber).Returns(encryptedCardNumber); var maskedCardNumber = "xxxx-xxxx-xxxx-5555"; _creditCardMasker.MaskCreditCardNumber(Arg.Any <string>()).Returns(maskedCardNumber); var payment = new Payment { Id = Guid.NewGuid(), Amount = request.Amount, Currency = request.Currency, FullName = request.FullName, CardNumber = encryptedCardNumber, Expiry = request.Expiry }; _paymentRepository.AddAsync(Arg.Any <Payment>()).Returns(payment); var cmd = new ProcessPaymentCommand(request); //Act var response = await _subject.Handle(cmd); //Assert Assert.NotNull(response); Assert.NotEqual(Guid.Empty, response.Id); Assert.Equal(request.FullName, response.FullName); Assert.Equal(request.Amount, response.Amount); Assert.Equal(request.Currency, response.Currency); Assert.Equal(maskedCardNumber, response.CardNumber); Assert.Equal(request.Expiry, response.Expiry); await _bankService.Received().ProcessPaymentAsync(request); await _paymentRepository.Received().AddAsync(Arg.Any <Payment>()); }
public async void Handle_ShouldProcessPayment() { var accountsRepo = new Mock <IAccountRepository>(); var account = new Account(Guid.NewGuid(), 100); account.AddPaymentRequest(new DateTime(2020, 3, 1), 40); accountsRepo.Setup(a => a.GetAsync(account.Id)).ReturnsAsync(account); var paymentRepo = new Mock <IPaymentRepository>(); var payment = account.PaymentRequests.First(); paymentRepo.Setup(p => p.GetAsync(payment.Id)).ReturnsAsync(payment); paymentRepo.Setup(p => p.UnitOfWork.SaveEntitiesAsync(It.IsAny <CancellationToken>())).ReturnsAsync(true); var reason = "Processed"; var command = new ProcessPaymentCommand(account.Id, payment.Id); var handler = new ProcessPaymentHandler(accountsRepo.Object, paymentRepo.Object); await handler.Handle(command, new CancellationToken()); Assert.Equal(PaymentStatus.Processed, payment.Status); Assert.Equal(reason, payment.Reason); }
public void ProcessPayment_Should_ThrowException_When_InvoiceInvalidState() { var guid = Guid.NewGuid(); DbContext.Invoices.Add(new Invoice() { Id = guid, Amount = Decimal.Zero, Payments = new List <Payment>() { new Payment() { Amount = 100 } } }); var command = new ProcessPaymentCommand { InvoiceId = guid, Amount = 10, }; var handler = new ProcessPaymentCommandHandler(InvoiceRepository); Assert.ThrowsAsync <Exceptions.InvalidOperationException>(async() => await handler.Handle(command, CancellationToken.None)); }
public void ProcessPayment_Should_ThrowException_When_PartialAmountPaid_And_NewAmountTooMuch() { var command = new ProcessPaymentCommand { InvoiceId = TestData.Invoice3Id, Amount = 100, }; var handler = new ProcessPaymentCommandHandler(InvoiceRepository); Assert.ThrowsAsync <Exceptions.InvalidOperationException>(async() => await handler.Handle(command, CancellationToken.None)); }
public void ProcessPayment_Should_ThrowException_When_NoPaymentNeeded() { var command = new ProcessPaymentCommand { InvoiceId = TestData.Invoice4Id, Amount = 10, }; var handler = new ProcessPaymentCommandHandler(InvoiceRepository); Assert.ThrowsAsync <Exceptions.InvalidOperationException>(async() => await handler.Handle(command, CancellationToken.None)); }
public void ProcessPayment_Should_ThrowException_When_NoInvoiceFoundForInvoiceId() { var command = new ProcessPaymentCommand { InvoiceId = Guid.NewGuid(), Amount = 10, }; var handler = new ProcessPaymentCommandHandler(InvoiceRepository); Assert.ThrowsAsync <NotFoundException>(async() => await handler.Handle(command, CancellationToken.None)); }
public void Handle_WhenClosed_ShouldThrowException() { _mediator.Setup(m => m.Send(It.IsAny <ReduceBalanceCommand>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(true)); var sut = new ProcessPaymentCommandHandler(_context, _mediator.Object, CurrentUser); var request = new ProcessPaymentCommand { Id = Guid.Parse("debf1d88-47ac-4fe4-a0b0-ce42f72ea66e") }; Assert.ThrowsAsync <ValidationException>(() => sut.Handle(request, CancellationToken.None)); }
public PaymentViewModel() { _urlPathSegment = "Payment demo"; var paymentService = Locator.Current.GetService <IPaymentProcessor>(); var canPay = this.WhenAnyValue(_ => _.Amount, _ => !string.IsNullOrEmpty(_) && decimal.TryParse(_, NumberStyles.Currency, CultureInfo.InvariantCulture, out var amount) && amount > 0); ProcessPaymentCommand = ReactiveCommand .CreateFromObservable(() => Locator.Current.GetService <IPaymentProcessor>().BeginPay(decimal.Parse(Amount, NumberStyles.Currency, CultureInfo.InvariantCulture)), canPay); ProcessPaymentCommand.Subscribe(_ => Application.Current.MainPage .DisplayAlert(_.Success ? "Hooray!" : "Oops!", _.Message, "OK")); }
public void Not_Allow_Non_Supported_Currencies() { var command = new ProcessPaymentCommand { Amount = 100, Currency = "AUS", CardExpiryYear = "2021", CardExpiryMonth = "04", }; var validator = new ProcessPaymentCommandValidator(); var result = validator.Validate(command); result.Errors.Select(x => x.ErrorMessage).Should().Contain("The currency is not support"); }
public void Not_Allow_Negative_Amount() { var command = new ProcessPaymentCommand { Amount = -1, Currency = "AUS", CardExpiryYear = "xxxx", CardExpiryMonth = "xxx", }; var validator = new ProcessPaymentCommandValidator(); var result = validator.Validate(command); result.Errors.Select(x => x.ErrorMessage).Should().Contain("amount must be greater than 0"); }
public async Task <IActionResult> ProcessPayment([FromBody] PaymentRequest request) { var command = new ProcessPaymentCommand { Amount = request.Amount, Currency = request.Currency, CardExpiryYear = request.CardExpiryYear, CardExpiryMonth = request.CardExpiryMonth, CardNumber = request.CardNumber, CVV = request.CVV, MerchantId = request.MerchantId }; return(Result.For(await _mediator.Send(command))); }
public async Task <ActionResult> ProcessPaymentAsync([FromHeader(Name = "ACCOUNT_KEY")] Guid accountId, Guid id) { var command = new ProcessPaymentCommand(accountId, id); try { var response = await _mediator.Send(command); return(Ok()); } catch (KeyNotFoundException) { return(NotFound()); } }
public void Not_Allow_Expired_CreditCard() { var command = new ProcessPaymentCommand { Amount = 100, Currency = "AUS", CardExpiryYear = "2020", CardExpiryMonth = "04", }; var validator = new ProcessPaymentCommandValidator(); var result = validator.Validate(command); result.Errors.Select(x => x.ErrorMessage).Should().Contain("The credit card is expired"); }
public async Task ProcessPayment_PayCorrectAmount_InvoicePaidOff() { var command = new ProcessPaymentCommand { InvoiceId = TestData.Invoice1Id, Amount = 10, }; var handler = new ProcessPaymentCommandHandler(InvoiceRepository); var result = await handler.Handle(command, CancellationToken.None); var invoice = DbContext.Invoices.First(x => x.Id == command.InvoiceId); Assert.AreEqual(10, invoice.AmountPaid); Assert.AreEqual(10, invoice.Payments.Sum(x => x.Amount)); }
public void Not_Allow_String_As_CardYear_And_CardMonth() { var command = new ProcessPaymentCommand { Amount = 100, Currency = "AUS", CardExpiryYear = "xxxx", CardExpiryMonth = "xxx", }; var validator = new ProcessPaymentCommandValidator(); var result = validator.Validate(command); result.Errors.Select(x => x.ErrorMessage).Should().Contain("expiry year is not valid"); result.Errors.Select(x => x.ErrorMessage).Should().Contain("expiry month is not valid"); }
public async Task Handle(CashInRemovedFromHistoryJobEvent evt, ICommandSender commandSender) { var assetToPayId = await _paymentResolver.Resolve(evt.AssetId); var processPaymentCommand = new ProcessPaymentCommand { Id = evt.Id, ClientId = evt.ClientId, AssetId = assetToPayId, Amount = evt.Amount, NewCashinId = Guid.NewGuid(), CashinId = evt.CashInId }; commandSender.SendCommand(processPaymentCommand, BoundedContext.ForwardWithdrawal); }
public async Task <CommandHandlingResult> Handle(ProcessPaymentCommand command, IEventPublisher eventPublisher) { try { var asset = await _assetsServiceWithCache.TryGetAssetAsync(command.AssetId); var result = await _exchangeOperationsService.ExchangeOperations.TransferAsync( new TransferRequestModel { DestClientId = command.ClientId, SourceClientId = _hotWalletId, Amount = command.Amount.TruncateDecimalPlaces(asset.Accuracy), AssetId = command.AssetId, TransferTypeCode = "Common", OperationId = command.NewCashinId.ToString(), }); if (result.IsOk()) { _log.Info($"Done processing: {command.ToJson()}"); eventPublisher.PublishEvent(new CashInProcesedEvent { ClientId = command.ClientId, OperationId = command.CashinId }); return(CommandHandlingResult.Ok()); } if (result.Code == (int)MeStatusCodes.Duplicate) { _log.Warning($"Duplicate transfer attempt: {command.ToJson()}"); return(CommandHandlingResult.Ok()); } throw new InvalidOperationException( $"During transfer of {command.Id}, ME responded with: {result.Code}"); } catch (Exception e) { _log.Error(e, context: command.ClientId); return(CommandHandlingResult.Fail(TimeSpan.FromMinutes(1))); } }
public void Handle_WhenPendingWithLowBalance_ShouldSetToClosed() { _mediator.Setup(m => m.Send(It.IsAny <ReduceBalanceCommand>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(false)); var sut = new ProcessPaymentCommandHandler(_context, _mediator.Object, CurrentUser); var request = new ProcessPaymentCommand { Id = Guid.Parse("b162e88d-a3a6-4341-87da-725658d743f3") }; var result = sut.Handle(request, CancellationToken.None).Result; Assert.AreEqual(Unit.Value, result); var record = _context.Payments.Single(i => i.Id == request.Id); Assert.AreEqual(PaymentStatus.Closed, record.Status); }
public async Task <ProcessPaymentResult> HandleAsync(ProcessPaymentCommand command) { var bankPayemntResult = await _acuquiryBank.ProcessPayment(new BankPaymentRequest { Amount = command.Amount, Currency = command.Currency, CardExpiryYear = command.CardExpiryYear, CardExpiryMonth = command.CardExpiryMonth, CardNumber = command.CardNumber, CVV = command.CVV, MerchantId = Guid.NewGuid().ToString() }); var encriptionKey = Guid.NewGuid().ToString("N"); var encriptedCardNumber = _cryptoService.Encrypt(command.CardNumber, encriptionKey); var encriptedCardMonth = _cryptoService.Encrypt(command.CardExpiryMonth, encriptionKey); var encriptedCardDay = _cryptoService.Encrypt(command.CardExpiryYear, encriptionKey); var encriptedCardCVV = _cryptoService.Encrypt(command.CVV, encriptionKey); var payment = new Payment { Id = Guid.NewGuid().ToString(), EncriptionKey = encriptionKey, CardNumber = encriptedCardNumber, CardExpiryMonth = encriptedCardMonth, CardExpiryYear = encriptedCardDay, CVV = encriptedCardCVV, Amount = command.Amount, Currency = command.Currency, MerchantId = command.MerchantId, }; payment.BankPaymentIdentifier = bankPayemntResult.PaymentIdentifier; payment.PaymentStatus = bankPayemntResult.PaymentStatus; await _paymentRepository.Save(payment); if (bankPayemntResult.PaymentStatus == PaymentStatus.Success) { return(new SuccessResult(payment.Id)); } else { return(new ErrorResult("The Bank was unable to process the payment")); } }
public async Task <IActionResult> Process(ProcessPaymentRequest request) { var command = new ProcessPaymentCommand( request.CardNumber, request.Expiry, request.Ccv, request.Amount, request.Currency); var result = await _mediator.Send(command); if (result.PaymentId is null) { return(BadRequest(result)); } return(Ok(result)); }
public async Task Proccess_And_Persist_Payment() { var mockPaymentRepository = new Mock <IPaymentRepository>(); var mockCyptoService = new Mock <ICryptoService>(); mockCyptoService.Setup(x => x.Encrypt(It.IsAny <string>(), It.IsAny <string>())) .Returns("__encripted__"); var sut = new ProcessPaymentCommandHandler(mockPaymentRepository.Object, mockCyptoService.Object); ProcessPaymentCommand command = new ProcessPaymentCommand { Amount = 100, Currency = "EUR", CardExpiryYear = "24", CardExpiryMonth = "4", CardNumber = "5564876598743467", CVV = "782", }; await sut.HandleAsync(command); mockCyptoService.Verify(x => x.Encrypt(command.CardNumber, It.IsAny <string>()), Times.Once); mockPaymentRepository.Verify(x => x.Save(It.Is <Payment>(y => y.CardNumber == "__encripted__")), Times.Once); }
public async Task <IActionResult> ProcessPaymentAsync([FromBody] ProcessPaymentCommand payment) { await _mediator.Send(payment); return(Ok()); }
public async Task <PaymentResponse> ProcessPaymentAsync([FromBody] ProcessPaymentRequest request) { var command = new ProcessPaymentCommand(request); return(await _mediator.Send(command)); }
public async Task <IActionResult> Process([FromBody] ProcessPaymentCommand command) => Ok(await Mediator.Send(command));
public async Task <ActionResult> ProcessPayment(ProcessPaymentCommand command) { await Mediator.Send(command); return(NoContent()); }
public static Task <bool> ProcessPayment(ProcessPaymentCommand message) { _success = !_success; return(Task.FromResult(_success)); }
public async Task <IActionResult> ProcessPayment([FromBody] ProcessPaymentCommand command) { var result = await _mediator.Send(command); return(CreatedAtAction("ProcessPayment", result)); }