public async Task <IActionResult> PaymentAvailable([FromQuery] GeorgianCardRequest request)
        {
            if (string.IsNullOrWhiteSpace(request.MerchantId) || request.MerchantId != _config.MerchantId)
            {
                return(Content(GeorgianCardHelper.BuildPaymentAvailableResponse(ResultCode.Fail, "Invalid merch_id.")));
            }

            if (!int.TryParse(request.PaymentId, out int paymentId))
            {
                return(Content(GeorgianCardHelper.BuildPaymentAvailableResponse(ResultCode.Fail, "Invalid o.id.")));
            }

            var payment = await _context.Payments.FindAsync(paymentId);

            if (payment == null)
            {
                return(Content(GeorgianCardHelper.BuildPaymentAvailableResponse(ResultCode.Fail, "Payment not found.")));
            }

            if (string.IsNullOrWhiteSpace(request.TransactionId))
            {
                return(Content(GeorgianCardHelper.BuildPaymentAvailableResponse(ResultCode.Fail, "Invalid trx_id.")));
            }

            payment.ExternalId = request.TransactionId;

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

            var paymentAmount = GeorgianCardHelper.ConvertGELToGeorgianCardAmount(payment.Amount);

            return(Content(GeorgianCardHelper.BuildPaymentAvailableResponse(ResultCode.Success, ResultCode.Success.ToString(), paymentAmount, _config)));
        }
        public async Task <IActionResult> PlaceOrder(int?id)
        {
            if (id == null)
            {
                return(BadRequest());
            }

            var order = await _context.Orders.FindAsync(id);

            if (order == null)
            {
                return(NotFound());
            }

            var payment = new Payment
            {
                OrderId = order.Id,
                Amount  = order.TotalPrice,
                Status  = PaymentStatus.Pending
            };
            await _context.AddAsync(payment);

            order.Status = OrderStatus.PendingPayment;

            await _context.SaveChangesAsync();

            var paymentUri = GeorgianCardHelper.BuildPaymentUri(payment.Id.ToString(), _config);

            return(Ok(new { RedirectUrl = paymentUri.AbsoluteUri }));
        }
        public async Task <IActionResult> RegisterPayment([FromQuery] GeorgianCardRequest request)
        {
            if (string.IsNullOrWhiteSpace(request.MerchantId) || request.MerchantId != _config.MerchantId)
            {
                return(Content(GeorgianCardHelper.BuildRegisterPaymentResponse(ResultCode.Fail, "Invalid merch_id.")));
            }

            if (!int.TryParse(request.PaymentId, out int paymentId))
            {
                return(Content(GeorgianCardHelper.BuildRegisterPaymentResponse(ResultCode.Fail, "Invalid o.id.")));
            }

            var payment = await _context.Payments.FindAsync(paymentId);

            if (payment == null)
            {
                return(Content(GeorgianCardHelper.BuildRegisterPaymentResponse(ResultCode.Fail, "Payment not found.")));
            }

            if (string.IsNullOrWhiteSpace(request.TransactionId) || request.TransactionId != payment.ExternalId)
            {
                return(Content(GeorgianCardHelper.BuildRegisterPaymentResponse(ResultCode.Fail, "Invalid trx_id.")));
            }

            if (!DateTime.TryParseExact(request.Date, _config.DateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime processDate))
            {
                return(Content(GeorgianCardHelper.BuildRegisterPaymentResponse(ResultCode.Fail, "Invalid ts.")));
            }

            payment.ProcessDate = processDate;

            var order = await _context.Orders.FindAsync(payment.OrderId);

            if (request.ResultCode == ResultCode.Success)
            {
                payment.Status = PaymentStatus.Succeeded;

                payment.PaymentDetails = new PaymentDetails
                {
                    AuthorizationCode = request.AuthCode,
                    Cardholder        = request.Cardholder,
                    ExpirationDate    = request.ExpiryDate,
                    MaskedPAN         = request.MaskedPan,
                    RRN = request.RRN
                };

                // order.Status = OrderStatus.Processing;
                // NOTE: All product orders require processing, except those that only contain products which are both Virtual and Downloadable.

                order.Status = OrderStatus.Completed;
            }
            else
            {
                payment.Status = PaymentStatus.Failed;

                order.Status = OrderStatus.Failed;
            }

            if (Enum.TryParse(request.ExtendedResultCode, true, out ExtendedResultCode extendedResultCode))
            {
                payment.ExternalExtendedResultDescription = extendedResultCode.ToString();
            }

            await _context.SaveChangesAsync();

            return(Content(GeorgianCardHelper.BuildRegisterPaymentResponse(ResultCode.Success, ResultCode.Success.ToString())));
        }