diff --git a/apps/auth-server/src/EShopOnAbp.AuthServer/EShopUserClaimsPrincipalFactory.cs b/apps/auth-server/src/EShopOnAbp.AuthServer/EShopUserClaimsPrincipalFactory.cs index 32d0e1fc..24421034 100644 --- a/apps/auth-server/src/EShopOnAbp.AuthServer/EShopUserClaimsPrincipalFactory.cs +++ b/apps/auth-server/src/EShopOnAbp.AuthServer/EShopUserClaimsPrincipalFactory.cs @@ -52,14 +52,21 @@ public class EShopUserClaimsPrincipalFactory : AbpUserClaimsPrincipalFactory { HttpContext.Request.Cookies.TryGetValue(EShopConstants.AnonymousUserClaimName, out var anonymousUserId); - await _cache.SetAsync(user.Id, new AnonymousUserItem {AnonymousUserId = anonymousUserId}, options: new DistributedCacheEntryOptions() - { - AbsoluteExpiration = DateTimeOffset.UtcNow.AddSeconds(60) - }); + await _cache.SetAsync(user.Id, new AnonymousUserItem {AnonymousUserId = anonymousUserId}, + options: new DistributedCacheEntryOptions() + { + AbsoluteExpiration = DateTimeOffset.UtcNow.AddSeconds(60) + }); _logger.LogInformation($"Cached anonymousUserId:{anonymousUserId}."); } var cachedItem = await _cache.GetAsync(user.Id); + if (cachedItem == null) + { + _logger.LogWarning($"Could not retrieve anonymousUserId from cache."); + return principal; + } + _logger.LogInformation($"Retrieved anonymousUserId:{cachedItem.AnonymousUserId} from cache."); principal.Identities.First() .AddClaim(new Claim(EShopConstants.AnonymousUserClaimName, cachedItem.AnonymousUserId)); diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/Basket/UserAddressProvider.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/Basket/UserAddressProvider.cs new file mode 100644 index 00000000..aa61de17 --- /dev/null +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/Basket/UserAddressProvider.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using Volo.Abp.DependencyInjection; + +namespace EShopOnAbp.PublicWeb.Basket; + +public class UserAddressProvider : ITransientDependency +{ + public List GetDemoAddresses() + { + return new List() + { + new() + { + Id = 1, + Name = EShopOnAbpPaymentConsts.DemoAddressTypes.Home, + Description = "Cecilia Chapman Senior 711-2880 Nulla St. Mankato Mississippi 96522/USA", + IsDefault = true + }, + new() + { + Id = 2, + Name = EShopOnAbpPaymentConsts.DemoAddressTypes.Work, + Description = "Yeşilköy Serbest Bölge Mah. E-Blok Sokak E1 Blok No:2, Bakırköy/İstanbul" + } + }; + } +} + +public class AddressDto +{ + public int Id { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public bool IsDefault { get; set; } = false; +} \ No newline at end of file diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/Basket/UserBasketProvider.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/Basket/UserBasketProvider.cs index 6abfc1b4..c96a21a9 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/Basket/UserBasketProvider.cs +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/Basket/UserBasketProvider.cs @@ -5,7 +5,6 @@ using System; using System.Threading.Tasks; using EShopOnAbp.Shared.Hosting.AspNetCore; using Volo.Abp.DependencyInjection; -using Volo.Abp.Guids; using Volo.Abp.Users; namespace EShopOnAbp.PublicWeb.Basket @@ -16,20 +15,17 @@ namespace EShopOnAbp.PublicWeb.Basket private readonly IHttpContextAccessor httpContextAccessor; protected readonly ILogger logger; - protected readonly IGuidGenerator guidGenerator; protected readonly IBasketAppService basketAppService; protected readonly ICurrentUser currentUser; public UserBasketProvider( IHttpContextAccessor httpContextAccessor, ILogger logger, - IGuidGenerator guidGenerator, IBasketAppService basketAppService, ICurrentUser currentUser) { this.httpContextAccessor = httpContextAccessor; this.logger = logger; - this.guidGenerator = guidGenerator; this.basketAppService = basketAppService; this.currentUser = currentUser; } @@ -41,30 +37,17 @@ namespace EShopOnAbp.PublicWeb.Basket // Get anonymous user id from cookie HttpContext.Request.Cookies.TryGetValue(EShopConstants.AnonymousUserClaimName, out string anonymousUserId); - logger.LogInformation($"========= Anonymous User Id from Cookie:{anonymousUserId} ========= "); - - // Generate new id for anonymous user - if (string.IsNullOrEmpty(anonymousUserId)) - { - anonymousUserId = guidGenerator.Create().ToString(); - HttpContext.Response.Cookies.Append(EShopConstants.AnonymousUserClaimName, anonymousUserId, new CookieOptions - { - SameSite = SameSiteMode.Lax - }); - logger.LogInformation( - $"========= Generated new User Id:{anonymousUserId} ========= APPENDED TO COOKIE ====== "); - } if (!currentUser.IsAuthenticated) { - logger.LogInformation( - $"========= Get Basket for Anonymous UserId:{anonymousUserId} ========= ====== "); + logger.LogInformation($"Getting basket for anonymous user id:{anonymousUserId}."); return await basketAppService.GetByAnonymousUserIdAsync(Guid.Parse(anonymousUserId)); } //TODO: Merge with anonymously stored cart if exist var userClaimValue = currentUser.FindClaimValue(EShopConstants.AnonymousUserClaimName); + // Fall-back for having trouble when setting claim on user login if (string.IsNullOrEmpty(userClaimValue)) { return await basketAppService.GetAsync(); diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/Components/AnonymousUser/AnonymousUserViewComponent.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/Components/AnonymousUser/AnonymousUserViewComponent.cs new file mode 100644 index 00000000..570c6c01 --- /dev/null +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/Components/AnonymousUser/AnonymousUserViewComponent.cs @@ -0,0 +1,48 @@ +using System; +using System.Threading.Tasks; +using EShopOnAbp.Shared.Hosting.AspNetCore; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Widgets; +using Volo.Abp.Guids; + +namespace EShopOnAbp.PublicWeb.Components.AnonymousUser; + +[Widget( + AutoInitialize = true +)] +public class AnonymousUserViewComponent : AbpViewComponent +{ + private readonly ILogger _logger; + private readonly IGuidGenerator _guidGenerator; + + public AnonymousUserViewComponent(ILogger logger, IGuidGenerator guidGenerator) + { + _logger = logger; + _guidGenerator = guidGenerator; + } + + public async Task InvokeAsync() + { + // Get anonymous user id from cookie + HttpContext.Request.Cookies.TryGetValue(EShopConstants.AnonymousUserClaimName, + out string anonymousUserId); + _logger.LogInformation($"========= Anonymous User Id from Cookie:{anonymousUserId} ========= "); + + // Generate new id for anonymous user + if (string.IsNullOrEmpty(anonymousUserId)) + { + anonymousUserId = _guidGenerator.Create().ToString(); + HttpContext.Response.Cookies.Append(EShopConstants.AnonymousUserClaimName, anonymousUserId, + new CookieOptions + { + SameSite = SameSiteMode.Lax + }); + _logger.LogInformation( + $"========= Generated new User Id:{anonymousUserId} ========= APPENDED TO COOKIE ====== "); + } + return await Task.FromResult(View("~/Components/AnonymousUser/Default.cshtml")); + } +} \ No newline at end of file diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/Components/AnonymousUser/Default.cshtml b/apps/public-web/src/EShopOnAbp.PublicWeb/Components/AnonymousUser/Default.cshtml new file mode 100644 index 00000000..42eb8c53 --- /dev/null +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/Components/AnonymousUser/Default.cshtml @@ -0,0 +1,3 @@ +
+ +
\ No newline at end of file diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/Components/Basket/Default.cshtml b/apps/public-web/src/EShopOnAbp.PublicWeb/Components/Basket/Default.cshtml index 4eac7762..37762811 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/Components/Basket/Default.cshtml +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/Components/Basket/Default.cshtml @@ -49,9 +49,6 @@
@await Component.InvokeAsync(typeof(PurchaseWidgetViewComponent), new { Basket = Model, ButtonDescription = "CompletePurchase"}) - - -
} diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/Components/Payment/Default.cshtml b/apps/public-web/src/EShopOnAbp.PublicWeb/Components/Payment/Default.cshtml new file mode 100644 index 00000000..bccdea48 --- /dev/null +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/Components/Payment/Default.cshtml @@ -0,0 +1,54 @@ +@using EShopOnAbp.Localization +@using EShopOnAbp.PublicWeb.Components.Purchase +@using Microsoft.Extensions.Localization +@model EShopOnAbp.PublicWeb.Components.Payment.PaymentViewModel + +@inject IStringLocalizer L + +@{ + const int defaultColumnSize = 4; +} + +
+
+
+

Select Address

+ @for (int i = 0; i < Math.Ceiling(Model.Address.Count / (double) defaultColumnSize); i++) + { + + @for (int j = 0; j < defaultColumnSize; j++) + { + + @if (i * defaultColumnSize + j < Model.Address.Count) + { + var address = Model.Address[(i * defaultColumnSize) + j]; + string isSelected = address.IsDefault ? "is-selected" : string.Empty; +
+
+

@address.Name

+

@address.Description

+
+
+ } +
+ } +
+ } +
+ +
+

Select Payment Method

+ + + + paypal logo + + + +
+
+
+ @await Component.InvokeAsync(typeof(PurchaseWidgetViewComponent), + new {Basket = Model.Basket, ButtonDescription = "CompleteOrder"}) +
+
\ No newline at end of file diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/Components/Payment/PaymentWidgetScriptContributor.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/Components/Payment/PaymentWidgetScriptContributor.cs new file mode 100644 index 00000000..851ac11e --- /dev/null +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/Components/Payment/PaymentWidgetScriptContributor.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; +using Volo.Abp.AspNetCore.Mvc.UI.Packages.SignalR; +using Volo.Abp.Modularity; + +namespace EShopOnAbp.PublicWeb.Components.Payment; + +[DependsOn(typeof(SignalRBrowserScriptContributor))] +public class PaymentWidgetScriptContributor : BundleContributor +{ + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files.AddIfNotContains("/components/payment/payment-widget.js"); + } +} \ No newline at end of file diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/Components/Payment/PaymentWidgetStyleContributor.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/Components/Payment/PaymentWidgetStyleContributor.cs new file mode 100644 index 00000000..e4a64246 --- /dev/null +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/Components/Payment/PaymentWidgetStyleContributor.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using Volo.Abp.AspNetCore.Mvc.UI.Bundling; + +namespace EShopOnAbp.PublicWeb.Components.Payment; + +public class PaymentWidgetStyleContributor: BundleContributor +{ + public override void ConfigureBundle(BundleConfigurationContext context) + { + context.Files.AddIfNotContains("/components/payment/payment-widget.css"); + } +} \ No newline at end of file diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/Components/Payment/PaymentWidgetViewComponent.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/Components/Payment/PaymentWidgetViewComponent.cs new file mode 100644 index 00000000..92b281fa --- /dev/null +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/Components/Payment/PaymentWidgetViewComponent.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using EShopOnAbp.BasketService; +using EShopOnAbp.PublicWeb.Basket; +using Microsoft.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.UI.Widgets; + +namespace EShopOnAbp.PublicWeb.Components.Payment; + +[Widget( + AutoInitialize = true, + RefreshUrl = "/Widgets/Payment", + StyleTypes = new[] {typeof(PaymentWidgetStyleContributor)}, + ScriptTypes = new[] {typeof(PaymentWidgetScriptContributor)} +)] +public class PaymentWidgetViewComponent : AbpViewComponent +{ + private readonly UserBasketProvider _userBasketProvider; + private readonly UserAddressProvider _userAddressProvider; + + public PaymentWidgetViewComponent(UserBasketProvider userBasketProvider, UserAddressProvider userAddressProvider) + { + _userBasketProvider = userBasketProvider; + _userAddressProvider = userAddressProvider; + } + + public async Task InvokeAsync() + { + var viewModel = new PaymentViewModel() + { + Basket = await _userBasketProvider.GetBasketAsync(), + Address = _userAddressProvider.GetDemoAddresses() + }; + return View("~/Components/Payment/Default.cshtml", viewModel); + } +} + +public class PaymentViewModel +{ + public BasketDto Basket { get; set; } + public List Address { get; set; } +} \ No newline at end of file diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbp.PublicWeb.csproj b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbp.PublicWeb.csproj index a66cf000..7f718696 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbp.PublicWeb.csproj +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbp.PublicWeb.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -6,6 +6,7 @@ + @@ -26,6 +27,8 @@ + + diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPaymentConsts.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPaymentConsts.cs new file mode 100644 index 00000000..c9a75f54 --- /dev/null +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPaymentConsts.cs @@ -0,0 +1,13 @@ +namespace EShopOnAbp.PublicWeb +{ + public static class EShopOnAbpPaymentConsts + { + public const string Currency = "USD"; + + public static class DemoAddressTypes + { + public const string Work = "Work"; + public const string Home = "Home"; + } + } +} diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicAutoMapperProfile.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicAutoMapperProfile.cs new file mode 100644 index 00000000..8b8ada44 --- /dev/null +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicAutoMapperProfile.cs @@ -0,0 +1,18 @@ +using AutoMapper; +using EShopOnAbp.BasketService; +using EShopOnAbp.PaymentService; + +namespace EShopOnAbp.PublicWeb +{ + public class EShopOnAbpPublicAutoMapperProfile : Profile + { + public EShopOnAbpPublicAutoMapperProfile() + { + CreateMap() + .ForMember(p => p.ReferenceId, opts => opts.MapFrom(p => p.ProductId.ToString())) + .ForMember(p => p.Name, opts => opts.MapFrom(p => p.ProductName)) + .ForMember(p => p.UnitPrice, opts => opts.MapFrom(p => p.TotalPrice / p.Count)) + .ForMember(p => p.Quantity, opts => opts.MapFrom(p => p.Count)); + } + } +} diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs index d912d267..146189d6 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebModule.cs @@ -1,18 +1,18 @@ -using System; -using System.Net.Http.Headers; -using EShopOnAbp.BasketService; +using EShopOnAbp.BasketService; using EShopOnAbp.CatalogService; using EShopOnAbp.Localization; +using EShopOnAbp.PaymentService; using EShopOnAbp.PublicWeb.Menus; using EShopOnAbp.Shared.Hosting.AspNetCore; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.DataProtection; -using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.IdentityModel.Protocols.OpenIdConnect; using StackExchange.Redis; +using System; +using System.Net.Http.Headers; using Volo.Abp; using Volo.Abp.Account; using Volo.Abp.AspNetCore.Authentication.OpenIdConnect; @@ -22,6 +22,7 @@ using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared; using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars; using Volo.Abp.AspNetCore.SignalR; +using Volo.Abp.AutoMapper; using Volo.Abp.Caching; using Volo.Abp.Caching.StackExchangeRedis; using Volo.Abp.EventBus.RabbitMq; @@ -47,7 +48,9 @@ namespace EShopOnAbp.PublicWeb typeof(EShopOnAbpSharedLocalizationModule), typeof(CatalogServiceHttpApiClientModule), typeof(BasketServiceHttpApiClientModule), - typeof(AbpAspNetCoreSignalRModule) + typeof(AbpAspNetCoreSignalRModule), + typeof(PaymentServiceHttpApiClientModule), + typeof(AbpAutoMapperModule) )] public class EShopOnAbpPublicWebModule : AbpModule { @@ -68,6 +71,12 @@ namespace EShopOnAbp.PublicWeb var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = context.Services.GetConfiguration(); + context.Services.AddAutoMapperObjectMapper(); + Configure(options => + { + options.AddMaps(validate: true); + }); + Configure(options => { options.IsEnabled = true; @@ -83,6 +92,11 @@ namespace EShopOnAbp.PublicWeb options.Applications["MVC"].RootUrl = configuration["App:SelfUrl"]; }); + Configure(options => + { + options.PaymentSuccessfulCallbackUrl = configuration["App:SelfUrl"].EnsureEndsWith('/') + "PaymentCompleted"; + }); + context.Services.AddAuthentication(options => { options.DefaultScheme = "Cookies"; @@ -110,6 +124,7 @@ namespace EShopOnAbp.PublicWeb options.Scope.Add("AdministrationService"); options.Scope.Add("BasketService"); options.Scope.Add("CatalogService"); + options.Scope.Add("PaymentService"); }); var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]); diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebPaymentOptions.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebPaymentOptions.cs new file mode 100644 index 00000000..dd4d1cc0 --- /dev/null +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/EShopOnAbpPublicWebPaymentOptions.cs @@ -0,0 +1,8 @@ +namespace EShopOnAbp.PublicWeb +{ + public class EShopOnAbpPublicWebPaymentOptions + { + public string PaymentSuccessfulCallbackUrl { get; set; } + public string PaymentFailureCallbackUrl { get; set; } + } +} diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Basket.cshtml b/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Basket.cshtml index f9879e85..bb9388f2 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Basket.cshtml +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Basket.cshtml @@ -11,8 +11,8 @@ @inject IStringLocalizer L
-

@L["YourBasket"]

-
+ @*

@L["YourBasket"]

*@ +
@await Component.InvokeAsync(typeof(BasketWidgetViewComponent))
\ No newline at end of file diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Basket.cshtml.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Basket.cshtml.cs index da1cbc36..ea18bcff 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Basket.cshtml.cs +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Basket.cshtml.cs @@ -6,11 +6,8 @@ namespace EShopOnAbp.PublicWeb.Pages; public class BasketModel : AbpPageModel { - private readonly ILogger _logger; - - public BasketModel(ILogger logger) + public BasketModel() { - _logger = logger; } public void OnGet() @@ -21,7 +18,7 @@ public class BasketModel : AbpPageModel { if (!CurrentUser.IsAuthenticated) { - _logger.LogInformation("Redirecting to Login"); + Logger.LogInformation("Redirecting to Login.."); return Challenge(); } diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Index.cshtml b/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Index.cshtml index 9589b904..51c1ed81 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Index.cshtml +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Index.cshtml @@ -6,21 +6,28 @@ @{ const int productsColumnSize = 4; // TODO: update abp-column helper to plain html for proper row and columns css + string pageHeader = L["OurProducts"]; } @section styles{ } + @section scripts { - - + + +} + +@if (Model.HasRemoteServiceError) +{ + pageHeader = L["CatalogServiceNotAvailable"]; }
-

@L["OurProducts"]

+

@pageHeader

- @for (int i = 0; i < Math.Ceiling(Model.Products.Count / (double)productsColumnSize); i++) + @for (int i = 0; i < Math.Ceiling(Model.Products.Count / (double) productsColumnSize); i++) { @for (int j = 0; j < productsColumnSize; j++) diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Index.cshtml.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Index.cshtml.cs index 6191dd43..1b2f7b1e 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Index.cshtml.cs +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Index.cshtml.cs @@ -1,4 +1,6 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Threading.Tasks; using EShopOnAbp.CatalogService.Products; using Microsoft.AspNetCore.Authentication; @@ -9,6 +11,7 @@ namespace EShopOnAbp.PublicWeb.Pages public class IndexModel : AbpPageModel { public IReadOnlyList Products { get; private set; } + public bool HasRemoteServiceError { get; set; } = false; private readonly IPublicProductAppService _productAppService; public IndexModel(IPublicProductAppService productAppService) @@ -18,7 +21,17 @@ namespace EShopOnAbp.PublicWeb.Pages public async Task OnGet() { - Products = (await _productAppService.GetListAsync()).Items; + try + { + Products = (await _productAppService.GetListAsync()).Items; + } + catch (Exception e) + { + Products = new ReadOnlyCollection(new List()); + HasRemoteServiceError = true; + Console.WriteLine(e); + } + } public async Task OnPostLoginAsync() diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Payment.cshtml b/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Payment.cshtml index 942cde10..09b5c2d8 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Payment.cshtml +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Payment.cshtml @@ -1,10 +1,14 @@ @page - @using EShopOnAbp.Localization +@using EShopOnAbp.PublicWeb.Components.Payment @using Microsoft.Extensions.Localization @model EShopOnAbp.PublicWeb.Pages.PaymentModel + @inject IStringLocalizer L
-

@L["Payment"]

+ @*

@L["Payment"]

*@ +
+ @await Component.InvokeAsync(typeof(PaymentWidgetViewComponent)) +
\ No newline at end of file diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Payment.cshtml.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Payment.cshtml.cs index 831ff457..239341c1 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Payment.cshtml.cs +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/Payment.cshtml.cs @@ -1,10 +1,59 @@ -using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; +using EShopOnAbp.BasketService; +using EShopOnAbp.PaymentService; +using EShopOnAbp.PaymentService.PaymentRequests; +using EShopOnAbp.PublicWeb.Basket; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; +using Volo.Abp.Users; namespace EShopOnAbp.PublicWeb.Pages; +[Authorize] public class PaymentModel : AbpPageModel { + private readonly IPaymentRequestAppService _paymentRequestAppService; + private readonly UserBasketProvider _userBasketProvider; + private readonly EShopOnAbpPublicWebPaymentOptions _publicWebPaymentOptions; + + public PaymentModel( + IPaymentRequestAppService paymentRequestAppService, + UserBasketProvider userBasketProvider, + IOptions publicWebPaymentOptions) + { + _paymentRequestAppService = paymentRequestAppService; + _userBasketProvider = userBasketProvider; + _publicWebPaymentOptions = publicWebPaymentOptions.Value; + } + public void OnGet() { } + + public async Task OnPostAsync() + { + Logger.LogInformation("Payment Proceeded..."); + + var basket = await _userBasketProvider.GetBasketAsync(); + + var paymentRequest = await _paymentRequestAppService.CreateAsync(new PaymentRequestCreationDto + { + BuyerId = CurrentUser.GetId().ToString(), + Currency = EShopOnAbpPaymentConsts.Currency, + Products = ObjectMapper.Map, List>(basket.Items) + }); + + var response = await _paymentRequestAppService.StartAsync(new PaymentRequestStartDto + { + PaymentRequestId = paymentRequest.Id, + ReturnUrl = _publicWebPaymentOptions.PaymentSuccessfulCallbackUrl, + CancelUrl = _publicWebPaymentOptions.PaymentFailureCallbackUrl, + }); + + return Redirect(response.CheckoutLink); + } } \ No newline at end of file diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/PaymentCompleted.cshtml b/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/PaymentCompleted.cshtml new file mode 100644 index 00000000..1dbd3b35 --- /dev/null +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/PaymentCompleted.cshtml @@ -0,0 +1,16 @@ +@page +@model EShopOnAbp.PublicWeb.Pages.PaymentCompletedModel + +
+ + @if (Model.IsSuccessful) + { +

Thank you for the payment!

+
+

Purchase completed!

+
+

click here to return to home page

+ + } + +
\ No newline at end of file diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/PaymentCompleted.cshtml.cs b/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/PaymentCompleted.cshtml.cs new file mode 100644 index 00000000..fa3f87b8 --- /dev/null +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/PaymentCompleted.cshtml.cs @@ -0,0 +1,32 @@ +using EShopOnAbp.PaymentService.PaymentRequests; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc.UI.RazorPages; + +namespace EShopOnAbp.PublicWeb.Pages; + +[Authorize] +public class PaymentCompletedModel : AbpPageModel +{ + private readonly IPaymentRequestAppService _paymentRequestAppService; + + public PaymentCompletedModel(IPaymentRequestAppService paymentRequestAppService) + { + _paymentRequestAppService = paymentRequestAppService; + } + + [BindProperty(SupportsGet = true)] + public string Token { get; set; } + + public PaymentRequestDto PaymentRequest { get; private set; } + + public bool IsSuccessful { get; private set; } + + public async Task OnGetAsync() + { + PaymentRequest = await _paymentRequestAppService.CompleteAsync(Token); + + IsSuccessful = PaymentRequest.State == PaymentRequestState.Completed; + } +} \ No newline at end of file diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/_ViewStart.cshtml b/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/_ViewStart.cshtml index 932987df..2f921a29 100644 --- a/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/_ViewStart.cshtml +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/Pages/_ViewStart.cshtml @@ -1,5 +1,7 @@ -@using Volo.Abp.AspNetCore.Mvc.UI.Theming +@using EShopOnAbp.PublicWeb.Components.AnonymousUser +@using Volo.Abp.AspNetCore.Mvc.UI.Theming @inject IThemeManager ThemeManager @{ Layout = ThemeManager.CurrentTheme.GetPublicLayout(); } +@await Component.InvokeAsync(typeof(AnonymousUserViewComponent)) \ No newline at end of file diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/wwwroot/components/payment/payment-widget.css b/apps/public-web/src/EShopOnAbp.PublicWeb/wwwroot/components/payment/payment-widget.css new file mode 100644 index 00000000..1b38f784 --- /dev/null +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/wwwroot/components/payment/payment-widget.css @@ -0,0 +1,20 @@ +.card { + /* Add shadows to create the "card" effect */ + box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); + transition: 0.3s; +} + +/* On mouse-over, add a deeper shadow */ +.card:hover { + box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2); + cursor: default; +} + +/* Add some padding inside the card container */ +.card-body { + padding: 2px 16px; +} + +.is-selected { + border: solid #bfbfe3; +} \ No newline at end of file diff --git a/apps/public-web/src/EShopOnAbp.PublicWeb/wwwroot/components/payment/payment-widget.js b/apps/public-web/src/EShopOnAbp.PublicWeb/wwwroot/components/payment/payment-widget.js new file mode 100644 index 00000000..b246c5f1 --- /dev/null +++ b/apps/public-web/src/EShopOnAbp.PublicWeb/wwwroot/components/payment/payment-widget.js @@ -0,0 +1,21 @@ +(function () { + abp.widgets.PaymentWidget = function ($wrapper) { + var widgetManager = $wrapper.data('abp-widget-manager'); + + var init = function (filters) { + $wrapper + .find('.address-list .card') + .click(function () { + var $this = $(this); + var addressId = $this.attr('data-address-id'); + abp.utils.setCookieValue("selected-address", addressId); + $this.parents(".address-list").find('.card').removeClass("is-selected"); + $this.addClass("is-selected"); + }); + }; + + return { + init: init + }; + }; +})(); \ No newline at end of file diff --git a/gateways/web-public/src/EShopOnAbp.WebPublicGateway/appsettings.json b/gateways/web-public/src/EShopOnAbp.WebPublicGateway/appsettings.json index fceda57f..0d2c05a6 100644 --- a/gateways/web-public/src/EShopOnAbp.WebPublicGateway/appsettings.json +++ b/gateways/web-public/src/EShopOnAbp.WebPublicGateway/appsettings.json @@ -87,6 +87,19 @@ ], "UpstreamPathTemplate": "/api/ordering/{everything}", "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] + }, + { + "ServiceKey": "Payment Service", + "DownstreamPathTemplate": "/api/payment/{everything}", + "DownstreamScheme": "https", + "DownstreamHostAndPorts": [ + { + "Host": "localhost", + "Port": 44357 + } + ], + "UpstreamPathTemplate": "/api/payment/{everything}", + "UpstreamHttpMethod": [ "Put", "Delete", "Get", "Post" ] } ], "GlobalConfiguration": { diff --git a/services/basket/src/EShopOnAbp.BasketService.Application.Contracts/IBasketAppService.cs b/services/basket/src/EShopOnAbp.BasketService.Application.Contracts/IBasketAppService.cs index 2bf27fe7..cc8d89b6 100644 --- a/services/basket/src/EShopOnAbp.BasketService.Application.Contracts/IBasketAppService.cs +++ b/services/basket/src/EShopOnAbp.BasketService.Application.Contracts/IBasketAppService.cs @@ -11,5 +11,4 @@ public interface IBasketAppService : IApplicationService Task MergeBasketsAsync(); Task AddProductAsync(AddProductDto input); Task RemoveProductAsync(RemoveProductDto input); - Task PurchaseAsync(); } \ No newline at end of file diff --git a/services/basket/src/EShopOnAbp.BasketService.Application/BasketAppService.cs b/services/basket/src/EShopOnAbp.BasketService.Application/BasketAppService.cs index f2280018..d597f4c5 100644 --- a/services/basket/src/EShopOnAbp.BasketService.Application/BasketAppService.cs +++ b/services/basket/src/EShopOnAbp.BasketService.Application/BasketAppService.cs @@ -104,15 +104,6 @@ public class BasketAppService : BasketServiceAppService, IBasketAppService return await GetBasketDtoAsync(basket); } - public async Task PurchaseAsync() - { - var basket = await _basketRepository.GetAsync(CurrentUser.GetId()); - var orderAcceptedEto = ObjectMapper.Map(basket); - await _distributedEventBus.PublishAsync(orderAcceptedEto); - basket.Clear(); - await _basketRepository.UpdateAsync(basket); - } - private async Task GetBasketDtoAsync(Basket basket) { var products = new Dictionary(); diff --git a/services/basket/src/EShopOnAbp.BasketService.Application/BasketServiceApplicationAutoMapperProfile.cs b/services/basket/src/EShopOnAbp.BasketService.Application/BasketServiceApplicationAutoMapperProfile.cs index 1f64020d..7d781826 100644 --- a/services/basket/src/EShopOnAbp.BasketService.Application/BasketServiceApplicationAutoMapperProfile.cs +++ b/services/basket/src/EShopOnAbp.BasketService.Application/BasketServiceApplicationAutoMapperProfile.cs @@ -8,8 +8,6 @@ namespace EShopOnAbp.BasketService public BasketServiceApplicationAutoMapperProfile() { CreateMap(); - CreateMap(); - CreateMap(); } } } diff --git a/services/basket/src/EShopOnAbp.BasketService.Domain.Shared/BasketServiceDomainSharedModule.cs b/services/basket/src/EShopOnAbp.BasketService.Domain.Shared/BasketServiceDomainSharedModule.cs index e32c00ad..73650d79 100644 --- a/services/basket/src/EShopOnAbp.BasketService.Domain.Shared/BasketServiceDomainSharedModule.cs +++ b/services/basket/src/EShopOnAbp.BasketService.Domain.Shared/BasketServiceDomainSharedModule.cs @@ -1,4 +1,5 @@ using EShopOnAbp.BasketService.Localization; +using EShopOnAbp.OrderingService; using Volo.Abp.Localization; using Volo.Abp.Localization.ExceptionHandling; using Volo.Abp.Modularity; @@ -9,7 +10,8 @@ using Volo.Abp.VirtualFileSystem; namespace EShopOnAbp.BasketService { [DependsOn( - typeof(AbpValidationModule) + typeof(AbpValidationModule), + typeof(OrderingServiceDomainSharedModule) )] public class BasketServiceDomainSharedModule : AbpModule { diff --git a/services/basket/src/EShopOnAbp.BasketService.Domain.Shared/EShopOnAbp.BasketService.Domain.Shared.csproj b/services/basket/src/EShopOnAbp.BasketService.Domain.Shared/EShopOnAbp.BasketService.Domain.Shared.csproj index 56e7c21d..c2145e96 100644 --- a/services/basket/src/EShopOnAbp.BasketService.Domain.Shared/EShopOnAbp.BasketService.Domain.Shared.csproj +++ b/services/basket/src/EShopOnAbp.BasketService.Domain.Shared/EShopOnAbp.BasketService.Domain.Shared.csproj @@ -16,6 +16,9 @@ + + + diff --git a/services/basket/src/EShopOnAbp.BasketService.Domain.Shared/OrderAcceptedEto.cs b/services/basket/src/EShopOnAbp.BasketService.Domain.Shared/OrderAcceptedEto.cs deleted file mode 100644 index 56ad03b4..00000000 --- a/services/basket/src/EShopOnAbp.BasketService.Domain.Shared/OrderAcceptedEto.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Collections.Generic; - -namespace EShopOnAbp.BasketService; - -public class OrderAcceptedEto -{ - public List Items { get; set; } -} \ No newline at end of file diff --git a/services/basket/src/EShopOnAbp.BasketService.Domain.Shared/OrderItemEto.cs b/services/basket/src/EShopOnAbp.BasketService.Domain.Shared/OrderItemEto.cs deleted file mode 100644 index 16cfa7e6..00000000 --- a/services/basket/src/EShopOnAbp.BasketService.Domain.Shared/OrderItemEto.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace EShopOnAbp.BasketService; - -public class OrderItemEto -{ - public Guid ProductId { get; set; } - public int Count { get; set; } -} \ No newline at end of file diff --git a/services/basket/src/EShopOnAbp.BasketService.Domain/Orders/OrderAcceptedEventHandler.cs b/services/basket/src/EShopOnAbp.BasketService.Domain/Orders/OrderAcceptedEventHandler.cs new file mode 100644 index 00000000..87324de1 --- /dev/null +++ b/services/basket/src/EShopOnAbp.BasketService.Domain/Orders/OrderAcceptedEventHandler.cs @@ -0,0 +1,26 @@ +using EShopOnAbp.OrderingService.Orders; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; + +namespace EShopOnAbp.BasketService.Orders +{ + public class OrderAcceptedEventHandler : + IDistributedEventHandler, + ITransientDependency + { + private readonly IBasketRepository _basketRepository; + + public OrderAcceptedEventHandler(IBasketRepository basketRepository) + { + _basketRepository = basketRepository; + } + + public async Task HandleEventAsync(OrderAcceptedEto eventData) + { + var basket = await _basketRepository.GetAsync(eventData.BuyerId); + basket.Clear(); + await _basketRepository.UpdateAsync(basket); + } + } +} diff --git a/services/basket/src/EShopOnAbp.BasketService.HttpApi.Client/ClientProxies/BasketClientProxy.Generated.cs b/services/basket/src/EShopOnAbp.BasketService.HttpApi.Client/ClientProxies/BasketClientProxy.Generated.cs index b8174b87..5c819286 100644 --- a/services/basket/src/EShopOnAbp.BasketService.HttpApi.Client/ClientProxies/BasketClientProxy.Generated.cs +++ b/services/basket/src/EShopOnAbp.BasketService.HttpApi.Client/ClientProxies/BasketClientProxy.Generated.cs @@ -48,10 +48,5 @@ namespace EShopOnAbp.BasketService.ClientProxies { typeof(RemoveProductDto), input } }); } - - public virtual async Task PurchaseAsync() - { - await RequestAsync(nameof(PurchaseAsync)); - } } } diff --git a/services/catalog/src/EShopOnAbp.CatalogService.Domain.Shared/EShopOnAbp.CatalogService.Domain.Shared.csproj b/services/catalog/src/EShopOnAbp.CatalogService.Domain.Shared/EShopOnAbp.CatalogService.Domain.Shared.csproj index 3577c481..eb169efe 100644 --- a/services/catalog/src/EShopOnAbp.CatalogService.Domain.Shared/EShopOnAbp.CatalogService.Domain.Shared.csproj +++ b/services/catalog/src/EShopOnAbp.CatalogService.Domain.Shared/EShopOnAbp.CatalogService.Domain.Shared.csproj @@ -16,6 +16,10 @@ + + + + diff --git a/services/catalog/src/EShopOnAbp.CatalogService.Domain/EShopOnAbp.CatalogService.Domain.csproj b/services/catalog/src/EShopOnAbp.CatalogService.Domain/EShopOnAbp.CatalogService.Domain.csproj index 889b067f..19beb646 100644 --- a/services/catalog/src/EShopOnAbp.CatalogService.Domain/EShopOnAbp.CatalogService.Domain.csproj +++ b/services/catalog/src/EShopOnAbp.CatalogService.Domain/EShopOnAbp.CatalogService.Domain.csproj @@ -9,7 +9,6 @@ - diff --git a/services/catalog/src/EShopOnAbp.CatalogService.Domain/OrderHandler.cs b/services/catalog/src/EShopOnAbp.CatalogService.Domain/OrderHandler.cs index c2f08b40..1dabcc8e 100644 --- a/services/catalog/src/EShopOnAbp.CatalogService.Domain/OrderHandler.cs +++ b/services/catalog/src/EShopOnAbp.CatalogService.Domain/OrderHandler.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using EShopOnAbp.BasketService; using EShopOnAbp.CatalogService.Products; +using EShopOnAbp.OrderingService.Orders; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Repositories; using Volo.Abp.EventBus.Distributed; diff --git a/services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/DbMigrations/IdentityServerDataSeeder.cs b/services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/DbMigrations/IdentityServerDataSeeder.cs index 70bf3231..3ddf3ba4 100644 --- a/services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/DbMigrations/IdentityServerDataSeeder.cs +++ b/services/identity/src/EShopOnAbp.IdentityService.HttpApi.Host/DbMigrations/IdentityServerDataSeeder.cs @@ -217,8 +217,9 @@ namespace EShopOnAbp.IdentityService.DbMigrations scopes: commonScopes.Union(new[] { "AdministrationService", - "CatalogService", - "BasketService" + "CatalogService", // Consider removing this service + "BasketService", + "PaymentService" }), grantTypes: new[] { "hybrid" }, secret: "1q2w3e*".Sha256(), diff --git a/services/ordering/src/EShopOnAbp.OrderingService.Domain.Shared/EShopOnAbp.OrderingService.Domain.Shared.csproj b/services/ordering/src/EShopOnAbp.OrderingService.Domain.Shared/EShopOnAbp.OrderingService.Domain.Shared.csproj index 6f8548a7..b107c275 100644 --- a/services/ordering/src/EShopOnAbp.OrderingService.Domain.Shared/EShopOnAbp.OrderingService.Domain.Shared.csproj +++ b/services/ordering/src/EShopOnAbp.OrderingService.Domain.Shared/EShopOnAbp.OrderingService.Domain.Shared.csproj @@ -1,4 +1,4 @@ - + @@ -16,6 +16,10 @@ + + + + diff --git a/services/ordering/src/EShopOnAbp.OrderingService.Domain.Shared/OrderingServiceDomainSharedModule.cs b/services/ordering/src/EShopOnAbp.OrderingService.Domain.Shared/OrderingServiceDomainSharedModule.cs index 51121b33..f3dce386 100644 --- a/services/ordering/src/EShopOnAbp.OrderingService.Domain.Shared/OrderingServiceDomainSharedModule.cs +++ b/services/ordering/src/EShopOnAbp.OrderingService.Domain.Shared/OrderingServiceDomainSharedModule.cs @@ -5,11 +5,13 @@ using Volo.Abp.Localization.ExceptionHandling; using Volo.Abp.Validation; using Volo.Abp.Validation.Localization; using Volo.Abp.VirtualFileSystem; +using EShopOnAbp.PaymentService; namespace EShopOnAbp.OrderingService { [DependsOn( - typeof(AbpValidationModule) + typeof(AbpValidationModule), + typeof(PaymentServiceDomainSharedModule) )] public class OrderingServiceDomainSharedModule : AbpModule { diff --git a/services/ordering/src/EShopOnAbp.OrderingService.Domain.Shared/Orders/OrderAcceptedEto.cs b/services/ordering/src/EShopOnAbp.OrderingService.Domain.Shared/Orders/OrderAcceptedEto.cs new file mode 100644 index 00000000..811f829a --- /dev/null +++ b/services/ordering/src/EShopOnAbp.OrderingService.Domain.Shared/Orders/OrderAcceptedEto.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EventBus; + +namespace EShopOnAbp.OrderingService.Orders +{ + [Serializable] + [EventName("EShopOnAbp.Order.Accepted")] + public class OrderAcceptedEto : EtoBase + { + public Guid OrderId { get; set; } + public Guid BuyerId { get; set; } + public List Items { get; set; } + } +} diff --git a/services/ordering/src/EShopOnAbp.OrderingService.Domain.Shared/Orders/OrderItemEto.cs b/services/ordering/src/EShopOnAbp.OrderingService.Domain.Shared/Orders/OrderItemEto.cs new file mode 100644 index 00000000..367baffd --- /dev/null +++ b/services/ordering/src/EShopOnAbp.OrderingService.Domain.Shared/Orders/OrderItemEto.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EShopOnAbp.OrderingService.Orders +{ + public class OrderItemEto + { + public Guid ProductId { get; set; } + public int Count { get; set; } + } +} diff --git a/services/ordering/src/EShopOnAbp.OrderingService.Domain/PaymentRequests/PaymentRequestEventHandler.cs b/services/ordering/src/EShopOnAbp.OrderingService.Domain/PaymentRequests/PaymentRequestEventHandler.cs new file mode 100644 index 00000000..bfd28dc1 --- /dev/null +++ b/services/ordering/src/EShopOnAbp.OrderingService.Domain/PaymentRequests/PaymentRequestEventHandler.cs @@ -0,0 +1,45 @@ +using EShopOnAbp.OrderingService.Orders; +using EShopOnAbp.PaymentService.PaymentRequests; +using System; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.EventBus.Distributed; + +namespace EShopOnAbp.OrderingService.PaymentRequests +{ + public class PaymentRequestEventHandler : + IDistributedEventHandler, + ITransientDependency + { + private readonly IDistributedEventBus _eventBus; + + public PaymentRequestEventHandler(IDistributedEventBus eventBus) + { + _eventBus = eventBus; + } + + public async Task HandleEventAsync(PaymentRequestCompletedEto eventData) + { + // TODO: Insert Order here. + //throw new NotImplementedException(); + + await _eventBus.PublishAsync(new OrderAcceptedEto + { + Items = eventData.Products.Select(MapProductToOrderItem).ToList(), + BuyerId = Guid.Parse(eventData.BuyerId), + OrderId = Guid.Empty, // TODO: Inserted OrderId, + }); + } + + private static OrderItemEto MapProductToOrderItem(PaymentRequestProductEto arg) + { + return new OrderItemEto + { + Count = arg.Quantity, + ProductId = Guid.Parse(arg.ReferenceId) + }; + } + } +} diff --git a/services/payment/src/EShopOnAbp.PaymentService.Application.Contracts/PaymentRequests/PaymentCompletedEto.cs b/services/payment/src/EShopOnAbp.PaymentService.Application.Contracts/PaymentRequests/PaymentCompletedEto.cs new file mode 100644 index 00000000..dd872e5b --- /dev/null +++ b/services/payment/src/EShopOnAbp.PaymentService.Application.Contracts/PaymentRequests/PaymentCompletedEto.cs @@ -0,0 +1,11 @@ +using Volo.Abp.Domain.Entities.Events.Distributed; +using Volo.Abp.EventBus; + +namespace EShopOnAbp.PaymentService.PaymentRequests +{ + [EventName("EShopOnAbp.Payment.Completed")] + public class PaymentCompletedEto : EtoBase + { + public PaymentRequestDto PaymentRequest { get; set; } + } +} diff --git a/services/payment/src/EShopOnAbp.PaymentService.Application/PaymentRequests/PaymentRequestAppService.cs b/services/payment/src/EShopOnAbp.PaymentService.Application/PaymentRequests/PaymentRequestAppService.cs index 4e4cfc9d..d07b7d77 100644 --- a/services/payment/src/EShopOnAbp.PaymentService.Application/PaymentRequests/PaymentRequestAppService.cs +++ b/services/payment/src/EShopOnAbp.PaymentService.Application/PaymentRequests/PaymentRequestAppService.cs @@ -28,6 +28,7 @@ namespace EShopOnAbp.PaymentService.PaymentRequests foreach (var paymentRequestProduct in input.Products .Select(s => new PaymentRequestProduct( + GuidGenerator.Create(), paymentRequest.Id, s.Name, s.UnitPrice, @@ -38,12 +39,14 @@ namespace EShopOnAbp.PaymentService.PaymentRequests paymentRequest.Products.Add(paymentRequestProduct); } + await PaymentRequestRepository.InsertAsync(paymentRequest); + return ObjectMapper.Map(paymentRequest); } public async Task StartAsync(PaymentRequestStartDto input) { - var paymentRequest = await PaymentRequestRepository.GetAsync(input.PaymentRequestId); + var paymentRequest = await PaymentRequestRepository.GetAsync(input.PaymentRequestId, includeDetails: true); var totalCheckoutPrice = paymentRequest.Products.Sum(s => s.TotalPrice); diff --git a/services/payment/src/EShopOnAbp.PaymentService.Application/PaymentServiceApplicationAutoMapperProfile.cs b/services/payment/src/EShopOnAbp.PaymentService.Application/PaymentServiceApplicationAutoMapperProfile.cs index 0867269d..44fbd070 100644 --- a/services/payment/src/EShopOnAbp.PaymentService.Application/PaymentServiceApplicationAutoMapperProfile.cs +++ b/services/payment/src/EShopOnAbp.PaymentService.Application/PaymentServiceApplicationAutoMapperProfile.cs @@ -1,4 +1,6 @@ using AutoMapper; +using EShopOnAbp.PaymentService.PaymentRequests; +using Volo.Abp.AutoMapper; namespace EShopOnAbp.PaymentService { @@ -6,6 +8,9 @@ namespace EShopOnAbp.PaymentService { public PaymentServiceApplicationAutoMapperProfile() { + CreateMap(); + CreateMap(); + /* You can configure your AutoMapper mapping configuration here. * Alternatively, you can split your mapping configurations * into multiple profile classes for a better organization. */ diff --git a/services/payment/src/EShopOnAbp.PaymentService.Application/PaymentServiceApplicationModule.cs b/services/payment/src/EShopOnAbp.PaymentService.Application/PaymentServiceApplicationModule.cs index 024b3ba5..864f0c1d 100644 --- a/services/payment/src/EShopOnAbp.PaymentService.Application/PaymentServiceApplicationModule.cs +++ b/services/payment/src/EShopOnAbp.PaymentService.Application/PaymentServiceApplicationModule.cs @@ -25,6 +25,8 @@ namespace EShopOnAbp.PaymentService options.AddMaps(validate: true); }); + Configure(context.Services.GetConfiguration().GetSection("Payment:PayPal")); + context.Services.AddTransient(provider => { var options = provider.GetService>().Value; diff --git a/services/payment/src/EShopOnAbp.PaymentService.Domain.Shared/PaymentRequests/PaymentRequestCompletedEto.cs b/services/payment/src/EShopOnAbp.PaymentService.Domain.Shared/PaymentRequests/PaymentRequestCompletedEto.cs index 7978cca4..de386871 100644 --- a/services/payment/src/EShopOnAbp.PaymentService.Domain.Shared/PaymentRequests/PaymentRequestCompletedEto.cs +++ b/services/payment/src/EShopOnAbp.PaymentService.Domain.Shared/PaymentRequests/PaymentRequestCompletedEto.cs @@ -1,15 +1,25 @@ using System; +using System.Collections.Generic; using Volo.Abp.Data; using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.EventBus; -namespace EShopOnAbp.PaymentService +namespace EShopOnAbp.PaymentService.PaymentRequests { [Serializable] - [EventName("Payment.Completed")] - public class PaymentRequestCompletedEto: EtoBase, IHasExtraProperties + [EventName("EShopOnAbp.Payment.Completed")] + public class PaymentRequestCompletedEto : EtoBase, IHasExtraProperties { public Guid PaymentRequestId { get; set; } + + public string Currency { get; set; } + + public string BuyerId { get; set; } + + public PaymentRequestState State { get; set; } + + public ICollection Products { get; set; } = new List(); + public ExtraPropertyDictionary ExtraProperties { get; set; } } } \ No newline at end of file diff --git a/services/payment/src/EShopOnAbp.PaymentService.Domain.Shared/PaymentRequests/PaymentRequestFailedEto.cs b/services/payment/src/EShopOnAbp.PaymentService.Domain.Shared/PaymentRequests/PaymentRequestFailedEto.cs index 7723aff2..f2d36c8c 100644 --- a/services/payment/src/EShopOnAbp.PaymentService.Domain.Shared/PaymentRequests/PaymentRequestFailedEto.cs +++ b/services/payment/src/EShopOnAbp.PaymentService.Domain.Shared/PaymentRequests/PaymentRequestFailedEto.cs @@ -6,7 +6,7 @@ using Volo.Abp.EventBus; namespace EShopOnAbp.PaymentService { [Serializable] - [EventName("Payment.Completed")] + [EventName("EShopOnAbp.Payment.Completed")] public class PaymentRequestFailedEto : EtoBase, IHasExtraProperties { public Guid PaymentRequestId { get; set; } diff --git a/services/payment/src/EShopOnAbp.PaymentService.Domain.Shared/PaymentRequests/PaymentRequestProductEto.cs b/services/payment/src/EShopOnAbp.PaymentService.Domain.Shared/PaymentRequests/PaymentRequestProductEto.cs new file mode 100644 index 00000000..f15ebd94 --- /dev/null +++ b/services/payment/src/EShopOnAbp.PaymentService.Domain.Shared/PaymentRequests/PaymentRequestProductEto.cs @@ -0,0 +1,18 @@ +using System; + +namespace EShopOnAbp.PaymentService.PaymentRequests +{ + [Serializable] + public class PaymentRequestProductEto + { + public string ReferenceId { get; set; } + + public string Name { get; set; } + + public decimal UnitPrice { get; set; } + + public int Quantity { get; set; } + + public decimal TotalPrice { get; set; } + } +} diff --git a/services/payment/src/EShopOnAbp.PaymentService.Domain/PaymentRequests/PaymentRequest.cs b/services/payment/src/EShopOnAbp.PaymentService.Domain/PaymentRequests/PaymentRequest.cs index b06df627..b487ea7e 100644 --- a/services/payment/src/EShopOnAbp.PaymentService.Domain/PaymentRequests/PaymentRequest.cs +++ b/services/payment/src/EShopOnAbp.PaymentService.Domain/PaymentRequests/PaymentRequest.cs @@ -1,6 +1,7 @@ using JetBrains.Annotations; using System; using System.Collections.Generic; +using System.Linq; using Volo.Abp; using Volo.Abp.Domain.Entities.Auditing; @@ -48,6 +49,10 @@ namespace EShopOnAbp.PaymentService.PaymentRequests AddDistributedEvent(new PaymentRequestCompletedEto { PaymentRequestId = Id, + BuyerId = BuyerId, + Currency = Currency, + State = State, + Products = Products.Select(MapProductToEto).ToList(), ExtraProperties = ExtraProperties }); } @@ -69,5 +74,17 @@ namespace EShopOnAbp.PaymentService.PaymentRequests ExtraProperties = ExtraProperties }); } + + private static PaymentRequestProductEto MapProductToEto(PaymentRequestProduct product) + { + return new PaymentRequestProductEto + { + Name = product.Name, + Quantity = product.Quantity, + ReferenceId = product.ReferenceId, + TotalPrice = product.TotalPrice, + UnitPrice = product.UnitPrice, + }; + } } } diff --git a/services/payment/src/EShopOnAbp.PaymentService.Domain/PaymentRequests/PaymentRequestProduct.cs b/services/payment/src/EShopOnAbp.PaymentService.Domain/PaymentRequests/PaymentRequestProduct.cs index 024bfe7d..91e8d431 100644 --- a/services/payment/src/EShopOnAbp.PaymentService.Domain/PaymentRequests/PaymentRequestProduct.cs +++ b/services/payment/src/EShopOnAbp.PaymentService.Domain/PaymentRequests/PaymentRequestProduct.cs @@ -19,6 +19,7 @@ namespace EShopOnAbp.PaymentService.PaymentRequests public decimal TotalPrice { get; set; } public PaymentRequestProduct( + Guid id, Guid paymentRequestId, [NotNull] string name, decimal unitPrice, @@ -26,6 +27,7 @@ namespace EShopOnAbp.PaymentService.PaymentRequests decimal totalPrice, [CanBeNull] string referenceId = null) { + Id = id; PaymentRequestId = paymentRequestId; Name = name; UnitPrice = unitPrice; diff --git a/services/payment/src/EShopOnAbp.PaymentService.EntityFrameworkCore/PaymentRequests/EfCorePaymentRequestRepository.cs b/services/payment/src/EShopOnAbp.PaymentService.EntityFrameworkCore/PaymentRequests/EfCorePaymentRequestRepository.cs index 8c1acc3c..8d5cffa7 100644 --- a/services/payment/src/EShopOnAbp.PaymentService.EntityFrameworkCore/PaymentRequests/EfCorePaymentRequestRepository.cs +++ b/services/payment/src/EShopOnAbp.PaymentService.EntityFrameworkCore/PaymentRequests/EfCorePaymentRequestRepository.cs @@ -1,5 +1,8 @@ using EShopOnAbp.PaymentService.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; using System; +using System.Linq; +using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; @@ -18,5 +21,11 @@ namespace EShopOnAbp.PaymentService.PaymentRequests { } + + public override async Task> WithDetailsAsync() + { + return (await base.WithDetailsAsync()) + .Include(p => p.Products); + } } } diff --git a/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Client/ClientProxies/PaymentRequestClientProxy.Generated.cs b/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Client/ClientProxies/PaymentRequestClientProxy.Generated.cs new file mode 100644 index 00000000..c59692b4 --- /dev/null +++ b/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Client/ClientProxies/PaymentRequestClientProxy.Generated.cs @@ -0,0 +1,50 @@ +// This file is automatically generated by ABP framework to use MVC Controllers from CSharp +using System; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Http.Client; +using Volo.Abp.Http.Modeling; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Http.Client.ClientProxying; +using EShopOnAbp.PaymentService.PaymentRequests; + +// ReSharper disable once CheckNamespace +namespace EShopOnAbp.PaymentService.Controllers.ClientProxies +{ + [Dependency(ReplaceServices = true)] + [ExposeServices(typeof(IPaymentRequestAppService), typeof(PaymentRequestClientProxy))] + public partial class PaymentRequestClientProxy : ClientProxyBase, IPaymentRequestAppService + { + public virtual async Task CompleteAsync(string token) + { + return await RequestAsync(nameof(CompleteAsync), new ClientProxyRequestTypeValue + { + { typeof(string), token } + }); + } + + public virtual async Task CreateAsync(PaymentRequestCreationDto input) + { + return await RequestAsync(nameof(CreateAsync), new ClientProxyRequestTypeValue + { + { typeof(PaymentRequestCreationDto), input } + }); + } + + public virtual async Task HandleWebhookAsync(string payload) + { + return await RequestAsync(nameof(HandleWebhookAsync), new ClientProxyRequestTypeValue + { + { typeof(string), payload } + }); + } + + public virtual async Task StartAsync(PaymentRequestStartDto input) + { + return await RequestAsync(nameof(StartAsync), new ClientProxyRequestTypeValue + { + { typeof(PaymentRequestStartDto), input } + }); + } + } +} diff --git a/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Client/ClientProxies/PaymentRequestClientProxy.cs b/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Client/ClientProxies/PaymentRequestClientProxy.cs new file mode 100644 index 00000000..7e7c5f7d --- /dev/null +++ b/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Client/ClientProxies/PaymentRequestClientProxy.cs @@ -0,0 +1,8 @@ +// This file is part of PaymentRequestClientProxy, you can customize it here +// ReSharper disable once CheckNamespace +namespace EShopOnAbp.PaymentService.Controllers.ClientProxies +{ + public partial class PaymentRequestClientProxy + { + } +} diff --git a/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Client/ClientProxies/PaymentService-generate-proxy.json b/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Client/ClientProxies/PaymentService-generate-proxy.json deleted file mode 100644 index cf60aca6..00000000 --- a/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Client/ClientProxies/PaymentService-generate-proxy.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "modules": { - "PaymentService": { - "rootPath": "PaymentService", - "remoteServiceName": "PaymentService", - "controllers": { - "EShopOnAbp.PaymentService.Samples.SampleController": { - "controllerName": "Sample", - "controllerGroupName": "Sample", - "type": "EShopOnAbp.PaymentService.Samples.SampleController", - "interfaces": [ - { - "type": "EShopOnAbp.PaymentService.Samples.ISampleAppService" - } - ], - "actions": { - "GetAsync": { - "uniqueName": "GetAsync", - "name": "GetAsync", - "httpMethod": "GET", - "url": "api/PaymentService/sample", - "supportedVersions": [], - "parametersOnMethod": [], - "parameters": [], - "returnValue": { - "type": "EShopOnAbp.PaymentService.Samples.SampleDto", - "typeSimple": "EShopOnAbp.PaymentService.Samples.SampleDto" - }, - "allowAnonymous": null, - "implementFrom": "EShopOnAbp.PaymentService.Samples.ISampleAppService" - }, - "GetAuthorizedAsync": { - "uniqueName": "GetAuthorizedAsync", - "name": "GetAuthorizedAsync", - "httpMethod": "GET", - "url": "api/PaymentService/sample/authorized", - "supportedVersions": [], - "parametersOnMethod": [], - "parameters": [], - "returnValue": { - "type": "EShopOnAbp.PaymentService.Samples.SampleDto", - "typeSimple": "EShopOnAbp.PaymentService.Samples.SampleDto" - }, - "allowAnonymous": false, - "implementFrom": "EShopOnAbp.PaymentService.Samples.ISampleAppService" - } - } - } - } - } - }, - "types": {} -} \ No newline at end of file diff --git a/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Client/ClientProxies/SampleClientProxy.Generated.cs b/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Client/ClientProxies/SampleClientProxy.Generated.cs deleted file mode 100644 index c1eda3e6..00000000 --- a/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Client/ClientProxies/SampleClientProxy.Generated.cs +++ /dev/null @@ -1,15 +0,0 @@ -// This file is automatically generated by ABP framework to use MVC Controllers from CSharp -using System; -using System.Threading.Tasks; -using Volo.Abp.Application.Dtos; -using Volo.Abp.Http.Client; -using Volo.Abp.Http.Modeling; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Http.Client.ClientProxying; -using EShopOnAbp.PaymentService.Samples; - -// ReSharper disable once CheckNamespace -namespace EShopOnAbp.PaymentService.Samples.ClientProxies -{ - -} diff --git a/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Client/ClientProxies/SampleClientProxy.cs b/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Client/ClientProxies/SampleClientProxy.cs deleted file mode 100644 index 63e60b1d..00000000 --- a/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Client/ClientProxies/SampleClientProxy.cs +++ /dev/null @@ -1,8 +0,0 @@ -// This file is part of SampleClientProxy, you can customize it here -// ReSharper disable once CheckNamespace -namespace EShopOnAbp.PaymentService.Samples.ClientProxies -{ - public partial class SampleClientProxy - { - } -} diff --git a/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Client/ClientProxies/payment-generate-proxy.json b/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Client/ClientProxies/payment-generate-proxy.json new file mode 100644 index 00000000..7f45f280 --- /dev/null +++ b/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Client/ClientProxies/payment-generate-proxy.json @@ -0,0 +1,171 @@ +{ + "modules": { + "payment": { + "rootPath": "payment", + "remoteServiceName": "PaymentService", + "controllers": { + "EShopOnAbp.PaymentService.Controllers.PaymentRequestController": { + "controllerName": "PaymentRequest", + "controllerGroupName": "PaymentRequest", + "type": "EShopOnAbp.PaymentService.Controllers.PaymentRequestController", + "interfaces": [ + { + "type": "EShopOnAbp.PaymentService.PaymentRequests.IPaymentRequestAppService" + } + ], + "actions": { + "CompleteAsyncByToken": { + "uniqueName": "CompleteAsyncByToken", + "name": "CompleteAsync", + "httpMethod": "POST", + "url": "api/payment/requests/complete", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "token", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "token", + "name": "token", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + } + ], + "returnValue": { + "type": "EShopOnAbp.PaymentService.PaymentRequests.PaymentRequestDto", + "typeSimple": "EShopOnAbp.PaymentService.PaymentRequests.PaymentRequestDto" + }, + "allowAnonymous": null, + "implementFrom": "EShopOnAbp.PaymentService.PaymentRequests.IPaymentRequestAppService" + }, + "CreateAsyncByInput": { + "uniqueName": "CreateAsyncByInput", + "name": "CreateAsync", + "httpMethod": "POST", + "url": "api/payment/requests", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "EShopOnAbp.PaymentService.PaymentRequests.PaymentRequestCreationDto, EShopOnAbp.PaymentService.Application.Contracts", + "type": "EShopOnAbp.PaymentService.PaymentRequests.PaymentRequestCreationDto", + "typeSimple": "EShopOnAbp.PaymentService.PaymentRequests.PaymentRequestCreationDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "jsonName": null, + "type": "EShopOnAbp.PaymentService.PaymentRequests.PaymentRequestCreationDto", + "typeSimple": "EShopOnAbp.PaymentService.PaymentRequests.PaymentRequestCreationDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "EShopOnAbp.PaymentService.PaymentRequests.PaymentRequestDto", + "typeSimple": "EShopOnAbp.PaymentService.PaymentRequests.PaymentRequestDto" + }, + "allowAnonymous": null, + "implementFrom": "EShopOnAbp.PaymentService.PaymentRequests.IPaymentRequestAppService" + }, + "HandleWebhookAsyncByPayload": { + "uniqueName": "HandleWebhookAsyncByPayload", + "name": "HandleWebhookAsync", + "httpMethod": "POST", + "url": "api/payment/requests/webhook", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "payload", + "typeAsString": "System.String, System.Private.CoreLib", + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "payload", + "name": "payload", + "jsonName": null, + "type": "System.String", + "typeSimple": "string", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "ModelBinding", + "descriptorName": "" + } + ], + "returnValue": { + "type": "System.Boolean", + "typeSimple": "boolean" + }, + "allowAnonymous": null, + "implementFrom": "EShopOnAbp.PaymentService.PaymentRequests.IPaymentRequestAppService" + }, + "StartAsyncByInput": { + "uniqueName": "StartAsyncByInput", + "name": "StartAsync", + "httpMethod": "POST", + "url": "api/payment/requests/start", + "supportedVersions": [], + "parametersOnMethod": [ + { + "name": "input", + "typeAsString": "EShopOnAbp.PaymentService.PaymentRequests.PaymentRequestStartDto, EShopOnAbp.PaymentService.Application.Contracts", + "type": "EShopOnAbp.PaymentService.PaymentRequests.PaymentRequestStartDto", + "typeSimple": "EShopOnAbp.PaymentService.PaymentRequests.PaymentRequestStartDto", + "isOptional": false, + "defaultValue": null + } + ], + "parameters": [ + { + "nameOnMethod": "input", + "name": "input", + "jsonName": null, + "type": "EShopOnAbp.PaymentService.PaymentRequests.PaymentRequestStartDto", + "typeSimple": "EShopOnAbp.PaymentService.PaymentRequests.PaymentRequestStartDto", + "isOptional": false, + "defaultValue": null, + "constraintTypes": null, + "bindingSourceId": "Body", + "descriptorName": "" + } + ], + "returnValue": { + "type": "EShopOnAbp.PaymentService.PaymentRequests.PaymentRequestStartResultDto", + "typeSimple": "EShopOnAbp.PaymentService.PaymentRequests.PaymentRequestStartResultDto" + }, + "allowAnonymous": null, + "implementFrom": "EShopOnAbp.PaymentService.PaymentRequests.IPaymentRequestAppService" + } + } + } + } + } + }, + "types": {} +} \ No newline at end of file diff --git a/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/PaymentServiceHttpApiHostModule.cs b/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/PaymentServiceHttpApiHostModule.cs index 497eca00..5512eb0d 100644 --- a/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/PaymentServiceHttpApiHostModule.cs +++ b/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/PaymentServiceHttpApiHostModule.cs @@ -1,5 +1,6 @@ using EShopOnAbp.PaymentService.DbMigrations; using EShopOnAbp.PaymentService.EntityFrameworkCore; +using EShopOnAbp.PaymentService.PayPal; using EShopOnAbp.Shared.Hosting.AspNetCore; using EShopOnAbp.Shared.Hosting.Microservices; using Microsoft.AspNetCore.Builder; @@ -25,6 +26,8 @@ namespace EShopOnAbp.PaymentService { public override void ConfigureServices(ServiceConfigurationContext context) { + Microsoft.IdentityModel.Logging.IdentityModelEventSource.ShowPII = true; + var hostingEnvironment = context.Services.GetHostingEnvironment(); var configuration = context.Services.GetConfiguration(); diff --git a/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/appsettings.json b/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/appsettings.json index a196a0ba..acec763a 100644 --- a/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/appsettings.json +++ b/services/payment/src/EShopOnAbp.PaymentService.HttpApi.Host/appsettings.json @@ -40,5 +40,12 @@ }, "ElasticSearch": { "Url": "http://localhost:9200" + }, + "Payment": { + "PayPal": { + "ClientId": "PAYPAL_CLIENT_ID", + "Secret": "PAYPAL_SECRET", + "Environment": "Sandbox" + } } } \ No newline at end of file diff --git a/shared/EShopOnAbp.Shared.Localization/Localization/EShopOnAbp/en.json b/shared/EShopOnAbp.Shared.Localization/Localization/EShopOnAbp/en.json index 00b556ae..c6389ed1 100644 --- a/shared/EShopOnAbp.Shared.Localization/Localization/EShopOnAbp/en.json +++ b/shared/EShopOnAbp.Shared.Localization/Localization/EShopOnAbp/en.json @@ -6,6 +6,7 @@ "YourBasket": "Your Basket", "Total": "Total", "OurProducts": "Our Products", + "CatalogServiceNotAvailable": "Catalog Service is unavailable right now! Try again later...", "StockCount": "Stock Count", "RemoveFromBasket": "Remove from basket", "CompletePurchase": "Complete purchase", diff --git a/shared/EShopOnAbp.Shared.Localization/Localization/EShopOnAbp/tr.json b/shared/EShopOnAbp.Shared.Localization/Localization/EShopOnAbp/tr.json index 159c5c5e..7b0c9f7e 100644 --- a/shared/EShopOnAbp.Shared.Localization/Localization/EShopOnAbp/tr.json +++ b/shared/EShopOnAbp.Shared.Localization/Localization/EShopOnAbp/tr.json @@ -6,6 +6,7 @@ "YourBasket": "Sepetiniz", "Total": "Toplam", "OurProducts": "Ürünlerimiz", + "CatalogServiceNotAvailable": "Ürün servisine şu anda ulaşılamıyor! Lütfen sonra tekrar deneyiniz...", "StockCount": "Stokta", "RemoveFromBasket": "Sepetten kaldır", "CompletePurchase": "Alışverişi tamamla",