Ejemplo n.º 1
0
        private async Task <PaymentStatus> ValidateTransaction(CompletePurchaseDto payment)
        {
            var purchase = _context.Purchases.FirstOrDefault(x => x.OrderId == payment.OrderId);

            if (purchase == null)
            {
                throw new ApiException($"The purchase with orderId {payment.OrderId} does not exist", 400);
            }

            if (purchase.Completed)
            {
                throw new ApiException("The given purchase has already been completed", 400);
            }

            var mobilePayPaymentStatus = await _mobilePayService.GetPaymentStatus(payment.OrderId);

            if (!Equals(Convert.ToDouble(purchase.Price), mobilePayPaymentStatus.OriginalAmount))
            {
                Log.Warning(
                    "Purchase price did not match the withdrawn amount from MobilePay. Possible tampering. Cancel transaction.");

                await _mobilePayService.CancelPaymentReservation(payment.OrderId);

                throw new ApiException("The purchase could not be completed. The purchase has been cancelled.");
            }

            return(mobilePayPaymentStatus.LatestPaymentStatus);
        }
Ejemplo n.º 2
0
        public Purchase DeliverProduct(CompletePurchaseDto completeDto, IEnumerable <Claim> claims)
        {
            var userId = claims.FirstOrDefault(x => x.Type == Constants.UserId);

            if (userId == null)
            {
                throw new ApiException("The token is invalid!", 401);
            }
            var id = int.Parse(userId.Value);

            var user = _context.Users.Include(x => x.Purchases).FirstOrDefault(x => x.Id == id);

            if (user == null)
            {
                throw new ApiException("The user could not be found");
            }

            var purchase = user.Purchases.FirstOrDefault(x => x.OrderId == completeDto.OrderId);

            if (purchase == null)
            {
                throw new ApiException("Purchase could not be found");
            }

            if (purchase.PurchasedBy.Id != user.Id)
            {
                throw new ApiException("You cannot complete a purchase that you did not initiate!", 401);
            }

            return(DeliverProductToUser(purchase, user, completeDto.TransactionId));
        }
Ejemplo n.º 3
0
        public async Task <ActionResult <MessageResponseDto> > CompletePurchase([FromBody] CompletePurchaseDto dto)
        {
            await _purchaseService.CompletePurchase(dto, User.Claims);

            return(Ok(new MessageResponseDto()
            {
                Message = "The purchase was completed with success!"
            }));
        }
Ejemplo n.º 4
0
        public async Task <Purchase> CompletePurchase(CompletePurchaseDto dto, IEnumerable <Claim> claims)
        {
            Log.Information(
                $"Trying to complete purchase with orderid: {dto.OrderId} and transactionId: {dto.TransactionId}");
            try
            {
                //TODO Figure out the purpose of this check, and probably fix it in regard to test environment
                if (!_mobilePaySettings.MerchantId.Equals("APPDK0000000000"))
                {
                    var paymentStatus = await ValidateTransaction(dto);

                    switch (paymentStatus)
                    {
                    case PaymentStatus.Captured:
                    {
                        Log.Information(
                            $"Validating transaction with orderId: {dto.OrderId} and transactionId: {dto.TransactionId} succeeded!");
                        break;
                    }

                    case PaymentStatus.Reserved:
                    {
                        var captureResponse = await _mobilePayService.CapturePayment(dto.OrderId);

                        Log.Information(
                            $"Validating transaction with orderId: {dto.OrderId} and transactionId: {captureResponse.TransactionId} succeeded!");
                        break;
                    }

                    default:
                    {
                        Log.Warning($"Validating transaction at MobilePay failed with status: {paymentStatus}");
                        throw new ApiException("The purchase could not be completed", 400);
                    }
                    }
                }
            }
            catch (MobilePayException e)
            {
                Log.Warning(
                    $"Complete purchase failed with error message: {e.Message} and status code: {e.GetHttpStatusCode()}");
                throw new ApiException("Failed to complete purchase using MobilePay", 400);
            }

            var purchase = DeliverProduct(dto, claims);

            await SendInvoiceEmailAsync(purchase);

            Log.Information(
                $"Completed purchase with success! OrderId: {dto.OrderId} transactionId: {dto.TransactionId}");

            return(purchase);
        }