public async Task <TransferFundsResponse> TransferFunds(TransferFundsRequest request) { try { return(await TransferFundsResponseInternal(request)); } catch (Exception e) { return(TransferFundsResponse.ExceptionResponse(e)); } }
public async Task Handle_BankResponseUnknownError_ReturnsBadGateway() { //arrange var transferFundsResponse = TransferFundsResponse.UnknownError(_fixture.Create <int>()); _mockBankApiClient .Setup(x => x.TransferFunds(It.IsAny <TransferFundsRequest>())) .ReturnsAsync(transferFundsResponse); //act var res = await _createPaymentHandler.Handle(_fixture.Create <CreatePaymentRequest>()); //assert res.StatusCode.Should().Be(StatusCodes.Status502BadGateway); }
public async Task Handle_BankResponseRejected_SendsProcessRejectedPaymentRequest() { //arrange var merchantId = _fixture.Create <string>(); _merchantContext.Setup(x => x.GetMerchantId()).Returns(merchantId); var transferFundsErrorResponse = _fixture.Create <TransferFundsErrorResponse>(); _mockBankApiClient .Setup(x => x.TransferFunds(It.IsAny <TransferFundsRequest>())) .ReturnsAsync(TransferFundsResponse.Error(StatusCodes.Status422UnprocessableEntity, transferFundsErrorResponse)); var request = _fixture.Create <CreatePaymentRequest>(); var expected = new ProcessRejectedPaymentRequest { Source = new ProcessRejectedPaymentRequest.PaymentSource { Cvv = request.Source.Cvv, CardExpiry = request.Source.CardExpiry, CardNumber = request.Source.CardNumber, }, Recipient = new ProcessRejectedPaymentRequest.PaymentRecipient { SortCode = request.Recipient.SortCode, AccountNumber = request.Recipient.AccountNumber }, Currency = request.Currency, Amount = request.Amount, Merchant = new ProcessRejectedPaymentRequest.MerchantDetails { Id = merchantId, }, BankResponse = new ProcessRejectedPaymentRequest.BankPaymentResponse { FailureReason = transferFundsErrorResponse.Code } }; //act await _createPaymentHandler.Handle(request); //assert _mediator.Verify(x => x.Send(It.Is <ProcessRejectedPaymentRequest>(req => req.Should().BeEquivalentToBool(expected)), It.IsAny <CancellationToken>()), Times.Once); }
private void SetupMockDefaults() { _mediator .Setup(x => x.Send(It.IsAny <ProcessSuccessfulPaymentRequest>(), It.IsAny <CancellationToken>())) .ReturnsAsync(_fixture.Create <ProcessSuccessfulPaymentResponse>()); _mediator .Setup(x => x.Send(It.IsAny <ProcessRejectedPaymentRequest>(), It.IsAny <CancellationToken>())) .ReturnsAsync(_fixture.Create <ProcessRejectedPaymentResponse>()); _merchantContext .Setup(x => x.GetMerchantId()) .Returns(_fixture.Create <string>()); _mockBankApiClient .Setup(x => x.TransferFunds(It.IsAny <TransferFundsRequest>())) .ReturnsAsync(TransferFundsResponse.Successful(_fixture.Create <TransferFundsSuccessfulResponse>())); }
public async Task Handle_BankResponseSuccessful_ReturnsExpectedSuccessResponse() { //arrange var processSuccessfulPaymentResponse = _fixture.Create <ProcessSuccessfulPaymentResponse>(); _mediator .Setup(x => x.Send(It.IsAny <ProcessSuccessfulPaymentRequest>(), It.IsAny <CancellationToken>())) .ReturnsAsync(processSuccessfulPaymentResponse); _mockBankApiClient .Setup(x => x.TransferFunds(It.IsAny <TransferFundsRequest>())) .ReturnsAsync(TransferFundsResponse.Successful(_fixture.Create <TransferFundsSuccessfulResponse>())); //act var res = await _createPaymentHandler.Handle(_fixture.Create <CreatePaymentRequest>()); //assert res.StatusCode.Should().Be(StatusCodes.Status201Created); res.SuccessResponse.Status.Should().Be(PaymentStatus.Succeeded); res.SuccessResponse.PaymentId.Should().Be(processSuccessfulPaymentResponse.Id); }
private async Task <TransferFundsResponse> TransferFundsResponseInternal(TransferFundsRequest request) { var response = await _httpClient.PostAsync( "api/payment", new StringContent(JsonConvert.SerializeObject(request), Encoding.UTF8, "application/json")); var responseBody = await response.Content.ReadAsStringAsync(); if (!response.IsSuccessStatusCode) { if (response.StatusCode == (HttpStatusCode)HttpStatusCodeUnprocessableEntity) { return(TransferFundsResponse.Error((int)response.StatusCode, JsonConvert.DeserializeObject <TransferFundsErrorResponse>(responseBody))); } else { return(TransferFundsResponse.UnknownError((int)response.StatusCode)); } } var deserialized = JsonConvert.DeserializeObject <TransferFundsSuccessfulResponse>(responseBody); return(TransferFundsResponse.Successful(deserialized)); }
//MCO: Here we are assuming that the bank has it's own idempotency methods that will allow us to safely retry in the case of a timeout, internal server error etc. private ApiResponse <CreatePaymentResponse> HandleUnknownBankResponse(TransferFundsResponse mockBankResponse) { _logger.LogCritical("Unknown response received from payment Response: {@mockBankResponse}", mockBankResponse); return(ApiResponse <CreatePaymentResponse> .Fail(StatusCodes.Status502BadGateway, "ERR_DEP_FAIL", "A dependency has failed, your payment has not been processed. Please try again")); }