Create a new Customer Entity in Sitecore Commerce 9.x

Akshay Sura - Partner

14 Mar 2019

Share on social media

If you are looking to create a new customer entity in Sitecore Commerce 9.x, this is the post for you. I spent some time searching for code using my friend Google but couldn’t find much. Hope this helps.

First, setup a new pipeline which accepts an object with values to create a new customer, make sure the output is of type Customer. This is crucial as we will pass the resulting customer to the persist block.

namespace Plugin.YOURNAMESPACE.Pipelines { using Sitecore.Commerce.Core; using Sitecore.Framework.Pipelines; using Plugin.YOURNAMESPACE.Models; using Sitecore.Commerce.Plugin.Customers; [PipelineDisplayName("CreateCustomerMinionPipeline")] public interface ICreateCustomerMinionPipeline : IPipeline<SOMEOBJECTWITHCUSTOMERDATA, Customer, CommercePipelineExecutionContext>, IPipelineBlock<SOMEOBJECTWITHCUSTOMERDATA, Customer, CommercePipelineExecutionContext>, IPipelineBlock, IPipeline { } } namespace Plugin.YOURNAMESPACE.Pipelines { using Microsoft.Extensions.Logging; using Sitecore.Commerce.Core; using Sitecore.Framework.Pipelines; using Plugin.YOURNAMESPACE.Models; using Sitecore.Commerce.Plugin.Customers; public class CreateCustomerMinionPipeline: CommercePipeline<SOMEOBJECTWITHCUSTOMERDATA, Customer>, ICreateCustomerMinionPipeline, IPipeline<SOMEOBJECTWITHCUSTOMERDATA, Customer, CommercePipelineExecutionContext>, IPipelineBlock<SOMEOBJECTWITHCUSTOMERDATA, Customer, CommercePipelineExecutionContext>, IPipelineBlock, IPipeline { public CreateCustomerMinionPipeline(IPipelineConfiguration<ICreateCustomerMinionPipeline> configuration, ILoggerFactory loggerFactory) : base(configuration, loggerFactory) { } } }

Next, create a new block to create the customer entity.

namespace Plugin.YOURNAMESPACE.Pipelines.Blocks { using Sitecore.Commerce.Core; using Sitecore.Framework.Pipelines; using System.Threading.Tasks; using Plugin.YOURNAMESPACE.Models; using Microsoft.Extensions.Logging; using System; using Sitecore.Commerce.Plugin.Customers; using Sitecore.Commerce.Plugin.ManagedLists; using System.Collections.Generic; using Sitecore.Commerce.EntityViews; [PipelineDisplayName("CreateCustomerMinionPipeline.CreateCustomerBlock")] public class CreateCustomersBlock : PipelineBlock<SOMEOBJECTWITHCUSTOMERDATA, Customer, CommercePipelineExecutionContext> { private readonly CommerceCommander _commerceCommander; private readonly FindEntityPipeline _findEntityPipeline; private readonly CreateCustomerPipeline _createCustomerPipeline; private readonly PersistEntityPipeline _persistEntityPipeline; public CreateCustomersBlock (CommerceCommander commerceCommander, FindEntityPipeline findEntityPipeline, CreateCustomerPipeline createCustomerPipeline, PersistEntityPipeline persistEntityPipeline) { _commerceCommander = commerceCommander; _findEntityPipeline = findEntityPipeline; _createCustomerPipeline = createCustomerPipeline; _persistEntityPipeline = persistEntityPipeline; } public override async Task<Customer> Run(SOMEOBJECTWITHCUSTOMERDATA arg, CommercePipelineExecutionContext context) { var propertiesPolicy = context.GetPolicy<CustomerPropertiesPolicy>(); var customer = new Customer(); string friendlyId = Guid.NewGuid().ToString("N"); customer.AccountNumber = friendlyId; customer.FriendlyId = friendlyId; customer.Id = $"{CommerceEntity.IdPrefix<Customer>()}{friendlyId}"; customer.Email = arg.CustomerEmail; customer.UserName = string.Concat("CommerceUsers\\", customer.Email); customer.AccountStatus = context.GetPolicy<KnownCustomersStatusesPolicy>()?.ActiveAccount; customer.FirstName = arg.CustomerFirstName; customer.LastName = arg.CustomerLastName; var details = new EntityView { Name = "Details" }; details.Properties.Add(new ViewProperty { Name = propertiesPolicy.FirstName, RawValue = arg.CustomerFirstName }); details.Properties.Add(new ViewProperty { Name = propertiesPolicy.LastName, RawValue = arg.CustomerLastName }); details.Properties.Add(new ViewProperty { Name = propertiesPolicy.AccountNumber, RawValue = friendlyId }); //Add to the customers index and the Customer lists, this will show up in the Biz Tools customer.SetComponent(new ListMembershipsComponent { Memberships = new List<string> { CommerceEntity.ListName<Customer>(), context.GetPolicy<KnownCustomersListsPolicy>().RecentCustomers, "CustomersIndex", "Customers" } }); customer.GetComponent<CustomerDetailsComponent>()?.View.ChildViews.Add(details); string billingId = Guid.NewGuid().ToString("D"); var billingAddressComponent = new AddressComponent { Name = "Billing" }; billingAddressComponent.Id = billingId; billingAddressComponent.Party.FirstName = arg.CustomerFirstName; billingAddressComponent.Party.LastName = arg.CustomerLastName; billingAddressComponent.Party.State = arg.BillingInfo.BillingState; billingAddressComponent.Party.StateCode = arg.BillingInfo.BillingState; billingAddressComponent.Party.CountryCode = arg.BillingInfo.BillingCountry; billingAddressComponent.Party.Country = arg.BillingInfo.BillingCountry; billingAddressComponent.Party.City = arg.BillingInfo.BillingCity; billingAddressComponent.Party.Address1 = arg.BillingInfo.BillingAddress; billingAddressComponent.Party.ZipPostalCode = arg.BillingInfo.BillingZip; billingAddressComponent.Party.AddressName = "Billing"; billingAddressComponent.Party.IsPrimary = true; //add address components to the customer customer.Components.Add(billingAddressComponent); string shippingId = Guid.NewGuid().ToString("D"); var shippingAddressComponent = new AddressComponent { Name = "Shipping" }; shippingAddressComponent.Id = shippingId; shippingAddressComponent.Party.FirstName = arg.CustomerFirstName; shippingAddressComponent.Party.LastName = arg.CustomerLastName; shippingAddressComponent.Party.State = arg.ShippingInfo.ShippingState; shippingAddressComponent.Party.StateCode = arg.ShippingInfo.ShippingState; shippingAddressComponent.Party.CountryCode = arg.ShippingInfo.ShippingCountry; shippingAddressComponent.Party.Country = arg.ShippingInfo.ShippingCountry; shippingAddressComponent.Party.City = arg.ShippingInfo.ShippingCity; shippingAddressComponent.Party.Address1 = arg.ShippingInfo.ShippingAddress; shippingAddressComponent.Party.ZipPostalCode = arg.ShippingInfo.ShippingZip; shippingAddressComponent.Party.AddressName = "Shipping"; //add address components to the customer customer.Components.Add(shippingAddressComponent); //add customer to the entity index so that we can search later await this._persistEntityPipeline.Run( new PersistEntityArgument( new EntityIndex { Id = $"{EntityIndex.IndexPrefix<Customer>("Id")}{customer.Id}", IndexKey = customer.Id, EntityId = customer.Id }), context); return customer; } } }

Finally configure your pipeline in the ConfigureSitecore class.

public void ConfigureServices(IServiceCollection services) { var assembly = Assembly.GetExecutingAssembly(); services.RegisterAllPipelineBlocks(assembly); services.Sitecore().Pipelines(config => config .AddPipeline<ICreateCustomerMinionPipeline, CreateCustomerMinionPipeline>(configure => { configure.Add<CreateCustomersBlock>().Add<PersistCustomerBlock>().Add<PersistCustomerIdIndexBlock>(); }) ); //hopefully we create a new customer entity in the CreateCustomersBlock which is our code, followed by the PersistCustomerBlock and the PersistCustomerIdIndexBlock which will save our new customer. services.RegisterAllCommands(assembly); }

In the next blog post, we will look at indexing custom attributes for entities so that we can search by custom attributes. Hopefully, your code search brings you to this post and I hope this blog post helps in some way.

If you have any questions or concerns, please get in touch with me. (@akshaysura13 on Twitter or on Slack).

Sign up to our newsletter

Share on social media

Akshay Sura

Akshay is a nine-time Sitecore MVP and a two-time Kontent.ai. In addition to his work as a solution architect, Akshay is also one of the founders of SUGCON North America 2015, SUGCON India 2018 & 2019, Unofficial Sitecore Training, and Sitecore Slack.

Akshay founded and continues to run the Sitecore Hackathon. As one of the founding partners of Konabos Consulting, Akshay will continue to work with clients to lead projects and mentor their existing teams.


Subscribe to newsletter