public async Task ThatCanProcessFailedPayment() { var request = TestDataProvider.GetValidPaymentRequest(); var expectedResponse = new BankPaymentResponse { Identifier = Guid.NewGuid().ToString(), Error = "Payment failed", }; this.bankMock.Setup(x => x.ProcessPaymentAsync(It.IsAny <BankPaymentRequest>())).ReturnsAsync(expectedResponse); this.paymentStorageMock.Setup(x => x.SavePaymentDetailsAsync(It.IsAny <PaymentRequest>(), It.IsAny <PaymentResponse>())).ReturnsAsync(true); var actualResponse = await this.paymentGateway.ProcessPaymentRequestAsync(request); actualResponse.Identifier.ShouldBe(expectedResponse.Identifier); actualResponse.Success.ShouldBe(expectedResponse.Success); actualResponse.Error.ShouldBe(expectedResponse.Error); }
public async Task CompletePaymentAsync_WithStatus_UpdatesRecord() { var command = CreateValidAddPaymentCommand(); var repository = new InMemoryPaymentsRepository(NullLogger <InMemoryPaymentsRepository> .Instance); var bankPaymentResponse = new BankPaymentResponse() { BankPaymentId = "TEST", Result = PaymentStatus.Paid }; var paymentId = await repository.StartPaymentAsync(1, command); await repository.CompletePaymentAsync(paymentId, bankPaymentResponse); var result = await repository.GetPaymentDetailsByPaymentIdAsync(paymentId); Assert.NotNull(result.BankPaymentId); Assert.Equal(bankPaymentResponse.Result, result.Status); Assert.True(result.ResponseReceivedDate > DateTime.MinValue); }
public static Transaction MapResponse(string rawResponse) { Transaction transaction = new Transaction(); if (!string.IsNullOrEmpty(rawResponse)) { JsonDoc json = JsonDoc.Parse(rawResponse); transaction.TransactionId = json.GetValue <string>("ob_trans_id"); transaction.PaymentMethodType = PaymentMethodType.BankPayment; transaction.OrderId = json.Get("order")?.GetValue <string>("id"); transaction.ResponseMessage = json.GetValue <string>("status"); BankPaymentResponse obResponse = new BankPaymentResponse(); obResponse.RedirectUrl = json.GetValue <string>("redirect_url"); obResponse.PaymentStatus = json.GetValue <string>("status"); obResponse.Id = json.GetValue <string>("ob_trans_id"); transaction.BankPaymentResponse = obResponse; } return(transaction); }
public void Initialize() { _paymentRepositoryMock = new Mock <IPaymentRepository>(); _merchantServiceMock = new Mock <IMerchantService>(); _bankServiceMock = new Mock <IBankService>(); _cardValidatorProvider = new CardValidatorProvider(); _merchantServiceMock.Setup(m => m.GetMerchantById(It.IsAny <Guid>())) .Returns(Task.FromResult( new MerchantResponse { MerchantId = Guid.NewGuid() })); bankPaymentResponse = new BankPaymentResponse { BankPaymentRef = Guid.NewGuid(), PaymentStatus = AppCodes.PaymentStatus.Successful }; _bankServiceMock.Setup(b => b.MakeBankPayment(It.IsAny <BankPaymentRequest>())) .Returns(Task.FromResult(bankPaymentResponse)); payment = new Payment { BankPaymentRef = bankPaymentResponse.BankPaymentRef, PaymentStaus = (short)bankPaymentResponse.PaymentStatus }; _paymentRepositoryMock.Setup(p => p.AddAsync(It.IsAny <Payment>())) .Returns(Task.FromResult(payment)); paymentService = new PaymentService( _paymentRepositoryMock.Object, _merchantServiceMock.Object, _bankServiceMock.Object, _cardValidatorProvider); }
public async Task ProcessPaymentAsync_HappyPath_ReportsToTelemetry() { // arrange var command = Fixture.Create <SubmitPaymentCommand>(); var payment = Fixture.Create <Payment>(); var bankPaymentResponse = new BankPaymentResponse { IsSuccessful = true, Id = Guid.NewGuid() }; PaymentRepositoryMock .Setup(m => m.GetByIdAsync(command.PaymentId)) .ReturnsAsync(payment); BankServiceClientMock .Setup(m => m.CreateOrderAsync(command)) .ReturnsAsync(bankPaymentResponse); // act await SUT.ProcessPaymentAsync(command); // assert TelemetrySubmitterMock .Verify(m => m.SubmitAsync(It.IsAny <ServiceOperation>())); }
public async Task ProcessPaymentAsync_HappyPath_SetsTransactionId() { // arrange var command = Fixture.Create <SubmitPaymentCommand>(); var payment = Fixture.Create <Payment>(); var bankPaymentResponse = new BankPaymentResponse { IsSuccessful = true, Id = Guid.NewGuid() }; PaymentRepositoryMock .Setup(m => m.GetByIdAsync(command.PaymentId)) .ReturnsAsync(payment); BankServiceClientMock .Setup(m => m.CreateOrderAsync(command)) .ReturnsAsync(bankPaymentResponse); // act await SUT.ProcessPaymentAsync(command); // assert PaymentRepositoryMock .Verify(m => m.UpdateAsync(It.Is <Payment>(p => p.Id == payment.Id && p.BankTransactionId == bankPaymentResponse.Id))); }
public async Task ProcessPaymentAsync_OnBankError_ReportsToTelemetry() { // arrange var command = Fixture.Create <SubmitPaymentCommand>(); var payment = Fixture.Create <Payment>(); var bankPaymentResponse = new BankPaymentResponse { IsSuccessful = true, Id = Guid.NewGuid() }; PaymentRepositoryMock .Setup(m => m.GetByIdAsync(command.PaymentId)) .ReturnsAsync(payment); BankServiceClientMock .Setup(m => m.CreateOrderAsync(command)) .ThrowsAsync(new InvalidOperationException()); // act await SUT.ProcessPaymentAsync(command); // assert TelemetrySubmitterMock .Verify(m => m.SubmitAsync(It.Is <ServiceOperation>(o => o.IsFaulted == 1))); }
public BankPaymentResponse InvoicePayment(Invoice invoice, BankPayment bankPayment) { var response = new BankPaymentResponse(); List <string> errors = new List <string>(); if (bankPayment == null) { response.Errors.Add("Payment details invalid"); return(response); } if (bankPayment.Bank == "XYZ") { response.Errors.Add("Payment through bank XYZ is not allowed"); return(response); } invoice.ClosedOn = DateTime.Now; invoice.Status = InvoiceStatus.Closed; response.PaymentConfirmatitonNumber = $"{bankPayment.Bank}{DateTime.Now:ssyymmhh}"; return(response); }
public PaymentGatewayServiceShould() { paymentReference = Guid.NewGuid(); paymentRequest = CreatePaymentRequest(); bankPaymentRequest = new BankPaymentRequest("4485063526474709", "01/20", 20.00m, "GBP", 123); bankApiMock = new Mock <IBankApiClient>(); var bankPaymentDetail = new BankPaymentDetail(paymentReference, "Accepted", "4485063526474709", "01/20", 20.00m, "GBP", 123); var bankPaymentResponse = new BankPaymentResponse(paymentReference, "Accepted"); var paymentResponse = new PaymentResponse(paymentReference, "Accepted"); var paymentDetail = new PaymentDetail(paymentReference, "Accepted", "4***********4709", "01/20", 20.00m, "GBP", 123); bankApiMock.Setup(service => service.Process(It.IsAny <BankPaymentRequest>())) .Returns(Task.FromResult(bankPaymentResponse)); bankApiMock.Setup(service => service.GetPaymentDetail(paymentReference)).Returns(Task.FromResult(bankPaymentDetail)); bankPaymentMapperMock = new Mock <IBankPaymentMapper>(); bankPaymentMapperMock.Setup(mapper => mapper.MapRequest(It.IsAny <PaymentRequest>())).Returns(bankPaymentRequest); bankPaymentMapperMock.Setup(mapper => mapper.MapResponse(It.IsAny <BankPaymentResponse>())) .Returns(paymentResponse); bankPaymentMapperMock.Setup(mapper => mapper.MapDetail(It.IsAny <BankPaymentDetail>())) .Returns(paymentDetail); applicationLoggerMock = new Mock <IApplicationLogger>(); paymentGatewayService = new PaymentGatewayService(bankApiMock.Object, bankPaymentMapperMock.Object, applicationLoggerMock.Object); }
private static PaymentResponse CreatePaymentResponse(BankPaymentResponse bankPaymentResponse) { return(new PaymentResponse(bankPaymentResponse.PaymentReference, bankPaymentResponse.Status)); }
public PaymentResponse ProcessPayment(ProcessPaymentRequest request, string merchantApiKey) { //Get merchant var merchant = _merchantDao.GetMerchantBasedOnApiKey(merchantApiKey); if (merchant == null) { Logger.Info("Request from an unknown merchant received"); throw new RequestValidationException("Unknown Merchant"); } if (string.IsNullOrWhiteSpace(request.CardNumber)) { Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Missing Card Number"); throw new RequestValidationException("Missing Card Number"); } if (!(request.CardNumber.Length == 19 || request.CardNumber.Length == 16)) { Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Invalid Card Number"); throw new RequestValidationException("Invalid Card Number"); } if (string.IsNullOrWhiteSpace(request.CardCvv)) { Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Missing Card CVV Number"); throw new RequestValidationException("Missing Card CVV Number"); } if (request.CardCvv.Length != 4) { Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Invalid Card Card CVV Number"); throw new RequestValidationException("Invalid Card Card CVV Number"); } if (request.PaymentAmount == 0) { Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Invalid Payment Amount"); throw new RequestValidationException("Payment Amount should be greater than zero"); } if (string.IsNullOrWhiteSpace(request.ExpiryDate)) { Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Missing Card Expiry Date"); throw new RequestValidationException("Missing Card Card Expiry Date"); } DateTime expiryDate; try { expiryDate = DateTime.ParseExact(request.ExpiryDate, _expiryDateFormat, CultureInfo.InvariantCulture); } catch (Exception e) { Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Invalid ExpiryDate provided"); throw new RequestValidationException("Invalid ExpiryDate provided"); } if (string.IsNullOrWhiteSpace(request.Currency)) { Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Missing Currency"); throw new RequestValidationException("Missing Currency"); } var currency = GetCurrency(request); if (currency == null) { Logger.Info($"Bad Request from MerchantId :{merchant.ID}, Unknown currency"); throw new RequestValidationException("Unknown Currency"); } var card = GetOrCreateCard(request, expiryDate); var paymentRequest = new PaymentRequest { MerchantId = merchant.ID, CardId = card.ID, CurrencyId = currency.ID, Amount = request.PaymentAmount, DateTimeAdded = DateTime.UtcNow }; _paymentRequestDao.InsertPaymentRequest(paymentRequest); paymentRequest = _paymentRequestDao.GetPaymentRequestBasedOnMerchantIdCardIdCurrencyIdAndAmount(paymentRequest); Logger.Info($"Payment request from Merchant: {merchant.ID} logged. PaymentRequestId : {paymentRequest.Id}"); var acquiringBankRequest = new AcquiringBankRequest { CardNumber = request.CardNumber, CardCvv = request.CardCvv, PaymentAmount = request.PaymentAmount, ExpiryDate = request.ExpiryDate, Currency = request.Currency, MerchantId = merchant.ID }; var response = _acquiringBankService.ProcessPayment(acquiringBankRequest); var bankPaymentResponse = new BankPaymentResponse { PaymentRequestId = paymentRequest.Id, Status = response.PaymentStatus, BankPaymentIdentifier = response.PaymentIdentifier, DateTimeAdded = DateTime.UtcNow }; _bankPaymentResponseDao.InsertBankPaymentResponse(bankPaymentResponse); return(new PaymentResponse { Status = response.PaymentStatus, PaymentUniqueId = response.PaymentIdentifier }); }
public PaymentResponse MapResponse(BankPaymentResponse bankPaymentResponse) { return(new PaymentResponse(bankPaymentResponse.PaymentReference, bankPaymentResponse.Status)); }
private PaymentInformation GenerateRepositoryPayment(BankPaymentRequest bankPaymentRequest, BankPaymentResponse bankPaymentResponse) { var payment = new PaymentInformation { Amount = bankPaymentRequest.Amount, Id = bankPaymentResponse.PaymentId, CardDetails = new CardDetails(bankPaymentRequest.CardDetails.CardNumber.ToString(), bankPaymentRequest.CardDetails.ExpiryDate, bankPaymentRequest.CardDetails.Currency, bankPaymentRequest.CardDetails.CVV.ToString()), MerchantDetails = new MerchantDetails(bankPaymentRequest.MerchantDetails.MerchantId), PaymentStatus = bankPaymentResponse.BankPaymentResponseStatus == BankPaymentResponseStatus.Unsuccessful ? "Unsuccessful" : "Successful" }; payment.CardDetails.Obfuscate(_dataObfuscator); return(payment); }