[modRetailCRM] - Интеграция с RetailCRM


Представляю модуль для интеграции популярного сервиса RetailCRM с MODX.




Работа из коробки

Небольшой функционал предусмотрен сразу же при установке приложения.
  1. Плагин срабатывающий на событие onUserSave, автоматически создает новый контакт в CRM при регистрации нового пользователя в MODX. Данное событие срабатывает в том числе при оформлении заказа в интернет-магазине.
  2. Плагин срабатывающий на событие msOnCreateOrder, автоматические создает новый заказ в CRM при оформлении заказа в MiniShop2
На данный момент я просто не знаю, какие еще возможности обязательно нужно включить в работу из коробки. Пишите свое мнение в комментариях. Основные повторяющиеся идеи обязательно внедрим.

Ручной режим

Дополнение основано на собственной библиотеке RetailCRM и в ручном режиме поддерживает ВЕСЬ функционал доступный через API RetaiCRM

Для любителей кастомизировать функционал сайта\интернет-магазина под собственные нужды это означает, что вы можете как угодно взаимодействовать с CRM, оперируя любыми данными.
Для этого доступны десятки методов.
Достаточно Вызвать приложение и указать нужны метод
Например:

//Вызываем приложение
if (!$RetailCrm = $modx->getService('RetailCrm','modretailcrm',MODX_CORE_PATH.'components/modretailcrm/model/modretailcrm/')) {
    $modx->log(1, '[RetailCrm] - Not found class RetailCrm');
    return;
} 
//Получаем список всех заказов одного клиента из CRM
$filters = array();
$filter['customer'] = '+7 701 987 65 43';
$orders = $RetailCrm->ordersList($filter);
//Массив $filters - позволяет фильтровать данные, указав, например, номер или Имя клиента.

//Создаем новый контакт
$customer = array();
$customer['firstName'] = 'Федор';
$customer['lastName'] = 'Бондарчук';
$customer['email'] = 'mail@mail.ru';
$customer['phones'][]['number'] =  '+7 701 987 65 43';
$RetailCrm->customersCreate($customer);

Все доступные методы и их параметры вы можете просмотреть в API RetaiCRM. У Сервиса отличная документация.
Точный вызов того или иного метода — можно найти в файле класса ApiClient внутри дополнения.
Как правило метод вроде /api/v4/customers/create вызывается как customersCreate

Основное преимущество — гибкость в разработке

Главная идея — в том, что мы можем используя существующую библиотеку, передавать в CRM любые данные с сайта, и наоборот получать любую информацию из CRM. Возможности очень гибкие. Мы никак не привязаны к MiniShop2, например.
Можно написать собственные сниппеты и плагины работающие с ShopKeeper.
Совсем не обязательно вообще привязываться к интернет-магазинам.
Совсем простой сниппет позволит создавать в CRM контакт при заполнении классической контактной формы на сайте (пример я написал выше).

Предварительная настройка

Естественно у вас должен быть аккаунт в RetailCRM.
В системных настройках сайта (раздел modretailcrm) Вам нужно указать API ключ, адрес вашей CRM и символьный код сайта. Все эти данные Вы можете посмотреть в личном кабинете RetailCRM

Приложение на данный момент находится на модерации в Modstore.pro, на днях будет опубликовано.
Если кому то не терпится попробовать — могу выслать установочный пакет на E-mail.

Обсуждаем компонент в комментариях. Постараюсь ответить на любые вопросы.
Также готов обсудить персональную адаптацию приложения под ваши конкретные проекты.
05 мая 2017, 23:15    Николай Савин   
1    865 +9

Комментарии (16)

  1. Антон 06 мая 2017, 08:43 # 0
    А есть пример с минишопом?
    Нужно передать данные о корзине, заказчике, доставке, оплате.
    1. Николай Савин 06 мая 2017, 09:10 # +2
      <?php
      if (!$RetailCrm = $modx->getService('RetailCrm','modretailcrm',MODX_CORE_PATH.'components/modretailcrm/model/modretailcrm/')) {
          $modx->log(1, '[RetailCrm] - Not found class RetailCrm');
          return;
      } 
      $site = $modx->getOption('modretailcrm_siteCode');
      /** @var modX $modx */
      switch ($modx->event->name) {
         
          case 'msOnCreateOrder':
              $Address = $msOrder->getOne('Address');
              $orderData = array();
              $orderData['customer']['externalId'] = $Address->get('user_id');
              //Отправляем данные клиента
              if ($profile = $modx->getObject('modUserProfile', $Address->get('user_id'))) {
                  $customer = array();
                  $customer['externalId'] =  $Address->get('user_id');
                  $customer['firstName'] = $profile->fullname;
                  $customer['email'] = $profile->email;
                  if(!empty($profile->phone)){
                      $customer['phones'][]['number'] = $profile->phone;
                  }
                  if(!empty($profile->mobilephone)){
                      $customer['phones'][]['number'] = $profile->mobilephone;
                  }
                  $response = $RetailCrm->customersCreate($customer, $site);  
              }
              
              $orderData['externalId'] = $Address->get('id');
              $orderData['firstName'] = $Address->get('receiver');
              $orderData['phone'] = $Address->get('phone');
              $orderData['email'] = $Address->get('email');
              
              $Products = $msOrder->getMany('Products');
              
              $items = array();
              $key = 0;
              foreach ($Products as $pr) {
                  $options = $pr->toArray();
                  $orderData['items'][$key]['initialPrice'] = $pr->get('cost');
                  $orderData['items'][$key]['purchasePrice'] = $pr->get('cost');
                  $orderData['items'][$key]['productName'] = $pr->get('name');
                  $orderData['items'][$key]['quantity'] = $pr->get('count');
                  $orderData['items'][$key]['offer']['externalId'] = $pr->get('id');
                  $key ++;
      		}
              //Указываем какие поля заполняются в корзине
              $fields = array(
                  'index' => 'Индекс', 
                  'country' => 'Страна', 
                  'region' => 'Регион', 
                  'city' => 'Город', 
                  'metro' => 'Метро', 
                  'street' => 'Улица', 
                  'building' => 'Дом', 
                  'room' => 'Квартира\офис',
                  'comment' => 'Комментарий к адресу'
              );
              $address = '';
              foreach($fields as $field=>$comment){
                  if(!empty($Address->get($field))){
                      $address .= $comment.':'.$Address->get($field).' ';
                      $orderData['delivery']['address'][$field] = $Address->get($field);
                  }
              }
              $orderData['delivery']['address']['text'] = $address;
      //Оплата и доставка довольно индивидуальны
      //Если надо заполнять данные о сервисе и методе доставки заполняем поля раздела order[delivery] 
      	//Данные об оплате заполняются в order[paymentType] order[paymentStatus] order[paymentDetail]
              $response = $RetailCrm->ordersCreate($orderData, $site);
            
              break;
      }
      
    2. Hiddenski 06 мая 2017, 10:57 # +1
      Грац! Шикарное дополнение, особенно нравится НЕпривязка к minishop'у.
      1. Николай Савин 06 мая 2017, 22:58 # +1
        Рад помочь.
        1. Алексей 14 мая 2017, 00:00 # +1
          Николай, у меня после установки лог забит ошибками
          ... xpdo.class.php : 503) Path specified for package modsendpulse is not a valid or accessible directory: ...
          modsendpulse не устанавливал.
          1. Николай Савин 15 мая 2017, 14:02 # 0
            Спасибо за сигнал. Я использовал заготовку от modsendpulse. Видимо где то забыл заменить адрес каталога.
            1. Алексей 15 мая 2017, 17:12 # +1
              Вот уж не за что, это Вам — спасибо!
              Заметил, что лог забивается сам по себе, без каких-то действий на сайте (он тестовый у меня). Как будто cron работает )
          2. Алексей 24 мая 2017, 16:34 # +1
            Николай, а будет ли обновление? Чтобы лог отдохнул )
            1. Николай Савин 28 мая 2017, 19:30 # 0
              Да конечно, на днях будет. Никак не выделю время с работой.
              1. Николай Савин 19 июня 2017, 14:54 # 0
                Выпустил обновление. Баг устранен.
                1. Алексей 27 июня 2017, 10:16 # 0
                  Не совсем:
                  (ERROR @ /core/xpdo/xpdo.class.php: 503) Path specified for package modsendpulse is not a valid or accessible directory: core/components/modsendpulse/model/

                  Источник здесь: components/modretailcrm/index.class.php
              2. Андрей 26 июля 2017, 22:12 # 0
                Подскажите, а смена статуса в админке магазина передается в retailCRM?
                1. Николай Савин 27 июля 2017, 22:00 # 0
                  Нет в исходном плагине прописана отправка данных пользователя и отправка заказа, у которого соответственно статус Новый.
                  Для отправки обновления статуса нужно дописать плагин на событие msOnChangeOrderStatus

                  Я честно говоря не знаю, будет ли сейчас работать метод обновления, так как RetailCRM сейчас выпустили обновление API. Что то изменили, что то добавили, некоторые методы убрали. Надо тестировать короче.
                2. Алексей 22 августа 2017, 17:25 # 0
                  Только руки дошли…
                  В общем, у кого осталась ошибка с «modsendpulse» в логе после обновления, уберите «modsendpulse» из системной настройки minishop2 «extension_packages»
                  1. Алексей 05 сентября 2017, 13:53 # 0
                    Если не верно указать адрес retailCRM (modretailcrm_urlCrm), то будет
                    PHP message: PHP Fatal error:  Uncaught Error: Class 'InvalidJsonException' not found in /home/xxx/xxx/xxx/components/modretailcrm/model/modretailcrm/Response/ApiResponse.php:52
                    Ошибка не очевидная… Наверно желательно добавить проверку нужных настроек в начале + добавить исключение, я так понимаю.
                    Вы должны авторизоваться, чтобы оставлять комментарии.