public async Task <TransferFundsResponse> TransferFunds(TransferFundsRequest request)
 {
     try
     {
         return(await TransferFundsResponseInternal(request));
     }
     catch (Exception e)
     {
         return(TransferFundsResponse.ExceptionResponse(e));
     }
 }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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>()));
        }
Ejemplo n.º 5
0
        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"));
        }