public async Task <ActionResult <BankResponse> > Post([FromBody] PaymentRequest paymentRequest, CancellationToken cancellationToken)
        {
            const string apiRoute = Constants.ApiRoutes.Payments;
            const string httpVerb = Constants.HttpVerbs.Post;

            using (RequestProcessingDurationSummary.WithLabels(apiRoute, httpVerb).NewTimer())
            {
                _logger.LogInformation("Received a request on route {ApiRoute} with http verb {HttpVerb}.", apiRoute, httpVerb);
                RequestsReceivedCounter.WithLabels(apiRoute, httpVerb).Inc();

                if (paymentRequest == null)
                {
                    throw new ArgumentNullException(nameof(paymentRequest));
                }

                paymentRequest.CreditCardNumber = NormalizeCreditCardNumber(paymentRequest.CreditCardNumber);
                var bankResponse = await _bankService.ProcessTransactionAsync(paymentRequest, cancellationToken);

                // This is NOT production-ready. From the minimal research I've done on the topic, we're not supposed to store credit card info
                // anywhere, not even encrypted. Due to time constraints and since the database used in this assignment is in-memory only, I've
                // decided to implement it this way to be able to fulfill the assignment's requirements. I've never had to handle credit cards
                // in my professional career so far and if a project requires it in the future, I would do extensive research on the best way
                // to handle them and hopefully ask someone more experienced in the subject for pointers.
                var payment = new Payment
                {
                    Amount                = paymentRequest.Amount,
                    CreditCardNumber      = paymentRequest.CreditCardNumber,
                    CreditCardCvv         = paymentRequest.CreditCardCvv,
                    CreditCardExpiryMonth = paymentRequest.CreditCardExpiryMonth,
                    CreditCardExpiryYear  = paymentRequest.CreditCardExpiryYear,
                    Currency              = paymentRequest.Currency,
                    TransactionId         = bankResponse.TransactionId,
                    TransactionStatusCode = bankResponse.TransactionStatusCode
                };
                await _paymentsService.CreatePaymentAsync(payment, cancellationToken);

                _logger.LogInformation("Successfully processed a request on route {ApiRoute} with http verb {HttpVerb}.", apiRoute, httpVerb);
                RequestsProcessedCounter.WithLabels(apiRoute, httpVerb).Inc();

                return(bankResponse);
            }
        }
        public async Task <ActionResult <Payment> > Get(Guid transactionId, CancellationToken cancellationToken)
        {
            const string apiRoute = Constants.ApiRoutes.Payments;
            const string httpVerb = Constants.HttpVerbs.Get;

            using (RequestProcessingDurationSummary.WithLabels(apiRoute, httpVerb).NewTimer())
            {
                _logger.LogInformation("Received a request on route {ApiRoute} with http verb {HttpVerb}.", apiRoute, httpVerb);
                RequestsReceivedCounter.WithLabels(apiRoute, httpVerb).Inc();

                if (transactionId == Guid.Empty)
                {
                    throw new ArgumentException("Missing transaction ID.");
                }

                var payment = await _paymentsService.GetPaymentAsync(transactionId, cancellationToken);

                if (payment == null)
                {
                    throw new ResourceNotFoundException("Could not find the specified payment.");
                }

                var maskedCreditCardNumber = _paymentsService.MaskCreditCardNumber(payment.CreditCardNumber);
                var response = new Payment
                {
                    Id                    = payment.Id,
                    Amount                = payment.Amount,
                    CreditCardCvv         = payment.CreditCardCvv,
                    CreditCardExpiryMonth = payment.CreditCardExpiryMonth,
                    CreditCardExpiryYear  = payment.CreditCardExpiryYear,
                    CreditCardNumber      = maskedCreditCardNumber,
                    Currency              = payment.Currency,
                    TransactionStatusCode = payment.TransactionStatusCode,
                    TransactionId         = payment.TransactionId
                };

                _logger.LogInformation("Successfully processed a request on route {ApiRoute} with http verb {HttpVerb}.", apiRoute, httpVerb);
                RequestsProcessedCounter.WithLabels(apiRoute, httpVerb).Inc();

                return(response);
            }
        }