예제 #1
0
        public async Task CreateAsync(Payment paymentExecutionResult)
        {
            string subtotalString = paymentExecutionResult.Transactions.First().RelatedResources.First().Sale.Amount.Total;

            try
            {
                Guid id = Guid.Empty;

                do
                {
                    id = Guid.NewGuid();
                } while (_easyShopContext.PayPalExecutedPayments.Any() && _easyShopContext.PayPalExecutedPayments.FirstOrDefault(x => x.Id == id) != null);

                var executedPayment = new PayPalExecutedPayment
                {
                    Id                     = id,
                    Shop                   = _rustShopService.GetCurrentRequestShopInRustStore(),
                    SteamUser              = _steamUserService.GetCurrentRequestSteamUser(),
                    AmountPaid             = Convert.ToDecimal(subtotalString),
                    PaymentDateTime        = DateTime.Now,
                    ParsedPayPalSdkPayment = JsonConvert.SerializeObject(paymentExecutionResult)
                };

                _easyShopContext.PayPalExecutedPayments.Add(executedPayment);
                await _easyShopContext.SaveChangesAsync();

                _logger.LogInformation($"New PayPalExecutedPayment successfully created. ID: {id}");
            }
            catch (Exception e)
            {
                _logger.LogError(e, $"Error on PayPalExecutedPayment entry creation.");
            }
        }
예제 #2
0
        public IActionResult History()
        {
            if (User.Identity.IsAuthenticated)
            {
                var currentShop = _rustShopService.GetCurrentRequestShopInRustStore();
                var steamUser   = _steamUserService.GetCurrentRequestSteamUser();

                var model = new RustStorePurchaseHistoryViewModel()
                {
                    PurchasedProducts = _rustPurchaseStatsServiceSql.GetAllByShopIdAndSteamUserId(currentShop.Id, steamUser.Id)
                                        .Select(x => new RustPurchasedProductViewModel
                    {
                        Name             = x.RustPurchasedItem.RustItem.Name,
                        ImgUrl           = x.RustPurchasedItem.RustItem.ImgUrl,
                        PaidTotal        = x.RustPurchasedItem.TotalPaid,
                        AmountOnPurchase = x.RustPurchasedItem.AmountOnPurchase,
                        AmountLeft       = x.RustPurchasedItem.AmountLeft,
                        PurchaseDateTime = x.RustPurchasedItem.PurchaseDateTime
                    })
                };

                return(View(model));
            }

            return(RedirectToAction("UserHaveToBeLoggedIn", "Authentication"));
        }
예제 #3
0
        public async Task <PayPalPaymentCreationResultDto> CreatePayPalPaymentAsync(string amountToPay)
        {
            var environment = new SandboxEnvironment(_payPalSettings.ClientId, _payPalSettings.ClientSecret);
            var client      = new PayPalHttpClient(environment);

            var steamUser = _steamUserService.GetCurrentRequestSteamUser();

            var payment = new Payment()
            {
                Intent       = "sale",
                Transactions = new List <Transaction>()
                {
                    new Transaction()
                    {
                        Amount = new Amount()
                        {
                            Total    = amountToPay,
                            Currency = "USD"
                        }
                    }
                },
                RedirectUrls = new RedirectUrls()
                {
                    ReturnUrl = $"{_hostString}/{_multiTenantContext.TenantInfo.Identifier}/payment/ExecutePayPalPayment",
                    CancelUrl = $"{_hostString}/{_multiTenantContext.TenantInfo.Identifier}/payment/PaymentFailed"
                },
                Payer = new Payer()
                {
                    PaymentMethod = "paypal"
                },
                NoteToPayer = _configuration["BuyerNotes"]
            };

            PaymentCreateRequest paymentCreateRequest = new PaymentCreateRequest();

            paymentCreateRequest.RequestBody(payment);

            _logger.LogInformation($"Preparation for payment creation against PayPal API");

            HttpStatusCode responseStatusCode;

            try
            {
                BraintreeHttp.HttpResponse paymentCreateRequestResult = await client.Execute(paymentCreateRequest);

                _logger.LogInformation($"PayPal payment creation result, {nameof(paymentCreateRequestResult)}: {JsonConvert.SerializeObject(paymentCreateRequestResult)}");

                responseStatusCode = paymentCreateRequestResult.StatusCode;

                if (responseStatusCode != HttpStatusCode.Created)
                {
                    return(null);
                }

                Payment paymentResult = paymentCreateRequestResult.Result <Payment>();

                await _payPalCreatedPaymentService.CreateAsync(paymentResult);

                return(new PayPalPaymentCreationResultDto {
                    State = PaymentCreationResultEnum.Success, PaymentDetails = paymentResult
                });
            }
            catch (BraintreeHttp.HttpException e)
            {
                responseStatusCode = e.StatusCode;
                var debugId = e.Headers.GetValues("PayPal-Debug-Id").FirstOrDefault();
                _logger.LogError(e, $"PayPal payment creation: Failed\nSteamUserID: {steamUser.Id}\nSteamUserUID: {steamUser.Uid}\nDebugId: {debugId}\nStatusCode: {responseStatusCode}");

                return(new PayPalPaymentCreationResultDto
                {
                    State = PaymentCreationResultEnum.Failed,
                    FailedReason = debugId
                });
            }
        }
        public async Task <RustStorePurchaseStandardProductResultDto> TryPurchaseAsync(RustStoreStandardItemOrder model)
        {
            #region Data preparation

            var steamUser       = _steamUserService.GetCurrentRequestSteamUser();
            var steamUserShop   = _steamUserService.GetCurrentRequestSteamUserShop();
            var currentShop     = _rustShopService.GetCurrentRequestShopInRustStore();
            var currentUserShop = _easyShopContext.UserShops.FirstOrDefault(x => x.ShopId == currentShop.Id);
            var appUser         = await _userManager.FindByIdAsync(currentUserShop?.AppUserId);

            var rustUserItem = _easyShopContext.RustUserItems
                               .Include(x => x.RustItem)
                               .FirstOrDefault(x => x.Id == Guid.Parse(model.ItemId));

            #endregion Data preparation

            #region Check data, continue or return

            var errorId = Guid.NewGuid();

            if (rustUserItem is null || appUser is null || currentUserShop is null || currentShop is null || steamUserShop is null || steamUser is null)
            {
                var error = new
                {
                    ErrorId                   = errorId,
                    rustUserItem              = rustUserItem?.Id,
                    currentShopOwner          = appUser?.Id,
                    currentShop               = currentShop?.Id,
                    ErrosteamUserrId          = steamUser?.Id,
                    currentUserShop_AppUserId = currentUserShop?.AppUserId,
                    currentUserShop_ShopId    = currentUserShop?.ShopId,
                    steamUserShop_SteamUserId = steamUserShop?.SteamUser.Id,
                    steamUserShop_ShopId      = steamUserShop?.Shop.Id,
                };

                _logger.LogError($"Purchase data preparation ErrorID: {errorId}\nVariables:\n{JsonConvert.SerializeObject(error, Formatting.Indented)}");

                return(new RustStorePurchaseStandardProductResultDto()
                {
                    Status = RustStorePurchaseProductResultEnum.ContactSupport,
                    ErrorMessage = $"Please contact support and give them this id '{errorId}'"
                });
            }

            #endregion Check data, continue or return

            #region Price calculation

            decimal actualPrice;
            if (rustUserItem.Discount > 0)
            {
                actualPrice = rustUserItem.Price - (rustUserItem.Price / 100) * rustUserItem.Discount;
            }
            else
            {
                actualPrice = rustUserItem.Price;
            }

            actualPrice *= model.Amount;

            #endregion Price calculation

            #region Check balance have enough money, if not return

            if (steamUserShop.Balance < actualPrice)
            {
                var balanceTooLow = new
                {
                    SteamUserId          = steamUser.Id,
                    ShopId               = currentShop.Id,
                    UserBalanceInShop    = steamUserShop.Balance,
                    OrderPrice           = actualPrice,
                    AmountOfItemsInOrder = model.Amount,
                    SingleItemPrice      = rustUserItem.Price - (rustUserItem.Price / 100) * rustUserItem.Discount
                };

                _logger.LogInformation($"Balance too low:\n{JsonConvert.SerializeObject(balanceTooLow, Formatting.Indented)}");

                return(new RustStorePurchaseStandardProductResultDto()
                {
                    Status = RustStorePurchaseProductResultEnum.Failed,
                    ErrorMessage = "Sorry, your balance is too low for this item please Top-Up balance and try again."
                });
            }


            #endregion Check balance have enough money, if not return

            #region SteamUserShop updating entry values

            steamUserShop.Balance    -= actualPrice;
            steamUserShop.TotalSpent += actualPrice;
            _easyShopContext.SteamUsersShops.Update(steamUserShop);

            #endregion SteamUserShop updating entry values

            #region SteamUser updating entry values

            steamUser.TotalSpent += actualPrice;
            _easyShopContext.SteamUsers.Update(steamUser);

            #endregion SteamUser updating entry values

            #region Creating entry RustPurchasedItems

            Guid rustPurchasedItemId;
            do
            {
                rustPurchasedItemId = Guid.NewGuid();
            } while (_easyShopContext.RustPurchasedItems.FirstOrDefault(x => x.Id == rustPurchasedItemId) != null);

            var newRustPurchasedItem = new RustPurchasedItem
            {
                Id               = rustPurchasedItemId,
                SteamUser        = steamUser,
                RustItem         = rustUserItem.RustItem,
                AmountLeft       = model.Amount,
                AmountOnPurchase = model.Amount,
                ItemsPerStack    = rustUserItem.ItemsPerStack,
                PurchaseDateTime = DateTime.Now,
                TotalPaid        = actualPrice
            };
            _easyShopContext.RustPurchasedItems.Add(newRustPurchasedItem);

            #endregion Creating entry RustPurchasedItems

            #region Creating entry RustPurchaseStats

            Guid rustPurchasedStatsId;
            do
            {
                rustPurchasedStatsId = Guid.NewGuid();
            } while (_easyShopContext.RustPurchaseStats.FirstOrDefault(x => x.Id == rustPurchasedStatsId) != null);

            var newRustPurchaseStats = new RustPurchaseStats
            {
                Id                = rustPurchasedStatsId,
                AppUser           = appUser,
                RustPurchasedItem = newRustPurchasedItem,
                Shop              = currentShop
            };
            _easyShopContext.RustPurchaseStats.Add(newRustPurchaseStats);

            #endregion Creating entry RustPurchaseStats

            #region Try to save data into DB. Return on error

            try
            {
                await _easyShopContext.SaveChangesAsync();

                var purchaseSuccessDetails = new
                {
                    SteamUserId          = steamUser.Id,
                    RustPurchasedItemId  = rustPurchasedItemId,
                    RustPurchasedStatsId = rustPurchasedStatsId
                };

                var     balanceBeforeFundsAddition = appUser.Balance;
                decimal fundsAddToAppUser          = actualPrice - (actualPrice / 100) * _servicePercentPerTransaction;
                appUser.Balance += fundsAddToAppUser;

                _easyShopContext.Users.Update(appUser);
                await _easyShopContext.SaveChangesAsync();

                _logger.LogInformation($"\nAppUser ID: {appUser.Id}\nAppUser Email: {appUser.Email}\nBalance before funds addition: {balanceBeforeFundsAddition}\nFunds added: {fundsAddToAppUser}\nBalance after funds addition: {appUser.Balance}");
                _logger.LogInformation($"Purchase success:\n{JsonConvert.SerializeObject(purchaseSuccessDetails, Formatting.Indented)}");

                return(new RustStorePurchaseStandardProductResultDto
                {
                    Status = RustStorePurchaseProductResultEnum.Success,
                    RustProduct = rustUserItem
                });
            }
            catch (Exception e)
            {
                _logger.LogError(e, $"Error on purchase:\n");
                return(new RustStorePurchaseStandardProductResultDto()
                {
                    Status = RustStorePurchaseProductResultEnum.Failed,
                    ErrorMessage = "Please contact support!"
                });
            }

            #endregion Try to save data into DB. Return on error
        }