Example #1
0
        public async Task <IActionResult> Post([FromBody] CreateChargeRequest request)
        {
            // Note that explicitly checking ModelState is not required for controllers with the [ApiController]
            // attribute, so there is no code here for that here.

            var entity = new Charge
            {
                IdempotentKey = request.IdempotentKey,
                CreatedOn     = DateTimeOffset.UtcNow,
                Status        = ChargeStatus.Pending,
                Amount        = request.Amount,
                Currency      = request.Currency,
                Description   = request.Description,
                CardNumber    = request.CardNumber,
                Cvv           = request.Cvv,
                ExpiryMonth   = request.ExpiryMonth,
                ExpiryYear    = request.ExpiryYear
            };

            _db.Charges.Add(entity);

            try
            {
                await _db.SaveChangesAsync();
            }
            catch (DbUpdateException exception) when(exception.IsViolationOfUniqueIndex())
            {
                // This handles the case where someone is double-posting a charge with the same IdempotentKey.

                _logger.LogWarning("A charge with idempotency key {IdempotentKey} attempted to double post.", request.IdempotentKey);
                return(Conflict());
            }

            var acquiringBankRequest = new AcquiringBankRequest
            {
                Amount      = entity.Amount,
                Currency    = entity.Currency,
                CardNumber  = entity.CardNumber,
                Cvv         = entity.Cvv,
                ExpiryMonth = entity.ExpiryMonth,
                ExpiryYear  = entity.ExpiryYear
            };

            var success = await _bank.TrySendAsync(acquiringBankRequest, out var bankChargeId);

            if (!success)
            {
                _logger.LogError("The acquiring bank for charge id {Id} rejected the payment.", entity.Id);
            }

            entity.Status       = success ? ChargeStatus.Success : ChargeStatus.Failed;
            entity.BankChargeId = bankChargeId;

            await _db.SaveChangesAsync();

            var result = new GetChargeResponse(entity);

            return(CreatedAtAction("Get", new { id = entity.Id }, result));
        }
        public async Task <T> AddAsync(T entity)
        {
            await _dbContext.Set <T>().AddAsync(entity);

            await _dbContext.SaveChangesAsync();

            return(entity);
        }
Example #3
0
        public async Task <Payment> Add(Payment payment)
        {
            if (payment == null)
            {
                throw new ArgumentNullException("payment");
            }

            _context.Add(payment);
            await _context.SaveChangesAsync();

            return(payment);
        }
Example #4
0
        public async Task <BankResponse> MakePaymentInTheBank(Payment payment)
        {
            BankResponse bankResponse = null;

            // Try to make payment in the bank
            using (var client = new HttpClient())
            {
                // Bank API address
                client.BaseAddress = new Uri("https://localhost:44317/ProccessPayment");

                // Process payment in POST call to Bank and get payment result
                var postTask = await client.PostAsJsonAsync <Payment>("ProccessPayment", payment);

                bankResponse = postTask.Content.ReadFromJsonAsync <BankResponse>().Result;
            }

            if (bankResponse == null)
            {
                return(null);
            }

            payment.BankConfirmationID  = bankResponse.BankConfirmationID;
            payment.IsPaymentSuccessful = bankResponse.IsPaymentSuccessful;

            _context.PaymentItems.Add(payment);
            await _context.SaveChangesAsync();

            return(bankResponse);
        }
        public async Task <SavePaymentResult> SavePaymentAsync(Payment payment)
        {
            await _dbContext.Payments.AddAsync(payment);

            try
            {
                await _dbContext.SaveChangesAsync();
            }
            catch (DbUpdateException exception)
            {
                _logger.LogError("Failed to save payment {PaymentId} to the database. {Exception}", payment.Id,
                                 exception);

                return(new SavePaymentResult
                {
                    Success = false,
                    Payment = payment
                });
            }

            _logger.LogInformation("Payment {PaymentId} successfully saved to the database.", payment.Id);

            return(new SavePaymentResult
            {
                Success = true,
                Payment = payment
            });
        }
Example #6
0
            public async Task Charge_Returned_When_Found()
            {
                // Arrange

                var charge = new Charge
                {
                    IdempotentKey = "IdempotentKey",
                    BankChargeId  = "BankChargeId",
                    CreatedOn     = DateTimeOffset.UtcNow,
                    Status        = ChargeStatus.Success,
                    Amount        = 123.456m,
                    Currency      = "USD",
                    Description   = "Description",
                    CardNumber    = "CardNumber",
                    Cvv           = "Cvv",
                    ExpiryMonth   = 1,
                    ExpiryYear    = 2020
                };

                _db.Charges.Add(charge);
                await _db.SaveChangesAsync();

                // Act

                using var response = await _client.GetAsync($"api/charges/?id={charge.Id}");

                // Assert

                Assert.IsNotNull(response);
                Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);

                using var responseStream = await response.Content.ReadAsStreamAsync();

                var responseCharge = await JsonSerializer.DeserializeAsync <GetChargeResponse>(responseStream);

                Assert.AreEqual(charge.Id, responseCharge.Id);
                Assert.AreEqual(charge.IdempotentKey, responseCharge.IdempotentKey);
                Assert.AreEqual(charge.CreatedOn, responseCharge.CreatedOn);
                Assert.AreEqual(charge.Status, responseCharge.Status);
                Assert.AreEqual(charge.Amount, responseCharge.Amount);
                Assert.AreEqual(charge.Currency, responseCharge.Currency);
                Assert.AreEqual(charge.Description, responseCharge.Description);
                Assert.AreEqual("******mber", responseCharge.CardNumber);
            }