Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Martin 81 posts 246 karma points
    Oct 30, 2014 @ 15:16
    Martin
    0

    Checkout flow - persisted customers / guest checkout

    Hi guys,

    about to embark on building the checkout flow and have a few questions.

    Initially when the user clicks on 'checkout' I would like them to land on a screen which allows them either to sign in to their account or perform a guest checkout. I've already created a member group called 'store customers' and I've created a test user which I've associated with that group.

    If the user signs in they should be redirected to the address details page where they can select one of their previously used addresses or add a new address to their account. How should I associate addresses with a member, have two MNTP properties on the member which can contain address nodes?

    If the user is performing a guest checkout, what should I collect from the user before allowing them to enter their billing & shipping addresses, name and email address?

    The rest of the checkout process should be straightforward, collect payment information and then after a successful purchase, if guest user allow them to create account by only entering a password (as we already have their name and email address).

    Would love if there was any sample code around this part

    Martin

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Oct 31, 2014 @ 03:14
    Rusty Swayne
    0

    Hey Martin,

    By default Merchello looks for the MemberType of "Customer" to associate Umbraco Members with Merchello persisted customers. For your member type you will need to add "store customers" to the Merchello.config (located /App_Plugins/Merchello/Config/) ... find the "customer" element.

    If the member signs in, the Merchello Customer object includes a collection of CustomerAddress with a bunch of CRUD extension methods to help you manage the addresses. The CustomerAddress collection has two types (AddressType) that you can manage Billing and Shipping addresses.

    In either case, if you are doing a Basket based checkout, you will have access to the SalesPreparation object generally accessed by an extension off of the Basket itself.

    Depending on you setup:

    // inside a surface controller
    
    var customerContext = new CustomerContext(UmbracoContext)
    
    var customer = customerContext.CurrentCustomer;  // this returns a ICustomerBase and used for either anonymous or known customers
    
    // to access the basket
    var basket = customer.Basket();
    
    // to access the SalesPreparation
    
    var salesPreparation = customer.Basket().SalesPreparation();
    

    The sales preparation class has helpful methods allowing you to "prepare a sale" storing billing address, shipping address, shipment rate quotes, prepare invoice for preview, and then finally authorize or authorize and capture payments when some sort of "complete checkout" is finally reached. It also handles, invalidating shipment rate quotes and taxation quotes in the event the customer goes back to shopping and/or manipulates quantities in their basket (which could affect weights, quantities ... etc).

    There are several example builds out there - but in the next few days we are consolidating them into the https://github.com/Merchello/Samples public repository so that various programming styles can be checked out in a single place ... just had a meeting about this today, just getting things organized.

    In the 1.5.0 release, I've made the change to the IInvoice that adds a setter to the CustomerKey so that after the checkout you will be able to associate an anonymous customer checkout with a customer if they choose to signup for an account after they complete the sale.

    We also have some good news, that we are in the design stage of publishing the documentation we have been working on for the last couple of months. We have about 70 documents so far ready to go ... these should be available on http://merchello.com in about a week coinciding with the 1.5.0 release.

    We would love to hear your feedback on the process as we are actively looking for ways to make the checkout process more straight forward.

    Also, please don't hesitate to enter any issues you have at http://issues.merchello.com.

    Thanks!

    Rusty

  • Martin 81 posts 246 karma points
    Dec 16, 2014 @ 22:33
    Martin
    0

    Hi Rusty, finally found some time to get back on to this Merchello project. So when a user is logged in and I look at the ICustomerBase CurrentCustomer object I see that the IsAnonymous value is set to false but the Email, FirstName, LastName, etc properties are blank. I collect these values when a user registers so should I be creating a customer at that point? The LoginName property is correctly set to the email address the user registered with but how do I go about setting the other properties. Also I couldn't see any CRUD methods for adding / editing / deleting addresses, could you give me some code samples around that.

    Many thanks, Martin

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Dec 17, 2014 @ 00:37
    Rusty Swayne
    0

    Hi Martin,

    The first name and last name fields on the customer is not something we can automatically set since we can't be 100% certain that the implementation will have a first name and last name on the members content type.

    In implementations I've done I added a handler to for the MemberService.Saved event and use whatever property aliases you have in your application.

      public class UmbracoEvents : ApplicationEventHandler
      {
           protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
           {
               LogHelper.Info<UmbracoEvents>("Binding Merchello Customer synchronization");
               MemberService.Saved += MemberServiceOnSaved;
           }
    
       protected void MemberServiceOnSaved(IMemberService sender, SaveEventArgs<IMember> saveEventArgs)
        {
            var members = saveEventArgs.SavedEntities.ToArray();
    
            // Allowed member types for Merchello customers
            var customerMemberTypes = MerchelloConfiguration.Current.CustomerMemberTypes.ToArray();
    
            // Get a reference to Merchello's customer service
            var customerService = MerchelloContext.Current.Services.CustomerService;
    
            foreach (var member in members)
            {
                // verify the member is a customer type
                if (!customerMemberTypes.Contains(member.ContentTypeAlias)) continue;
    
                var customer = customerService.GetByLoginName(member.Username);
                if (customer == null) continue;
    
                customer.FirstName = member.GetValue<string>("firstName") ?? string.Empty;
                customer.LastName = member.GetValue<string>("lastName") ?? string.Empty;
                customer.Email = member.Username;
    
                customerService.Save(customer);
            }
        }
    
      }
    
  • Martin 81 posts 246 karma points
    Dec 17, 2014 @ 23:12
    Martin
    0

    Hi Rusty, thanks for that, just what I needed for setting the customer properties but how about saving a billing / shipping IAddress against the customer?

  • Rusty Swayne 1655 posts 4993 karma points c-trib
    Dec 17, 2014 @ 23:27
    Rusty Swayne
    0

    Hi Martin,

    The customers actually have their own address - ICustomerAddress so you could use

                  var address = [Your IAddress];
                  var customerAddress = new CustomerAddress(customer.Key)
                                    {
                                        Label = [your label],   // maybe shipping or billing
                                        FullName = Name,
                                        Address1 = address.Address1,
                                        Address2 = address.Address2,
                                        AddressType = AddressType.Shipping,
                                        Locality = address.Locality,
                                        Region = address.Region,
                                        PostalCode = address.PostalCode,
                                        CountryCode = address.CountryCode,
                                        Company = address.Organization,
                                    };
    
                   // then save it
                   customer.SaveCustomerAddress(customerAddress);
    
                   // I think there is a bug that you may have to work around here to get the address to reindex in the Customer index
                   // so you may need to save the customer again.  Not confirmed as I know everything is in the database but I have it
                   // as a todo to look at.
                   MerchelloContext.Current.Services.CustomerService.Save(customer); 
    
  • This forum is in read-only mode while we transition to the new forum.

    You can continue this topic on the new forum by tapping the "Continue discussion" link below.

Please Sign in or register to post replies