-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #107 from commercetools/CheckoutApp-Example
Checkout App Example
- Loading branch information
Showing
83 changed files
with
41,248 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
commercetools.Sdk/Examples/commercetools.Api.CheckoutApp/Controllers/BaseController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
using System.Threading.Tasks; | ||
using commercetools.Api.CheckoutApp.Models; | ||
using commercetools.Api.CheckoutApp.Services; | ||
using commercetools.Base.Client; | ||
using commercetools.Base.Client.Tokens; | ||
using Microsoft.AspNetCore.Mvc; | ||
|
||
namespace commercetools.Api.CheckoutApp.Controllers | ||
{ | ||
public class BaseController : Controller | ||
{ | ||
protected readonly IClient _client; | ||
protected readonly IUserCredentialsStoreManager _userCredentialsStore; | ||
protected readonly MeServices _meServices; | ||
protected readonly CartServices _cartServices; | ||
|
||
public BaseController(IClient client, | ||
IUserCredentialsStoreManager userCredentialsStore, | ||
MeServices meServices, | ||
CartServices cartServices) | ||
{ | ||
this._client = client; | ||
this._userCredentialsStore = userCredentialsStore; | ||
this._meServices = meServices; | ||
this._cartServices = cartServices; | ||
} | ||
|
||
public async Task<CustomerProfileViewModel> GetCurrentCustomerProfile() | ||
{ | ||
var profileViewModel = new CustomerProfileViewModel(); | ||
var meProfile = await _meServices.GetMyProfile(); | ||
profileViewModel.ActiveCart = await _cartServices.GetActiveCartViewModel(); | ||
if (meProfile != null) | ||
{ | ||
var baseInfo = new BaseCustomer(meProfile); | ||
profileViewModel.Customer = baseInfo; | ||
} | ||
|
||
return profileViewModel; | ||
} | ||
} | ||
} |
50 changes: 50 additions & 0 deletions
50
commercetools.Sdk/Examples/commercetools.Api.CheckoutApp/Controllers/HomeController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
using System.Threading.Tasks; | ||
using commercetools.Api.CheckoutApp.Models; | ||
using commercetools.Api.CheckoutApp.Services; | ||
using commercetools.Api.Models.Me; | ||
using commercetools.Api.Models.Products; | ||
using commercetools.Base.Client; | ||
using commercetools.Base.Client.Tokens; | ||
using Microsoft.AspNetCore.Mvc; | ||
using Microsoft.Extensions.Configuration; | ||
|
||
namespace commercetools.Api.CheckoutApp.Controllers | ||
{ | ||
public class HomeController : BaseController | ||
{ | ||
private readonly ProductServices _productServices; | ||
public HomeController(IClient client, | ||
IUserCredentialsStoreManager userCredentialsStore, | ||
MeServices meServices, | ||
CartServices cartServices,ProductServices productServices) | ||
: base(client, userCredentialsStore, meServices, cartServices) | ||
{ | ||
this._productServices = productServices; | ||
} | ||
|
||
public async Task<IActionResult> Index() | ||
{ | ||
var products = await _productServices.GetAllProducts(); | ||
var customerProfile = await GetCurrentCustomerProfile(); | ||
var homeModel = new HomeViewModel(products, customerProfile); | ||
return View(homeModel); | ||
} | ||
|
||
public async Task<IActionResult> AddToCart(Product product) | ||
{ | ||
var cartDraft = GetCartDraft(); | ||
var cart = await _cartServices.CreateCartForCurrentCustomer(cartDraft); | ||
await _cartServices.AddProductToCurrentActiveCart(cart, product); | ||
return RedirectToAction("Index"); | ||
} | ||
|
||
private IMyCartDraft GetCartDraft() | ||
{ | ||
var cartDraft = new MyCartDraft | ||
{ | ||
Currency = "EUR", | ||
}; | ||
return cartDraft; | ||
} | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
commercetools.Sdk/Examples/commercetools.Api.CheckoutApp/Controllers/MeController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
using System.Threading.Tasks; | ||
using commercetools.Api.CheckoutApp.Models; | ||
using commercetools.Api.CheckoutApp.Services; | ||
using commercetools.Base.Client; | ||
using commercetools.Base.Client.Tokens; | ||
using Microsoft.AspNetCore.Mvc; | ||
|
||
namespace commercetools.Api.CheckoutApp.Controllers | ||
{ | ||
public class MeController : BaseController | ||
{ | ||
public MeController(IClient client, | ||
MeServices meServices, | ||
CartServices cartServices, | ||
IUserCredentialsStoreManager userCredentialsStoreManager) | ||
: base(client, userCredentialsStoreManager, meServices, cartServices) | ||
{ | ||
} | ||
|
||
public async Task<IActionResult> SignIn() | ||
{ | ||
var customerProfile = await GetCurrentCustomerProfile(); | ||
return View(new SignInCustomerViewModel(customerProfile)); | ||
} | ||
[HttpPost] | ||
[ValidateAntiForgeryToken] | ||
public async Task<IActionResult> SignIn(SignInCustomerViewModel model) | ||
{ | ||
if (ModelState.IsValid) | ||
{ | ||
var signInResult = await _meServices.SignIn(model.Email, model.Password); | ||
if (signInResult.IsValidCredentials) | ||
{ | ||
//after signin, the anonymous access token and refresh token are immediately invalid | ||
//we need to get new access and refresh tokens with the password flow | ||
_userCredentialsStore.StoreUserCredentialsAndClearToken(model.Email, model.Password); | ||
return RedirectToAction("Index", "MyCart"); | ||
} | ||
|
||
else | ||
{ | ||
model.ResetAfterLoginFailed(); | ||
} | ||
} | ||
return View("SignIn", model); | ||
} | ||
|
||
public async Task<IActionResult> Logout() | ||
{ | ||
_userCredentialsStore.ClearCredentialsAndToken(); | ||
return RedirectToAction("Index", "Home"); | ||
} | ||
} | ||
} |
31 changes: 31 additions & 0 deletions
31
commercetools.Sdk/Examples/commercetools.Api.CheckoutApp/Controllers/MyCartController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
using System.Threading.Tasks; | ||
using commercetools.Api.CheckoutApp.Services; | ||
using commercetools.Base.Client; | ||
using commercetools.Base.Client.Tokens; | ||
using Microsoft.AspNetCore.Mvc; | ||
|
||
namespace commercetools.Api.CheckoutApp.Controllers | ||
{ | ||
public class MyCartController : BaseController | ||
{ | ||
public MyCartController(IClient client, | ||
CartServices cartServices, | ||
MeServices meServices, | ||
IUserCredentialsStoreManager userCredentialsStoreManager) | ||
: base(client, userCredentialsStoreManager, meServices, cartServices) | ||
{ | ||
} | ||
|
||
public async Task<IActionResult> Index() | ||
{ | ||
var customerProfile = await GetCurrentCustomerProfile(); | ||
return View(customerProfile); | ||
} | ||
|
||
public async Task<IActionResult> Delete(string lineItemId) | ||
{ | ||
var myCart = await _cartServices.DeleteLineItem(lineItemId); | ||
return RedirectToAction("Index"); | ||
} | ||
} | ||
} |
123 changes: 123 additions & 0 deletions
123
commercetools.Sdk/Examples/commercetools.Api.CheckoutApp/Extensions/ClientInjectionSetup.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
using System; | ||
using System.Net.Http; | ||
using commercetools.Api.Models.Errors; | ||
using commercetools.Base.Client; | ||
using commercetools.Base.Client.Tokens; | ||
using commercetools.Sdk.Api; | ||
using commercetools.Sdk.Api.Serialization; | ||
using Microsoft.AspNetCore.Http; | ||
using Microsoft.Extensions.Configuration; | ||
using Microsoft.Extensions.DependencyInjection; | ||
|
||
namespace commercetools.Api.CheckoutApp.Extensions | ||
{ | ||
public static class ClientInjectionSetup | ||
{ | ||
/// <summary> | ||
/// Inject Scoped Client per each Request | ||
/// </summary> | ||
/// <param name="services">services container</param> | ||
/// <param name="configuration"></param> | ||
/// <param name="clientName"></param> | ||
public static IHttpClientBuilder UseCommercetoolsScopedClient(this IServiceCollection services, | ||
IConfiguration configuration, | ||
string clientName) | ||
{ | ||
services.UseCommercetoolsApiSerialization(); | ||
services.UseScopedCredentialsStoreManagers(clientName, configuration); | ||
services.UseScopedTokenProvider(clientName, configuration); | ||
|
||
//Create Client with proper TokenProvider as scoped service | ||
services.AddScoped(serviceProvider => | ||
{ | ||
var clientConfiguration = configuration.GetSection(clientName).Get<ClientConfiguration>(); | ||
var tokenProvider = serviceProvider.GetService<ITokenProvider>(); | ||
var client = ClientFactory.Create(clientName, clientConfiguration, | ||
serviceProvider.GetService<IHttpClientFactory>(), | ||
serviceProvider.GetService<SerializerService>(), | ||
tokenProvider); | ||
client.Name = clientName; | ||
return client; | ||
}); | ||
|
||
//Add the httpClient and setup the Middlewares | ||
return services.SetupClient(clientName, | ||
errorTypeMapper => typeof(ErrorResponse), | ||
serviceProvider => serviceProvider.GetService<SerializerService>()); | ||
} | ||
|
||
|
||
/// <summary> | ||
/// Inject two instance, one for IAnonymousCredentialsStoreManager and other for IUserCredentialsStoreManager | ||
/// </summary> | ||
/// <param name="services"></param> | ||
/// <param name="clientName"></param> | ||
/// <param name="configuration"></param> | ||
public static void UseScopedCredentialsStoreManagers(this IServiceCollection services, | ||
string clientName, | ||
IConfiguration configuration) | ||
{ | ||
services.AddScoped<IAnonymousCredentialsStoreManager>(serviceProvider => | ||
{ | ||
var inCookiesStoreManager = serviceProvider.GetService<InCookiesStoreManager>(); | ||
var inSessionStoreManager = serviceProvider.GetService<InSessionStoreManager>(); | ||
var anonymousIdStore = new InSessionAnonymousCredentialsStoreManager(inSessionStoreManager,inCookiesStoreManager); | ||
return anonymousIdStore; | ||
}); | ||
services.AddScoped<IUserCredentialsStoreManager>(serviceProvider => | ||
{ | ||
var inCookiesStoreManager = serviceProvider.GetService<InCookiesStoreManager>(); | ||
var inSessionStoreManager = serviceProvider.GetService<InSessionStoreManager>(); | ||
var userCredentialsStore = new InSessionUserCredentialsStoreManager(inSessionStoreManager,inCookiesStoreManager); | ||
return userCredentialsStore; | ||
}); | ||
} | ||
|
||
/// <summary> | ||
/// Inject scoped tokenProvider based on current tokenFlow | ||
/// </summary> | ||
/// <param name="services"></param> | ||
/// <param name="clientName"></param> | ||
/// <param name="configuration"></param> | ||
public static void UseScopedTokenProvider(this IServiceCollection services, | ||
string clientName, | ||
IConfiguration configuration) | ||
{ | ||
services.AddScoped(serviceProvider => | ||
{ | ||
var clientConfiguration = configuration.GetSection(clientName).Get<ClientConfiguration>(); | ||
var httpClientFactory = serviceProvider.GetService<IHttpClientFactory>(); | ||
var currentTokenFlow = GetCurrentTokenFlow(serviceProvider); | ||
ITokenProvider tokenProvider = null; | ||
if (currentTokenFlow == TokenFlow.Password) | ||
{ | ||
var userCredentialsStore = serviceProvider.GetService<IUserCredentialsStoreManager>(); | ||
tokenProvider = TokenProviderFactory.CreatePasswordTokenProvider( | ||
clientConfiguration, httpClientFactory, userCredentialsStore); | ||
} | ||
else | ||
{ | ||
var anonymousIdStore = serviceProvider.GetService<IAnonymousCredentialsStoreManager>(); | ||
if (anonymousIdStore != null && anonymousIdStore.Token == null) | ||
{ | ||
anonymousIdStore.AnonymousId = Guid.NewGuid().ToString(); | ||
} | ||
tokenProvider = TokenProviderFactory.CreateAnonymousSessionTokenProvider( | ||
clientConfiguration, httpClientFactory, anonymousIdStore); | ||
} | ||
return tokenProvider; | ||
}); | ||
} | ||
|
||
public static TokenFlow GetCurrentTokenFlow(IServiceProvider serviceProvider) | ||
{ | ||
var tokenFlow = TokenFlow.AnonymousSession; | ||
var userCredentialsStore = serviceProvider.GetService<IUserCredentialsStoreManager>(); | ||
if (userCredentialsStore != null && !string.IsNullOrEmpty(userCredentialsStore.Username)) | ||
{ | ||
tokenFlow = TokenFlow.Password; | ||
} | ||
return tokenFlow; | ||
} | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
commercetools.Sdk/Examples/commercetools.Api.CheckoutApp/Extensions/InCookiesStoreManager.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
using System; | ||
using commercetools.Api.CheckoutApp.Services; | ||
using Microsoft.AspNetCore.Http; | ||
|
||
namespace commercetools.Api.CheckoutApp.Extensions | ||
{ | ||
public class InCookiesStoreManager | ||
{ | ||
private readonly IHttpContextAccessor _httpContextAccessor; | ||
|
||
public InCookiesStoreManager(IHttpContextAccessor httpContextAccessor) | ||
{ | ||
this._httpContextAccessor = httpContextAccessor; | ||
} | ||
|
||
public void SetInCookie(string key,string value) | ||
{ | ||
var response = _httpContextAccessor?.HttpContext?.Response; | ||
response?.Cookies.Append(key, value, | ||
new CookieOptions() | ||
{ | ||
Path = "/", | ||
Secure = true, | ||
HttpOnly = true, | ||
Expires = DateTimeOffset.Now.AddDays(Settings.ExpireInDays) | ||
}); | ||
} | ||
public string GetFromCookie(string key) | ||
{ | ||
var request = _httpContextAccessor?.HttpContext?.Request; | ||
return request?.Cookies[key]; | ||
} | ||
public void ClearCookie(string key) | ||
{ | ||
var response = _httpContextAccessor?.HttpContext?.Response; | ||
response?.Cookies.Delete(key); | ||
} | ||
} | ||
} |
Oops, something went wrong.