I'm implementing a B2B solution where users within the same organization should share the same cart. All APIs for loading carts requires a customerId [sic] which relates to a contact ID, i.e. we will always load or create a cart for just that user. How do we implement this in the best way? I see a few different approaches:
Has someone already implemented this, how did you do this, any drawbacks, pitfalls?
I haven't implemented it but i would like to suggest two different approaches:
The primary contact would be my first try on implementing this, if you need/want to use the primary contact for other things then a new metafield for a contact guid can easily be added.
I haven't implemented it (I hardly do except some quick dirty PoC), but I think this will work:
Of course that would mean a customer belongs to a company will always access the organization's cart. If you want it to be case by case (personal cart, or company cart), then it will be much trickier.
Thanks for your feedback!
I rather not create organizations in Commerce database, these are stored elsewhere and I don't want to keep the different sources in sync, but I do already have an ID for the organization (not Commerce organization) stored on the cart (and order).
@Quan are there any reasons I still want to create an organization and primary contact in Commerce? I want to touch as few subsystems as possible, since we're not using organization to anything else.
@Erik regarding your second approach, I then have to update the organization with a new ID everytime a new cart is created. Seems error prone.
You still need to map between customers and organization. You can implement that yourself if you don't like Business Foundation, but something is still needed.
Why do I need to implement organizations in Commerce? From what I can see only contacts are connected to an OrderForm and they doesn't need to belong to an organization. In a B2C scenario, do you then need to implement organizations as well? That seems weird.
I was just thinking if there were any benefits implementing organizations in Commerce as well? I already know which "organization" a user/contact/customer belongs to and that is already stored on the cart by an extended property.
Well, if you already have that information somehow, then you don't have to implement it. However for SerializableCart it'll be tricky to search for carts by metafields.
Aha. Ok, so then we're back on square one :) I'm leaning towards my first approach then - sharing the same contact for everyone within the same organization. Not optimal.
This might be something for your backlog Quan, better API support for retrieving carts.
We actually have something in backlog - an unified APIs for searching for carts. But it is still a long way to get there.
As always, too many things to do, too little time.
However sharing carts between contacts seems to be a fairly common request. I'll see if we can do something about it.
A bit stunned that nobody else has run in to this issue... or maybe I'm just not able to find those threads.
Not here, but in other internal channels. I said what I think will work (as above), but of course we might want to make thing easier from the framework.
I don't think I need to intercept any services. I just need to pass in the correct and same customerId (which should be named contactId, because that's what it is) for everyone within the same organization.
Thanks for you feedback!
How's about the case for normal users? Well, if you don't have to handle that then it's much easier. Intercept is to make sure you can fallback to default behavior if you have company-users and private users, which is a fairly common scenario.
In this case all users belongs to an organization. If we would enable a B2C scenario I would imagine that it still would work, because then they would get their own contact and not share the same.
It isn't mandatory to delete carts after placing an order, you can just clear the cart items and keep any additional info for the next time. Especially in a B2B case it could make sense to adopt that approach.
Yepp, i do believe the customerId doesn't even have to be a contactId, that is there doesn't have to be a contact matching it. Because anonymous purchases gets a customerId guid as well.
You can store such an id in a custom metafield on contact as well. I suggested organization to avoid redundancy but if you have the organization info from another source you can skip it. Having an existing contact and organization in episerver would make order handling in episerver easier for the customer service/administrators, but i don't know if your case includes using episerver for those functions.
Great input Erik. Thanks. Unfortunately our ID for organizations is not a guid. So I have to create a common contact anyway to get a guid.
Or any form of mapping table organizationid=>guid that Quan mentioned earlier.
If your organization ids are static and unique integers/longs you can even just build your own psuedo-guids from that identifier like 00000000-0000-0000-0000-000000001234. A bit too quick and dirty maybe? :)
Hehe, nice solution Patrick. They are indeed static but not sure which value type they are. We recieve them as strings from an ERP and eventually we will bring on more ERPs when we launch in more markets. So the type might change.