В сценариях вспомогательной коммерции, колл-центров и B2B Агент по продажам часто приходится работать от имени нескольких клиентов в рамках одного сеанса с аутентификацией.
Типичное требование выглядит так:
-
Торговый агент авторизуется один раз (через OKTA)
-
Использование Выберите клиента выбрать клиента
-
Управляет корзиной для этого клиента
-
Переход к другому клиенту
Возвращается к предыдущему клиенту и продолжает с того места, на котором остановился.
Изначально Optimizely Commerce предполагает одна активная корзина на каждого пользователячто делает этот сценарий нетривиальным.
В этом блоге объясняется чистый, масштабируемый шаблон для поддержки несколько корзин клиентов в одном сеансе агента по продажам в Optimizely Commerce 14.
Проблемы
По умолчанию корзина в Optimizely Commerce связана с:
-
CustomerId -
Рынок
-
Название корзины
В сценариях сопровождаемых продаж:
-
вошедший в систему пользователь — торговый агент
-
фактический покупатель — выбранный покупатель
-
Торговый агент должен управлять несколько тележекпо одному на клиента
Принцип проектирования (который я использовал)
Относитесь к торговому агенту как к оператору, а не как к владельцу тележки.
-
Личность торгового агента остается неизменной
-
У каждого клиента есть свой собственная постоянная корзина
-
Переключение контекста клиента явный
-
В пользовательском интерфейсе одновременно активна только одна корзина.
Поэтому, чтобы выполнить это требование, я создал конечную точку, которая будет принимать идентификаторы клиентов для активного клиента и выбранного клиента, поэтому на основе идентификатора клиента система переключает/выбирает правильную корзину и делает ее основной корзиной.
Модель ввода для переключения контекста клиента
Переключение клиентов осуществляется с помощью простой и явной модели ввода:
public class CustomerCartDetailsInputModel
{
[DataMember(Name = "activeCustomerId")]
public string ActiveCustomerId { get; set; }
[DataMember(Name = "selectedCustomerId")]
public string SelectedCustomerId { get; set; }
}
Цель:
Это позволяет избежать неявного поведения сеанса и сохраняет ясность владения корзиной.
Конечная точка переключения корзины клиента
Всякий раз, когда агент по продажам нажимает Выберите клиентаинтерфейс вызывает одну конечную точку:
[HttpPost]
public async Task Post(
[FromBody] CustomerCartDetailsInputModel inputModel)
{
return new JsonHttpStatusResult(
await _customerCartService.UpdateCustomerCartAsync(inputModel),
SerializerSettings.JsonDefault);
}
Эта конечная точка действует как единственный источник истины для:
-
Сохранение корзины активного клиента
-
Загрузка или создание корзины выбранного клиента
-
Переключение активного контекста корзины
Высокоуровневый процесс переключения
-
Разрешение личности агента по продажам
-
Загрузите или создайте Контекстная корзина агента по продажам
-
Сохранение корзины активного клиента
-
Загрузите или создайте корзину выбранного клиента
-
Скопируйте выбранную корзину клиента в контекст агента по продажам.
-
Отметить выбранного клиента как активного
Упрощенная логика переключения корзин (базовый шаблон)
Ниже приведена очищенная версия базовой логики, ориентированная только на обработку нескольких тележек:
public async Task UpdateCustomerCartAsync(
CustomerCartDetailsInputModel inputModel)
{
var salesAgentId = GetSalesAgentId();
// Load or create Sales Agent context cart
var agentCart = _orderRepository.LoadOrCreateCart(
salesAgentId, OrderNames.Default);
// Ensure identifiers exist
if (string.IsNullOrEmpty(inputModel.ActiveCustomerId))
inputModel.ActiveCustomerId = Guid.NewGuid().ToString();
if (string.IsNullOrEmpty(inputModel.SelectedCustomerId))
inputModel.SelectedCustomerId = Guid.NewGuid().ToString();
Guid.TryParse(inputModel.ActiveCustomerId, out var activeCustomerId);
Guid.TryParse(inputModel.SelectedCustomerId, out var selectedCustomerId);
// Persist active customer cart
if (activeCustomerId != Guid.Empty)
{
var activeCustomerCart =
_orderRepository.LoadCart(activeCustomerId, OrderNames.Default)
?? _orderRepository.Create(activeCustomerId, OrderNames.Default);
activeCustomerCart.CopyFrom(agentCart, _orderGroupFactory);
activeCustomerCart.CustomerId = activeCustomerId;
_cartRepository.SaveCart(activeCustomerCart);
}
// Load or create selected customer cart
var selectedCustomerCart =
_orderRepository.LoadCart(selectedCustomerId, OrderNames.Default)
?? _orderRepository.Create(selectedCustomerId, OrderNames.Default);
selectedCustomerCart.CustomerId = selectedCustomerId;
// Switch active context
agentCart.CopyFrom(selectedCustomerCart, _orderGroupFactory);
agentCart.CustomerId = salesAgentId;
_cartRepository.SaveCart(agentCart); // Save Cart
return new CartGetViewModel
{
Cart = await BuildCartViewModel(agentCart), // Generate View Model of Cart
CartCustomerId = selectedCustomerId.ToString()
};
}
Понимание CopyFrom Метод
CopyFrom – это основной API Optimizely Commerce, используемый для глубоко скопировать всю структуру корзины из одной группы заказов в другую.
targetCart.CopyFrom(sourceCart, _orderGroupFactory);
Что CopyFrom Делает
-
Копирует позиции, поставки, платежи и адреса.
-
Копирует пользовательские свойства
-
Воссоздает все объекты, используя
IOrderGroupFactory
Почему CopyFrom Здесь важно
В сценариях с несколькими корзинами:
-
Корзины клиентов должны оставаться изолированными
-
Контекстная корзина агента по продажам должна полностью переключиться в состояние.
-
Частичные обновления небезопасны
CopyFrom гарантирует чистый переключатель тележки без утечки данных.
Разделив Личность агента по продажам от владение корзиной клиента и используя явный Выберите клиента flow, вы можете создать масштабируемую систему вспомогательной коммерции на Optimizely Commerce, не борясь с платформой.
Ниже приведен результат проектирования:
22 декабря 2025 г.
Продолжение темы

