Опыт интеграции с AMO CRM part 1

Авторизация и получение токенов доступа

Задача — интеграция АМО с e-commerce платформой для магазина. Заказы должны поступать в АМО и при изменении статуса заказа, так же должен меняться статус заказа на e-commerce платформе.
Взаимодействуют обе системы через сторонний сервер который обеспечивает также интеграцию с платежной системой и API Greeninvoice для отправки чеков.

Для тех кто не в курсе что такое AMO CRM — Это довольно таки мощный инструмент для бизнеса, основное его назначение это контакт с покупателем. Он позволяет автоматизировать многие рутинные задачи и облегчает бизнес процессы.
В данном случае основная задача, получить заказ из интернет магазина и работать с ним в уже знакомой заказчику среде. При получении заказа из интернет магазина сервер интеграции обрабатывает данные и создает в АМО сделку, создает и прикрепляет к ней учетную запись клиента с его данными (телефон, адрес и прочее), также при необходимости обновляет список товаров в АМО, заполняет данные о заказе (заказанные товары, дата и способ доставки, комментарий покупателя, статус оплаты и прочее разное).

В общем-то всё то же самое что есть в админ панели самой e-commerce платформы. НО в АМО собираются заказы из самых разных источников, что позволяет работать с заказами вне зависимости от источника.

AMO CRM имеет свою PHP библиотеку для работы со своим API. Ставится через Composer. После установки мы имеем в папке vendor/amocrm/examples примеры для работы с библиотекой.

Первое что я сделал, это интерфейс авторизации для получения токенов. Теоретически этого можно было бы не делать, амо использует 2 вида токенов, первый имеет короткий срок жизни и служит для запросов к апи, второй живет 3 мес и нужен для получения первого, и вряд-ли бизнес может позволить себе 3 мес стоять. Но бывает всякое, и у клиента должна быть возможность запустить интеграцию вручную.

На амо есть инструкция пример по шагам. Сначала по этой инструкции создал саму интеграцию в кабинете на амо. Потом сделал контроллер который показывал, на мой взгляд самый простой способ авторизации приложения, кнопку амо. По сути я просто скопировал скрипт и подставил туда свои параметры

Ниже пример кода скрипта.

 <script
        class="amocrm_oauth"
        charset="utf-8"
        data-client-id="<?php echo $amoIntegrationId; ?>"
        data-title=""
        data-compact="false"
        data-class-name="amoButton"
        data-color="default"
        data-state="<?php echo $autoriseHesh; ?>"
        data-error-callback="functionName"
        data-mode="popup"
        src="https://www.amocrm.ru/auth/button.min.js"
    ></script>

Далее я сделал функцию в контроллере для записи получения ответа от амо. Ниже обе функции первая передает во вьюху параметры для кнопки, вторая записывает их в файл (это не обязательно, я сделал для анализа возможных ошибок) и получает токены (код авторизации живет только 20 минут).

public function indexAction()
{
   parent::indexAction(); // TODO: Change the autogenerated stub

    return $this->view->render('Amocrm/index.phtml', [
        'amoIntegrationId' => (string) AMO_INTEGRATION_ID,
        'autoriseHesh' => AMO_AUTORISE_HESH,
   ]);
}

// первичная запись ответа при авторизации
// получаем кад авторизации и по нему получаем токены
public function callbackAction()
{

    if(!empty($_GET['code']) && $_GET['state'] == AMO_AUTORISE_HESH) {
        $getJson = json_encode($_GET);
        file_put_contents(AMO_AUTORISE_FILE, $getJson);

        // получение токенов доступа
 реализовано через объект модели
        Amo::getTokens($_GET, 'authorization_code');
    }
}

Порывшись в примерах я сделал модель Amo и функцию для получения токенов.

class Amo
{
    // константы прописаны в конфиг файле
    private static $secretKey = AMO_SECRET_KEY;
    private static $integrationId = AMO_INTEGRATION_ID;
    private static $requestUrl = AMO_APP_BACKURL;

 
    public static function getTokens(array $AmoDate, $mode)
    {

        $subdomain = $AmoDate['referer']; //Поддомен нужного аккаунта
        $link = 'https://' . $subdomain . '/oauth2/access_token'; //Формируем URL для запроса

        /** Соберем данные для запроса */
        $data = [
            'client_id' => self::$integrationId,
            'client_secret' => self::$secretKey,
            'grant_type' => $mode,
            'redirect_uri' => AMO_APP_BACKURL,
        ];

        // модификация запроса для получения или обновления токенов
        if ($mode == 'refresh_token') {
            $data['refresh_token'] = $AmoDate['refresh_token'];
        } else {
            $data['code'] = $AmoDate['code'];
        }


        /**
         * Нам необходимо инициировать запрос к серверу.
         * Воспользуемся библиотекой cURL (поставляется в составе PHP).
         * Вы также можете использовать и кроссплатформенную программу cURL, если вы не программируете на PHP.
         */
        $curl = curl_init(); //Сохраняем дескриптор сеанса cURL
        /** Устанавливаем необходимые опции для сеанса cURL  */
        curl_setopt($curl,CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl,CURLOPT_USERAGENT,'amoCRM-oAuth-client/1.0');
        curl_setopt($curl,CURLOPT_URL, $link);
        curl_setopt($curl,CURLOPT_HTTPHEADER,['Content-Type:application/json']);
        curl_setopt($curl,CURLOPT_HEADER, false);
        curl_setopt($curl,CURLOPT_CUSTOMREQUEST, 'POST');
        curl_setopt($curl,CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($curl,CURLOPT_SSL_VERIFYPEER, 1);
        curl_setopt($curl,CURLOPT_SSL_VERIFYHOST, 2);
        $out = curl_exec($curl); //Инициируем запрос к API и сохраняем ответ в переменную
        $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);


        /** Теперь мы можем обработать ответ, полученный от сервера. Это пример. Вы можете обработать данные своим способом. */
        $code = (int)$code;

        $errors = [
            400 => 'Bad request',
            401 => 'Unauthorized',
            403 => 'Forbidden',
            404 => 'Not found',
            500 => 'Internal server error',
            502 => 'Bad gateway',
            503 => 'Service unavailable',
        ];

        /** Если код ответа не успешный - возвращаем сообщение об ошибке  */
        if ($code < 200 || $code > 204) {

            if (!empty($errors[$code])) {
                echo "error $code " . $errors[$code] . '<br>';
            }
            $res = json_decode($out);

            foreach ($res as $k => $val) {
                // тут скорее всего надо бы записать ошибку в лог
                echo "<p>$k - $val</p>";
            }

        } else {
            /**
             * Данные получаем в формате JSON
             * Записывем в файл ответ с токенами
             */
            file_put_contents(AMO_TOKEN_MODEL_FILE, $out);

            return $out;
        }

    }

}

Вообще в библиотеке амо для получения токенов есть примеры. Но так исторически сложилось что я сделал свою реализацию. И пользуясь принципом, работает — не трогай, пока там ничего не меняю )))

В следующей статье рассмотрен пример создания сделки в амоCRM Опыт интеграции с AMO CRM part 2

Сдедующая статья
Опыт интеграции с AMO CRM part 2
Предыдущая статья
Оптимизация блога