{"id":15578483,"url":"https://github.com/andrey-tech/amocrm-api-php","last_synced_at":"2025-04-06T07:13:29.416Z","repository":{"id":45037722,"uuid":"264145465","full_name":"andrey-tech/amocrm-api-php","owner":"andrey-tech","description":"Простая обертка на PHP7+ для работы с API amoCRM v2 с aвторизацией oAuth 2.0, поддержкой AJAX-запросов к frontend-методам, троттлингом запросов к API, блокировкой одновременного обновления одной сущности и логированием в файл.","archived":false,"fork":false,"pushed_at":"2025-01-26T12:55:25.000Z","size":2403,"stargazers_count":35,"open_issues_count":0,"forks_count":12,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-30T06:06:41.236Z","etag":null,"topics":["amocrm","amocrm-php","api","api-wrapper","crm","loggging","oauth2","php","php7","throttling"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andrey-tech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-05-15T08:56:53.000Z","updated_at":"2025-02-05T23:43:00.000Z","dependencies_parsed_at":"2024-01-15T19:20:43.024Z","dependency_job_id":"ecb6c234-c389-4940-ab70-1c9e219d1418","html_url":"https://github.com/andrey-tech/amocrm-api-php","commit_stats":{"total_commits":87,"total_committers":4,"mean_commits":21.75,"dds":0.3563218390804598,"last_synced_commit":"00c0c4659b075d423d1e35fba3212f47bda07c4d"},"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrey-tech%2Famocrm-api-php","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrey-tech%2Famocrm-api-php/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrey-tech%2Famocrm-api-php/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrey-tech%2Famocrm-api-php/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andrey-tech","download_url":"https://codeload.github.com/andrey-tech/amocrm-api-php/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247445671,"owners_count":20939958,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["amocrm","amocrm-php","api","api-wrapper","crm","loggging","oauth2","php","php7","throttling"],"created_at":"2024-10-02T19:10:47.418Z","updated_at":"2025-04-06T07:13:29.396Z","avatar_url":"https://github.com/andrey-tech.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# amoCRM API PHP Wrapper\n\n![amoCRM logo](./assets/amocrm-logo.png)  \n\n[![Latest Stable Version](https://poser.pugx.org/andrey-tech/amocrm-api-php/v)](//packagist.org/packages/andrey-tech/amocrm-api-php)\n[![Total Downloads](https://poser.pugx.org/andrey-tech/amocrm-api-php/downloads)](//packagist.org/packages/andrey-tech/amocrm-api-php)\n[![GitHub stars](https://img.shields.io/github/stars/andrey-tech/amocrm-api-php)](https://github.com/andrey-tech/amocrm-api-php/stargazers)\n[![GitHub forks](https://img.shields.io/github/forks/andrey-tech/amocrm-api-php)](https://github.com/andrey-tech/amocrm-api-php/network)\n[![GitHub watchers](https://img.shields.io/github/watchers/andrey-tech/amocrm-api-php)](https://github.com/andrey-tech/amocrm-api-php/watchers)\n[![License](https://poser.pugx.org/andrey-tech/amocrm-api-php/license)](//packagist.org/packages/andrey-tech/amocrm-api-php)\n\nПростая обертка на PHP7+ для работы с REST API [amoCRM](https://www.amocrm.ru) **v2 (версии 2)** с авторизацией по протоколу oAuth 2.0\nили по API-ключу пользователя, поддержкой AJAX-запросов к frontend-методам, троттлингом запросов к API,\nблокировкой одновременного обновления одной сущности и логированием запросов/ответов к API в файл.\n\nДанная библиотека была создана для удовлетворения\n[новых требований amoCRM](https://www.amocrm.ru/developers/content/integrations/requirements),\nпредъявляемых к публичным интеграциям:\n\u003e Публичные интеграции должны использовать механизм авторизации oAuth 2.0,\nиспользование механизма API ключей не допускается. Требование с февраля 2020 года.\n\nС 1 июля 2020 г. информация о API-ключе пользователя стала недоступна в интерфейсе amoCRM.\n\nВ настоящее время актуальной версией является [REST API amoCRM **v4 (версия 4)**](https://www.amocrm.ru/developers/content/crm_platform/api-reference) (запросы к API отправляются на /api/v4/).  \n\n## Документация по REST API amoCRM **v2**\n\nДокументация по REST API **v2** теперь недоступна на русскоязычной версии сайта amoCRM.\nНа англоязычной версии сайта эта документация перенесена в раздел [API V2 GENERAL METHODS](https://www.amocrm.com/developers/).\n\nАрхив документации по REST API amoCRM **v2** в формате HTML вынесен в самостоятельный [репозиторий](https://github.com/andrey-tech/amocrm-api-v2-docs).   \nНиже приведены ссылки на отдельные HTML-файлы этого архива:\n\n- [Аккаунт](https://htmlpreview.github.io/?https://github.com/andrey-tech/amocrm-api-v2-docs/blob/master/docs/account.html) \n- [Авторизация](https://htmlpreview.github.io/?https://github.com/andrey-tech/amocrm-api-v2-docs/blob/master/docs/auth.html)\n- [Компании](https://htmlpreview.github.io/?https://github.com/andrey-tech/amocrm-api-v2-docs/blob/master/docs/companies.html)\n- [Контакты](https://htmlpreview.github.io/?https://github.com/andrey-tech/amocrm-api-v2-docs/blob/master/docs/contacts.html)\n- [Сделки](https://htmlpreview.github.io/?https://github.com/andrey-tech/amocrm-api-v2-docs/blob/master/docs/leads.html)\n- [События](https://htmlpreview.github.io/?https://github.com/andrey-tech/amocrm-api-v2-docs/blob/master/docs/notes.html)\n- [Задачи](https://htmlpreview.github.io/?https://github.com/andrey-tech/amocrm-api-v2-docs/blob/master/docs/tasks.html)\n- [Списки](https://htmlpreview.github.io/?https://github.com/andrey-tech/amocrm-api-v2-docs/blob/master/docs/catalogs.html)\n- [Элементы списков](https://htmlpreview.github.io/?https://github.com/andrey-tech/amocrm-api-v2-docs/blob/master/docs/catalog-elements.html)\n- [Неразобранное](https://htmlpreview.github.io/?https://github.com/andrey-tech/amocrm-api-v2-docs/blob/master/docs/unsorted.html)\n- [Webhooks](https://htmlpreview.github.io/?https://github.com/andrey-tech/amocrm-api-v2-docs/blob/master/docs/webhooks.html)\n- [Покупатели](https://htmlpreview.github.io/?https://github.com/andrey-tech/amocrm-api-v2-docs/blob/master/docs/customers.html)\n- [Дополнительные поля](https://htmlpreview.github.io/?https://github.com/andrey-tech/amocrm-api-v2-docs/blob/master/docs/custom_fields.html)\n- [Виджеты](https://htmlpreview.github.io/?https://github.com/andrey-tech/amocrm-api-v2-docs/blob/master/docs/widgets.html)\n- [Товары](https://htmlpreview.github.io/?https://github.com/andrey-tech/amocrm-api-v2-docs/blob/master/docs/products.html)\n- [Воронки и этапы продаж](https://htmlpreview.github.io/?https://github.com/andrey-tech/amocrm-api-v2-docs/blob/master/docs/pipelines.html)\n- [Логирование звонков](https://htmlpreview.github.io/?https://github.com/andrey-tech/amocrm-api-v2-docs/blob/master/docs/calls-add.html)\n- [Уведомление о звонке](https://htmlpreview.github.io/?https://github.com/andrey-tech/amocrm-api-v2-docs/blob/master/docs/call-event.html)\n- [Коды ошибок](https://htmlpreview.github.io/?https://github.com/andrey-tech/amocrm-api-v2-docs/blob/master/docs/errors.html)\n- [Ограничения и рекомендации](https://htmlpreview.github.io/?https://github.com/andrey-tech/amocrm-api-v2-docs/blob/master/docs/recommendations.html)\n\n## Содержание\n\n\u003c!-- MarkdownTOC levels=\"1,2,3,4,5,6\" autoanchor=\"true\" autolink=\"true\" --\u003e\n\n- [Требования](#%D0%A2%D1%80%D0%B5%D0%B1%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F)\n- [Установка](#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0)\n- [Авторизация](#%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F)\n    - [Авторизация по протоколу oAuth 2.0 \\(актуальный метод\\)](#%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F-%D0%BF%D0%BE-%D0%BF%D1%80%D0%BE%D1%82%D0%BE%D0%BA%D0%BE%D0%BB%D1%83-oauth-20-%D0%B0%D0%BA%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9-%D0%BC%D0%B5%D1%82%D0%BE%D0%B4)\n        - [Первичная авторизация и обмен кода авторизации на access токен и refresh токен](#%D0%9F%D0%B5%D1%80%D0%B2%D0%B8%D1%87%D0%BD%D0%B0%D1%8F-%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F-%D0%B8-%D0%BE%D0%B1%D0%BC%D0%B5%D0%BD-%D0%BA%D0%BE%D0%B4%D0%B0-%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8-%D0%BD%D0%B0-access-%D1%82%D0%BE%D0%BA%D0%B5%D0%BD-%D0%B8-refresh-%D1%82%D0%BE%D0%BA%D0%B5%D0%BD)\n        - [Последующие авторизации](#%D0%9F%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%83%D1%8E%D1%89%D0%B8%D0%B5-%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8)\n        - [Хранение access и refresh токенов](#%D0%A5%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5-access-%D0%B8-refresh-%D1%82%D0%BE%D0%BA%D0%B5%D0%BD%D0%BE%D0%B2)\n            - [Интерфейс `TokenStorageInterface`](#%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81-tokenstorageinterface)\n            - [Класс `FileStorage`](#%D0%9A%D0%BB%D0%B0%D1%81%D1%81-filestorage)\n            - [Использование собственного класса для сохранения токенов](#%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE-%D0%BA%D0%BB%D0%B0%D1%81%D1%81%D0%B0-%D0%B4%D0%BB%D1%8F-%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F-%D1%82%D0%BE%D0%BA%D0%B5%D0%BD%D0%BE%D0%B2)\n        - [Проверка наличия первичной авторизации](#%D0%9F%D1%80%D0%BE%D0%B2%D0%B5%D1%80%D0%BA%D0%B0-%D0%BD%D0%B0%D0%BB%D0%B8%D1%87%D0%B8%D1%8F-%D0%BF%D0%B5%D1%80%D0%B2%D0%B8%D1%87%D0%BD%D0%BE%D0%B9-%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8)\n    - [Авторизация по API-ключу пользователя \\(устаревший метод\\)](#%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F-%D0%BF%D0%BE-api-%D0%BA%D0%BB%D1%8E%D1%87%D1%83-%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F-%D1%83%D1%81%D1%82%D0%B0%D1%80%D0%B5%D0%B2%D1%88%D0%B8%D0%B9-%D0%BC%D0%B5%D1%82%D0%BE%D0%B4)\n    - [Одновременная авторизация в нескольких аккаунтах amoCRM](#%D0%9E%D0%B4%D0%BD%D0%BE%D0%B2%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F-%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F-%D0%B2-%D0%BD%D0%B5%D1%81%D0%BA%D0%BE%D0%BB%D1%8C%D0%BA%D0%B8%D1%85-%D0%B0%D0%BA%D0%BA%D0%B0%D1%83%D0%BD%D1%82%D0%B0%D1%85-amocrm)\n- [Параметры настройки](#%D0%9F%D0%B0%D1%80%D0%B0%D0%BC%D0%B5%D1%82%D1%80%D1%8B-%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B8)\n- [Работа с сущностями amoCRM](#%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D1%81%D1%83%D1%89%D0%BD%D0%BE%D1%81%D1%82%D1%8F%D0%BC%D0%B8-amocrm)\n    - [Список методов и констант моделей](#%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA-%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%B2-%D0%B8-%D0%BA%D0%BE%D0%BD%D1%81%D1%82%D0%B0%D0%BD%D1%82-%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D0%B5%D0%B9)\n        - [Базовый класс моделей `AmoObject`](#%D0%91%D0%B0%D0%B7%D0%BE%D0%B2%D1%8B%D0%B9-%D0%BA%D0%BB%D0%B0%D1%81%D1%81-%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D0%B5%D0%B9-amoobject)\n        - [Класс `AmoContact` - модель контакта](#%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amocontact---%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D0%BA%D0%BE%D0%BD%D1%82%D0%B0%D0%BA%D1%82%D0%B0)\n        - [Класс `AmoCompany` - модель компании](#%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amocompany---%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D0%B8)\n        - [Класс `AmoLead` - модель сделки](#%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amolead---%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D1%81%D0%B4%D0%B5%D0%BB%D0%BA%D0%B8)\n        - [Класс `AmoTask` - модель задачи](#%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amotask---%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8)\n        - [Класс `AmoNote` - модель события \\(примечания\\)](#%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amonote---%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D1%81%D0%BE%D0%B1%D1%8B%D1%82%D0%B8%D1%8F-%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%87%D0%B0%D0%BD%D0%B8%D1%8F)\n        - [Класс `AmoCatalog` - модель списка \\(каталога\\)](#%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amocatalog---%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0-%D0%BA%D0%B0%D1%82%D0%B0%D0%BB%D0%BE%D0%B3%D0%B0)\n        - [Класс `AmoCatalogElement` - модель элемента списка \\(каталога\\)](#%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amocatalogelement---%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%B0-%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0-%D0%BA%D0%B0%D1%82%D0%B0%D0%BB%D0%BE%D0%B3%D0%B0)\n        - [Класс `AmoIncomingLead` - базовая модель заявки из неразобранного](#%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amoincominglead---%D0%B1%D0%B0%D0%B7%D0%BE%D0%B2%D0%B0%D1%8F-%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D0%B7%D0%B0%D1%8F%D0%B2%D0%BA%D0%B8-%D0%B8%D0%B7-%D0%BD%D0%B5%D1%80%D0%B0%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE)\n            - [Общие методы для работы с заявками из неразобранного](#%D0%9E%D0%B1%D1%89%D0%B8%D0%B5-%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D1%8B-%D0%B4%D0%BB%D1%8F-%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%8B-%D1%81-%D0%B7%D0%B0%D1%8F%D0%B2%D0%BA%D0%B0%D0%BC%D0%B8-%D0%B8%D0%B7-%D0%BD%D0%B5%D1%80%D0%B0%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE)\n            - [Класс `AmoIncomingLeadForm` - модель заявки из неразобранного при добавлении из веб-формы](#%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amoincomingleadform---%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D0%B7%D0%B0%D1%8F%D0%B2%D0%BA%D0%B8-%D0%B8%D0%B7-%D0%BD%D0%B5%D1%80%D0%B0%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE-%D0%BF%D1%80%D0%B8-%D0%B4%D0%BE%D0%B1%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B8-%D0%B8%D0%B7-%D0%B2%D0%B5%D0%B1-%D1%84%D0%BE%D1%80%D0%BC%D1%8B)\n            - [Класс `AmoIncomingLeadSip` - модель заявки из неразобранного с типом входящий звонок](#%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amoincomingleadsip---%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D0%B7%D0%B0%D1%8F%D0%B2%D0%BA%D0%B8-%D0%B8%D0%B7-%D0%BD%D0%B5%D1%80%D0%B0%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE-%D1%81-%D1%82%D0%B8%D0%BF%D0%BE%D0%BC-%D0%B2%D1%85%D0%BE%D0%B4%D1%8F%D1%89%D0%B8%D0%B9-%D0%B7%D0%B2%D0%BE%D0%BD%D0%BE%D0%BA)\n    - [Методы для загрузки сущностей](#%D0%9C%D0%B5%D1%82%D0%BE%D0%B4%D1%8B-%D0%B4%D0%BB%D1%8F-%D0%B7%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8-%D1%81%D1%83%D1%89%D0%BD%D0%BE%D1%81%D1%82%D0%B5%D0%B9)\n    - [Методы для пакетного сохранения сущностей](#%D0%9C%D0%B5%D1%82%D0%BE%D0%B4%D1%8B-%D0%B4%D0%BB%D1%8F-%D0%BF%D0%B0%D0%BA%D0%B5%D1%82%D0%BD%D0%BE%D0%B3%D0%BE-%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F-%D1%81%D1%83%D1%89%D0%BD%D0%BE%D1%81%D1%82%D0%B5%D0%B9)\n    - [Методы для пакетного удаления сущностей](#%D0%9C%D0%B5%D1%82%D0%BE%D0%B4%D1%8B-%D0%B4%D0%BB%D1%8F-%D0%BF%D0%B0%D0%BA%D0%B5%D1%82%D0%BD%D0%BE%D0%B3%D0%BE-%D1%83%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F-%D1%81%D1%83%D1%89%D0%BD%D0%BE%D1%81%D1%82%D0%B5%D0%B9)\n    - [Методы для webhooks](#%D0%9C%D0%B5%D1%82%D0%BE%D0%B4%D1%8B-%D0%B4%D0%BB%D1%8F-webhooks)\n    - [Методы для неразобранного](#%D0%9C%D0%B5%D1%82%D0%BE%D0%B4%D1%8B-%D0%B4%D0%BB%D1%8F-%D0%BD%D0%B5%D1%80%D0%B0%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE)\n    - [Дополнительные методы](#%D0%94%D0%BE%D0%BF%D0%BE%D0%BB%D0%BD%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D1%8B)\n- [Блокировка одновременного обновления одной сущности](#%D0%91%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0-%D0%BE%D0%B4%D0%BD%D0%BE%D0%B2%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE-%D0%BE%D0%B1%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F-%D0%BE%D0%B4%D0%BD%D0%BE%D0%B9-%D1%81%D1%83%D1%89%D0%BD%D0%BE%D1%81%D1%82%D0%B8)\n- [Троттлинг запросов к API](#%D0%A2%D1%80%D0%BE%D1%82%D1%82%D0%BB%D0%B8%D0%BD%D0%B3-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2-%D0%BA-api)\n- [Отладочный режим и логирование](#%D0%9E%D1%82%D0%BB%D0%B0%D0%B4%D0%BE%D1%87%D0%BD%D1%8B%D0%B9-%D1%80%D0%B5%D0%B6%D0%B8%D0%BC-%D0%B8-%D0%BB%D0%BE%D0%B3%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)\n- [Обработка ошибок](#%D0%9E%D0%B1%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B0-%D0%BE%D1%88%D0%B8%D0%B1%D0%BE%D0%BA)\n- [Примеры](#%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B)\n    - [Работа с контактами](#%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D0%BA%D0%BE%D0%BD%D1%82%D0%B0%D0%BA%D1%82%D0%B0%D0%BC%D0%B8)\n    - [Работа с компаниями](#%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F%D0%BC%D0%B8)\n    - [Работа со сделками](#%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81%D0%BE-%D1%81%D0%B4%D0%B5%D0%BB%D0%BA%D0%B0%D0%BC%D0%B8)\n    - [Работа с событиями](#%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D1%81%D0%BE%D0%B1%D1%8B%D1%82%D0%B8%D1%8F%D0%BC%D0%B8)\n    - [Работа с задачами](#%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B0%D0%BC%D0%B8)\n    - [Работа со списками \\(каталогами\\)](#%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81%D0%BE-%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0%D0%BC%D0%B8-%D0%BA%D0%B0%D1%82%D0%B0%D0%BB%D0%BE%D0%B3%D0%B0%D0%BC%D0%B8)\n    - [Работа с элементами списков \\(каталогов\\)](#%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D0%BC%D0%B8-%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%BE%D0%B2-%D0%BA%D0%B0%D1%82%D0%B0%D0%BB%D0%BE%D0%B3%D0%BE%D0%B2)\n    - [Работа с webhooks](#%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-webhooks)\n    - [Работа с заявками из неразобранного](#%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D0%B7%D0%B0%D1%8F%D0%B2%D0%BA%D0%B0%D0%BC%D0%B8-%D0%B8%D0%B7-%D0%BD%D0%B5%D1%80%D0%B0%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE)\n    - [Поддержка AJAX-запросов к frontend-методам](#%D0%9F%D0%BE%D0%B4%D0%B4%D0%B5%D1%80%D0%B6%D0%BA%D0%B0-ajax-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2-%D0%BA-frontend-%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%B0%D0%BC)\n    - [Работа с несколькими поддоменами](#%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D0%BD%D0%B5%D1%81%D0%BA%D0%BE%D0%BB%D1%8C%D0%BA%D0%B8%D0%BC%D0%B8-%D0%BF%D0%BE%D0%B4%D0%B4%D0%BE%D0%BC%D0%B5%D0%BD%D0%B0%D0%BC%D0%B8)\n    - [Отладка и логирование](#%D0%9E%D1%82%D0%BB%D0%B0%D0%B4%D0%BA%D0%B0-%D0%B8-%D0%BB%D0%BE%D0%B3%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)\n- [UML-диаграмма классов](#uml-%D0%B4%D0%B8%D0%B0%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0-%D0%BA%D0%BB%D0%B0%D1%81%D1%81%D0%BE%D0%B2)\n- [Автор](#%D0%90%D0%B2%D1%82%D0%BE%D1%80)\n- [Лицензия](#%D0%9B%D0%B8%D1%86%D0%B5%D0%BD%D0%B7%D0%B8%D1%8F)\n\n\u003c!-- /MarkdownTOC --\u003e\n\n\u003ca id=\"%D0%A2%D1%80%D0%B5%D0%B1%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F\"\u003e\u003c/a\u003e\n## Требования\n\n- PHP \u003e= 7.0.\n- Произвольный автозагрузчик классов, реализующий стандарт [PSR-4](https://www.php-fig.org/psr/psr-4/).\n\n\u003ca id=\"%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0\"\u003e\u003c/a\u003e\n## Установка\n\nУстановка через composer:\n```\n$ composer require andrey-tech/amocrm-api-php:\"^2.7\"\n```\n\nили путем добавления:\n\n```\n\"andrey-tech/amocrm-api-php\": \"^2.7\"\n```\n\nв секцию require файла composer.json.\n\n\u003ca id=\"%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F\"\u003e\u003c/a\u003e\n## Авторизация\n\n\u003ca id=\"%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F-%D0%BF%D0%BE-%D0%BF%D1%80%D0%BE%D1%82%D0%BE%D0%BA%D0%BE%D0%BB%D1%83-oauth-20-%D0%B0%D0%BA%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9-%D0%BC%D0%B5%D1%82%D0%BE%D0%B4\"\u003e\u003c/a\u003e\n### Авторизация по протоколу oAuth 2.0 ([актуальный метод](https://www.amocrm.ru/developers/content/oauth/oauth))\n\n- `static AmoAPI::oAuth2(string $subdomain, string $clientId, string $clientSecret, string $redirectUri, string $authCode = null) :array`  \n    - `$subdomain` - поддомен или полный домен amoCRM;\n    - `$clientId` - ID интеграции;\n    - `$clientSecret` - секрет интеграции;\n    - `$redirectUri` - URI перенаправления;\n    - `$authCode` - код авторизации (временный ключ) для обмена на access токен и refresh токен.\n\n\u003ca id=\"%D0%9F%D0%B5%D1%80%D0%B2%D0%B8%D1%87%D0%BD%D0%B0%D1%8F-%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F-%D0%B8-%D0%BE%D0%B1%D0%BC%D0%B5%D0%BD-%D0%BA%D0%BE%D0%B4%D0%B0-%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8-%D0%BD%D0%B0-access-%D1%82%D0%BE%D0%BA%D0%B5%D0%BD-%D0%B8-refresh-%D1%82%D0%BE%D0%BA%D0%B5%D0%BD\"\u003e\u003c/a\u003e\n#### Первичная авторизация и обмен кода авторизации на access токен и refresh токен\n\nПри первичной авторизации производится [обмен кода авторизации](https://www.amocrm.ru/developers/content/oauth/step-by-step#get_access_token) `authCode`\nна access токен и refresh токен, которые сохраняются в хранилище токенов вместе с переданными значениями `$clientId`, `$clientSecret` и `$redirectUri`.\n\n```php\nuse AmoCRM\\{AmoAPI, AmoAPIException};\nuse AmoCRM\\TokenStorage\\TokenStorageException;\n\ntry {\n    // Параметры авторизации по протоколу oAuth 2.0\n    $clientId     = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';\n    $clientSecret = 'TFPoaG2A5hp3G3o6opCL8eC9v92Mm0fKQWEHBDwIjedCmVliT4kI3XQcjOOP1s';\n    $authCode     = 'eee60208cc09e3ae3506d667228038345b6578a11d4862094655f630074c8c6ed87a9d804d49b5880e';\n    $redirectUri  = 'https://www.example.com/oauth2/';\n    $subdomain    = 'testsubdomain';\n\n    // Первичная авторизация\n    AmoAPI::oAuth2($subdomain, $clientId, $clientSecret, $redirectUri, $authCode);\n\n    // Получение информации об аккаунте вместе с пользователями и группами\n    print_r(AmoAPI::getAccount($with = 'users,groups'));\n\n} catch (AmoAPIException $e) {\n    printf('Ошибка авторизации (%d): %s' . PHP_EOL, $e-\u003egetCode(), $e-\u003egetMessage());\n} catch (TokenStorageException $e) {\n    printf('Ошибка обработки токенов (%d): %s' . PHP_EOL, $e-\u003egetCode(), $e-\u003egetMessage());\n}\n```\n\n\u003ca id=\"%D0%9F%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D1%83%D1%8E%D1%89%D0%B8%D0%B5-%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8\"\u003e\u003c/a\u003e\n#### Последующие авторизации\n\nПосле первичного обмена кода авторизации на access токен и refresh токен, при последующих авторизациях, \nдостаточно передать только `$subdomain` - поддомен или полный домен amoCRM.\n\n```php\nuse AmoCRM\\{AmoAPI, AmoAPIException};\nuse AmoCRM\\TokenStorage\\TokenStorageException;\n\ntry {\n\n    // Последующие авторизации\n    $subdomain = 'testsubdomain';\n    AmoAPI::oAuth2($subdomain);\n\n    // Получение информации об аккаунте\n    print_r(AmoAPI::getAccount());\n\n} catch (AmoAPIException $e) {\n    printf('Ошибка авторизации (%d): %s' . PHP_EOL, $e-\u003egetCode(), $e-\u003egetMessage());\n} catch (TokenStorageException $e) {\n    printf('Ошибка обработки токенов (%d): %s' . PHP_EOL, $e-\u003egetCode(), $e-\u003egetMessage());\n}\n```\n\nПолучение нового access токена и refresh токена по истечении срока действия access токена происходит автоматически,\nкогда на запрос к API amoCRM приходит ответ с HTTP-статусом `401 Unauthorized`.\n\n\u003ca id=\"%D0%A5%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5-access-%D0%B8-refresh-%D1%82%D0%BE%D0%BA%D0%B5%D0%BD%D0%BE%D0%B2\"\u003e\u003c/a\u003e\n#### Хранение access и refresh токенов\n\nСохранение и загрузка токенов выполняется с помощью классов, реализующих интерфейс `\\AmoCRM\\TokenStorage\\TokenStorageInterface`.\n\n\u003ca id=\"%D0%98%D0%BD%D1%82%D0%B5%D1%80%D1%84%D0%B5%D0%B9%D1%81-tokenstorageinterface\"\u003e\u003c/a\u003e\n##### Интерфейс `TokenStorageInterface`\n\nВ интерфейсе `\\AmoCRM\\TokenStorage\\TokenStorageInterface` определены три метода:\n\n- `save(array $tokens, string $domain) :void` Сохраняет параметры авторизации и токены.\n    * `$tokens` - ассоциативный массив параметров авторизации и токенов:  \n       `[ 'access_token' =\u003e '...', 'refresh_token' =\u003e '...', 'client_id' =\u003e '...', 'client_secret' =\u003e '...', 'redirect_uri'=\u003e '...' ]`;\n    * `$domain` - полный домен amoCRM (например, `testsubdomain.amocrm.ru`).\n- `load(string $domain) :?array` Загружает параметры авторизации и токены и возвращает их.\n    Метод должен возвращать `null`, когда нет сохраненных токенов.\n    * `$domain` - полный домен amoCRM.\n- `hasTokens(string $domain) :bool` Проверяет существуют ли токены для заданного домена amoCRM, то есть была ли выполнена первичная авторизация.\n    * `$domain` - полный домен amoCRM.\n\n\u003ca id=\"%D0%9A%D0%BB%D0%B0%D1%81%D1%81-filestorage\"\u003e\u003c/a\u003e\n##### Класс `FileStorage`\n\nПо умолчанию для сохранения и загрузки токенов используется класс `\\AmoCRM\\TokenStorage\\FileStorage`,\nреализующий интерфейс `\\AmoCRM\\TokenStorage\\TokenStorageInterface`.\nКласс хранит токены в JSON-файлах, с именами, соответствующими именам доменов amoCRM (например, `testsubdomain.amocrm.ru.json`).  \n\nВ параметрах, передаваемых конструктору класса, можно указать каталог для хранения файлов токенов:\n\n- `__construct(string $storageFolder = '')` Конструктор класса.\n    * `$storageFolder` - каталог для хранения файлов токенов. Может быть задан абсолютный путь\nили путь относительно текущего рабочего каталога. Если передана пустая строка, то создается каталог по умолчанию - 'tokens'. \n\nПри возникновении ошибок выбрасывается исключение класса `\\AmoCRM\\TokenStorage\\TokenStorageException`. \n\n\u003ca id=\"%D0%98%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5-%D1%81%D0%BE%D0%B1%D1%81%D1%82%D0%B2%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE-%D0%BA%D0%BB%D0%B0%D1%81%D1%81%D0%B0-%D0%B4%D0%BB%D1%8F-%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F-%D1%82%D0%BE%D0%BA%D0%B5%D0%BD%D0%BE%D0%B2\"\u003e\u003c/a\u003e\n##### Использование собственного класса для сохранения токенов\n\nПример использования собственного класса для сохранения токенов в базе данных:\n```php\nuse AmoCRM\\{AmoAPI, AmoAPIException};\nuse AmoCRM\\TokenStorage\\DatabaseStorage;\n\ntry {\n    // Параметры авторизации по протоколу oAuth 2.0\n    $clientId     = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';\n    $clientSecret = 'TFPoaG2A5hp3G3o6opCL8eC9v92Mm0fKQWEHBDwIjedCmVliT4kI3XQcjOOP1s';\n    $authCode     = 'eee60208cc09e3ae3506d667228038345b6578a11d4862094655f630074c8c6ed87a9d804d49b5880e';\n    $redirectUri  = 'https://www.example.com/oauth2/';\n    $subdomain    = 'testsubdomain';\n\n    // Устанавливаем объект класса, обеспечивающего сохранение токенов\n    AmoAPI::$tokenStorage = new DatabaseStorage();\n\n    // Авторизация\n    AmoAPI::oAuth2($subdomain, $clientId, $clientSecret, $redirectUri, $authCode);\n\n    // Получение информации об аккаунте\n    print_r(AmoAPI::getAccount());\n\n} catch (AmoAPIException $e) {\n    printf('Ошибка авторизации (%d): %s' . PHP_EOL, $e-\u003egetCode(), $e-\u003egetMessage());\n}\n```\n\nПример класса `\\AmoCRM\\TokenStorage\\DatabaseStorage`:\n```php\n\u003c?php\nnamespace AmoCRM\\TokenStorage;\n\nclass DatabaseStorage implements TokenStorageInterface\n{\n    /**\n     * Сохраняет токены\n     * @param  array  $tokens Токены для сохранения\n     * @param  string $domain Полный домен amoCRM\n     * @return void\n     */\n    public function save(array $tokens, string $domain)\n    {\n        // Здесь токены сохраняются в базе данных\n    }\n\n    /**\n     * Загружает токены\n     * @param  string $domain Полный домен amoCRM\n     * @return array|null\n     */\n    public function load(string $domain)\n    {\n        // Здесь токены извлекаются из базы данных\n    }\n\n    /**\n     * Проверяет: существуют ли токены для заданного домена amoCRM,\n     * то есть была ли выполнена первичная авторизация\n     * @param  string  $domain Полный домен amoCRM\n     * @return boolean\n     */\n    public function hasTokens(string $domain) :bool\n    {\n        // Здесь проверяется наличие токенов в базе данных\n    }\n}\n```\n\n\u003ca id=\"%D0%9F%D1%80%D0%BE%D0%B2%D0%B5%D1%80%D0%BA%D0%B0-%D0%BD%D0%B0%D0%BB%D0%B8%D1%87%D0%B8%D1%8F-%D0%BF%D0%B5%D1%80%D0%B2%D0%B8%D1%87%D0%BD%D0%BE%D0%B9-%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D0%B8\"\u003e\u003c/a\u003e\n#### Проверка наличия первичной авторизации\n\nЧтобы проверить, происходила ли первичная авторизация для нужного поддомена amoCRM,\nможно воспользоваться методом hasTokens() интерфейса `\\AmoCRM\\TokenStorage\\TokenStorageInterface`:\n\n```php\nuse AmoCRM\\{AmoAPI, AmoAPIException};\nuse AmoCRM\\TokenStorage\\{FileStorage, TokenStorageException};\n\ntry {\n\n    // Параметры авторизации по протоколу oAuth 2.0\n    $clientId     = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';\n    $clientSecret = 'TFPoaG2A5hp3G3o6opCL8eC9v92Mm0fKQWEHBDwIjedCmVliT4kI3XQcjOOP1s';\n    $authCode     = 'eee60208cc09e3ae3506d667228038345b6578a11d4862094655f630074c8c6ed87a9d804d49b5880e';\n    $redirectUri  = 'https://www.example.com/oauth2/';\n    $subdomain    = 'testsubdomain';\n\n    AmoAPI::$tokenStorage = new FileStorage();\n\n    $domain = AmoAPI::getAmoDomain($subdomain);\n    $isFirstAuth = ! AmoAPI::$tokenStorage-\u003ehasTokens($domain);\n\n    if ($isFirstAuth) {\n        // Первичная авторизация\n        AmoAPI::oAuth2($subdomain, $clientId, $clientSecret, $redirectUri, $authCode);\n    } else {\n        // Последующие авторизации\n        AmoAPI::oAuth2($subdomain);\n    }\n\n} catch (AmoAPIException $e) {\n    printf('Ошибка авторизации (%d): %s' . PHP_EOL, $e-\u003egetCode(), $e-\u003egetMessage());\n} catch (TokenStorageException $e) {\n    printf('Ошибка обработки токенов (%d): %s' . PHP_EOL, $e-\u003egetCode(), $e-\u003egetMessage());\n}\n```\n\n\u003ca id=\"%D0%90%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F-%D0%BF%D0%BE-api-%D0%BA%D0%BB%D1%8E%D1%87%D1%83-%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8F-%D1%83%D1%81%D1%82%D0%B0%D1%80%D0%B5%D0%B2%D1%88%D0%B8%D0%B9-%D0%BC%D0%B5%D1%82%D0%BE%D0%B4\"\u003e\u003c/a\u003e\n### Авторизация по API-ключу пользователя ([устаревший метод](https://www.amocrm.ru/developers/content/oauth/old))\n\nС 1 июля 2020 г. информация о API-ключе пользователя стала недоступна в интерфейсе amoCRM.\n\n- `static AmoAPI::oauth(string $login, string $hash, string $subdomain) :array`\n    - `$login` - логин пользователя;\n    - `$hash` - API-ключ пользователя;\n    - `$subdomain` - поддомен или полный домен amoCRM.\n\nПример авторизации по API-ключу пользователя.\n```php\nuse \\AmoCRM\\{AmoAPI, AmoAPIException};\n\ntry {\n    // Параметры авторизации по API-ключу пользователя\n    $login     = 'login@example.com';\n    $hash      = 'TFPoaG2A5hp3G3o6opCL8eC9v92Mm0fKQWEHBDwIjedCmVliT4kI3XQcjOOP1s';\n    $subdomain = 'testsubdomain';\n\n    // Авторизация\n    AmoAPI::auth($login, $hash, $subdomain);\n\n    // Получение информации об аккаунте\n    print_r(AmoAPI::getAccount());\n\n} catch (AmoAPIException $e) {\n    printf('Ошибка авторизации (%d): %s' . PHP_EOL, $e-\u003egetCode(), $e-\u003egetMessage());\n}\n```\n\n\u003ca id=\"%D0%9E%D0%B4%D0%BD%D0%BE%D0%B2%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F-%D0%B0%D0%B2%D1%82%D0%BE%D1%80%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F-%D0%B2-%D0%BD%D0%B5%D1%81%D0%BA%D0%BE%D0%BB%D1%8C%D0%BA%D0%B8%D1%85-%D0%B0%D0%BA%D0%BA%D0%B0%D1%83%D0%BD%D1%82%D0%B0%D1%85-amocrm\"\u003e\u003c/a\u003e\n### Одновременная авторизация в нескольких аккаунтах amoCRM\n\nБиблиотека позволяет одновременно работать с несколькими поддоменами (аккаунтами) amoCRM.\nДля этого необходимо последовательно выполнить авторизацию в каждом их поддоменов.\n\n```php\nuse AmoCRM\\{AmoAPI, AmoAPIException};\n\ntry {\n    // Авторизация в поддомене 1\n    AmoAPI::oAuth2($subdomain1, $clientId1, $clientSecret1, $redirectUri1, $authCode1);\n\n    // Авторизация в поддомене 2\n    AmoAPI::auth($login2, $hash2, $subdomain2);\n\n    //...\n\n    // Авторизация в поддомене N\n    AmoAPI::oAuth2($subdomainN, $clientIdN, $clientSecretN, $redirectUriN, $authCodeN);\n\n} catch (AmoAPIException $e) {\n    printf('Ошибка авторизации (%d): %s' . PHP_EOL, $e-\u003egetCode(), $e-\u003egetMessage());\n}\n```\n\n\u003ca id=\"%D0%9F%D0%B0%D1%80%D0%B0%D0%BC%D0%B5%D1%82%D1%80%D1%8B-%D0%BD%D0%B0%D1%81%D1%82%D1%80%D0%BE%D0%B9%D0%BA%D0%B8\"\u003e\u003c/a\u003e\n## Параметры настройки\n\nВсе параметры настройки библиотеки устанавливаются через статические свойства класса `AmoAPI`.\n\n| Свойство                | По умолчанию            | Описание                                                                                                                                                                                               |\n|-------------------------|-------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `$debug`                | false                   | Включает отладочный режим с выводом запросов/ответов в API в STDOUT                                                                                                                                    |\n| `$debugLogger`          | null                    | Устанавливает объект класса, выполняющего логирование и реализующего стандарт [PSR-3](https://www.php-fig.org/psr/psr-3/)                                                                              |\n| `$throttle`             | 7                       | Устанавливает максимальное число запросов к API amoCRM в секунду ([не более 7 запросов в секунду](https://www.amocrm.ru/developers/content/api/recommendations))                                       |\n| `$verifySSLCerfificate` | true                    | Включает проверку SSL/TLS-сертификата сервера amoCRM                                                                                                                                                   |\n| `$SSLCertificateFile`   | 'cacert.pem'            | Устанавливает файл SSL/TLS-сертификатов X.509 корневых удостоверяющих центров (CA) в формате РЕМ (null - использовать файл, указанный в параметре curl.cainfo файла php.ini)                           |\n| `$amoDomain`            | 'amocrm.ru'             | Устанавливает домен для запросов к API amoCRM                                                                                                                                                          |\n| `$amoUserAgent`         | 'amoCRM-API-client/2.0' | Устанавливает НТТР заголовок UserAgent в запросах                                                                                                                                                      |\n| `$amoConnectTimeout`    | 30                      | Устанавливает таймаут соединения с сервером аmoCRM, секунды                                                                                                                                            |\n| `$amoTimeout`           | 30                      | Устанавливает таймаут обмена данными с сервером аmoCRM, секунды                                                                                                                                        |\n| `$reAuthTimeout`        | 5                       | Устанавливает таймаут перед повторной авторизацией по API-ключу пользователя при ответе сервера '401 Unauthorized', секунды                                                                            |\n| `$reAuthAttempts`       | 3                       | Устанавливает максимальное число попыток повторной авторизации по API-ключу пользователя при ответе сервера '401 Unauthorized'                                                                         |\n| `$cookieFileDir`        | 'cookies/'              | Устанавливает относительный каталог для хранения файлов cookie                                                                                                                                         |\n| `$lockEntityDir`        | 'lock/'                 | Устанавливает каталог для хранения lock-файлов блокировки обновления сущностей при вызове метода `AmoObject::save()`                                                                                   |\n| `$lockEntityAttempts`   | 10                      | Устанавливает максимальное число попыток блокировки обновления сущности при вызове метода `AmoObject::save()` (0 - блокировка не выполняется)                                                          |\n| `$lockEntityTimeout`    | 1                       | Устанавливает таймаут между попытками блокировки обновления сущности при вызове метода `AmoObject::save()`, секунды                                                                                    |\n| `$limitRows`            | 500                     | Устанавливает максимальное количество сущностей, выбираемых за один запрос к серверу amoCRM ([не более 500, рекомендуется не более 250](https://www.amocrm.ru/developers/content/api/recommendations)) |\n| `$tokenStorage`         | object                  | Устанавливает объект класса, обеспечивающего сохранение токенов oAuth 2.0 и реализующего интерфейс `TokenStorageInterface`. По умолчанию объект класса `FileStorage`                                   |\n| `$successStatusCodes`   | `[ 200, 202, 204 ]`     | Коды состояния НТТР, соответствующие успешному выполнению запроса                                                                                                                                      |\n\n\u003ca id=\"%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D1%81%D1%83%D1%89%D0%BD%D0%BE%D1%81%D1%82%D1%8F%D0%BC%D0%B8-amocrm\"\u003e\u003c/a\u003e\n## Работа с сущностями amoCRM\n\nРабота с сущностями amoCRM строится с помощью:\n\n- методов классов-моделей:\n    - `AmoContact` - модель контакта;\n    - `AmoCompany` - модель компании;\n    - `AmoLead` - модель сделки;\n    - `AmoNote` - модель события (примечания);\n    - `AmoTask` - модель задачи;\n    - `AmoCatalog` - модель списка (каталога);\n    - `AmoCatalogElement` - модель элемента списка (каталога);\n    - `AmoIncomingLead` - абстрактная базовая модель заявки из неразобранного;\n    - `AmoIncomingLeadForm` - модель заявки из неразобранного при добавлении заявки из веб-формы;\n    - `AmoIncomingLeadSip` - модель заявки из неразобранного с типом входящий звонок.\n- дополнительных статических методов класса `AmoAPI`;\n- параметров моделей, доступных через публичные свойства объектов классов-моделей.\n\n\u003ca id=\"%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA-%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D0%BE%D0%B2-%D0%B8-%D0%BA%D0%BE%D0%BD%D1%81%D1%82%D0%B0%D0%BD%D1%82-%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D0%B5%D0%B9\"\u003e\u003c/a\u003e\n### Список методов и констант моделей\n\n\u003ca id=\"%D0%91%D0%B0%D0%B7%D0%BE%D0%B2%D1%8B%D0%B9-%D0%BA%D0%BB%D0%B0%D1%81%D1%81-%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D0%B5%D0%B9-amoobject\"\u003e\u003c/a\u003e\n#### Базовый класс моделей `AmoObject`\n\nАбстрактный базовый класс всех моделей - `AmoObject` содержит следующие общие методы:\n\n- `__construct(array $params = [], string $subdomain = null)` Создает новый объект модели и заполняет ее.\n    + `$params` - параметры модели;\n    + `$subdomain` - поддомен или полный домен amoCRM. Если null, то используется поддомен последней авторизации.\n- `fillById(int|string $id, array $params = []) :AmoObject` Заполняет модель данными по ID сущности.\n    + `$id` - ID сущности;\n    + `$params` - дополнительные параметры, передаваемые в GET-запросе к amoCRM.\n- `getParams() :array` Возвращает все параметры модели.\n- `getCustomFields(array|int $ids) :array` Возвращает дополнительные поля по ID полей.\n    + `$ids` - ID поля или массив ID полей.\n- `getCustomFieldValueById(int $id, bool $returnFirst = true, string $returnValue = 'value')` Возвращает значение дополнительного поля по ID поля.\n    + `$i` - ID поля;\n    + `$returnFirst` - вернуть только первое значение из списка значений;\n    + `$returnValue` - имя параметра, значение которого возвращается (`value`, `enum`, `subtype`).\n- `setCustomFields(array $params) :AmoObject` Устанавливает значения дополнительных полей.\n    + `$params` - массив значений дополнительных полей.\n- `addTags(array|string $tags) :AmoObject` Добавляет теги.\n    + `$tags` - тег или массив тегов.\n- `delTags(array|string $tags) :AmoObject` Удаляет теги. \n    + `$tags` - тег или массив тегов.\n- `save(bool $returnResponse = false)` Сохраняет объект модели в amoCRM и возвращает ID сущности. \n    + `$returnResponse` - вернуть ответ сервера вместо ID сущности.\n\nКонстанты, определяющие типы привязываемых сущностей:\n\n- `CONTACT_TYPE = 1` - контакт;\n- `LEAD_TYPE = 2` - сделка;\n- `COMPANY_TYPE = 3` - компания;\n- `TASK_TYPE = 4` - задача;\n- `CUSTOMER_TYPE = 12` - покупатель.\n\n\u003ca id=\"%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amocontact---%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D0%BA%D0%BE%D0%BD%D1%82%D0%B0%D0%BA%D1%82%D0%B0\"\u003e\u003c/a\u003e\n#### Класс `AmoContact` - модель контакта\n\n- `addLeads(array|int $id)` Привязывает сделки по ID.\n- `addCustomers(array|int $id)` Привязывает покупателей по ID.\n- `addCompany(int $id)` Привязывает компанию по ID.\n- `getPhone()` Возвращает первый телефон контакта.\n- `getEmail()` Возвращает первый e-mail контакта.\n\n\u003ca id=\"%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amocompany---%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D0%B8\"\u003e\u003c/a\u003e\n#### Класс `AmoCompany` - модель компании\n\n- `addLeads(array|int $id)` Привязывает сделки по ID.\n- `addContacts(array|int $id)` Привязывает контакты по ID.\n- `addCustomers(array|int $id)` Привязывает покупателей по ID.\n- `getPhone()` Возвращает первый телефон компании.\n- `getEmail()` Возвращает первый e-mail компании.\n\n\u003ca id=\"%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amolead---%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D1%81%D0%B4%D0%B5%D0%BB%D0%BA%D0%B8\"\u003e\u003c/a\u003e\n#### Класс `AmoLead` - модель сделки\n\n⚠ \u0026nbsp; Для заявок из неразобранного существуют [специальные методы](#%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amoincominglead---%D0%B1%D0%B0%D0%B7%D0%BE%D0%B2%D0%B0%D1%8F-%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D0%B7%D0%B0%D1%8F%D0%B2%D0%BA%D0%B8-%D0%B8%D0%B7-%D0%BD%D0%B5%D1%80%D0%B0%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE).\n\n- `addContacts(array|int $id)` Привязывает контакты по ID контакта(ов) ([не более 40 контактов у одной сделки](https://www.amocrm.ru/developers/content/api/leads)).\n- `removeContacts(array|int $id)` Отвязывает контакты по ID контакта(ов).\n- `addCompany(int $id)` Привязывает компанию по ID компании.\n- `removeCompany(int $id)` Отвязывает компанию по ID компании.\n- `setCatalogElements(array $catalogElements)` Устанавливает элементы списков (каталогов) по ID списков.\n\n\u003ca id=\"%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amotask---%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B8\"\u003e\u003c/a\u003e\n#### Класс `AmoTask` - модель задачи\n\n- `addContact(int $id)` Привязывает контакт по ID.\n- `addLead(int $id)` Привязывает сделку по ID.\n\nКонстанты класса, определяющие типы задач:\n\n- `CALL_TASKTYPE = 1` - звонок;\n- `MEET_TASKTYPE = 2` - встреча;\n- `MAIL_TASKTYPE = 3` - написать письмо.\n\n\u003ca id=\"%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amonote---%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D1%81%D0%BE%D0%B1%D1%8B%D1%82%D0%B8%D1%8F-%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%87%D0%B0%D0%BD%D0%B8%D1%8F\"\u003e\u003c/a\u003e\n#### Класс `AmoNote` - модель события (примечания)\n\nКонстанты класса, определяющие типы событий:\n\n- `LEAD_CREATED_NOTETYPE = 1` - создание сделки;\n- `CONTACT_CREATED_NOTETYPE = 2` - создание контакта;\n- `LEAD_STATUS_CHANGED_NOTETYPE = 3` - изменение статуса сделки;\n- `COMMON_NOTETYPE = 4` - обычное примечание;\n- `COMPANY_CREATED_NOTETYPE = 12` - создание компании;\n- `TASK_RESULT_NOTETYPE = 13`  результат по задаче;\n- `SYSTEM_NOTETYPE = 25` - системное сообщение;\n- `SMS_IN_NOTETYPE = 102` - входящее SMS сообщение;\n- `SMS_OUT_NOTETYPE = 103` - исходящее SMS сообщение.\n\n\u003ca id=\"%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amocatalog---%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0-%D0%BA%D0%B0%D1%82%D0%B0%D0%BB%D0%BE%D0%B3%D0%B0\"\u003e\u003c/a\u003e\n#### Класс `AmoCatalog` - модель списка (каталога)\n\nКласс `AmoCatalog` не имеет собственных специфических методов.\n\n\u003ca id=\"%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amocatalogelement---%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%B0-%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0-%D0%BA%D0%B0%D1%82%D0%B0%D0%BB%D0%BE%D0%B3%D0%B0\"\u003e\u003c/a\u003e\n#### Класс `AmoCatalogElement` - модель элемента списка (каталога)\n\nКласс `AmoCatalogElement` не имеет собственных специфических методов.\n\n\u003ca id=\"%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amoincominglead---%D0%B1%D0%B0%D0%B7%D0%BE%D0%B2%D0%B0%D1%8F-%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D0%B7%D0%B0%D1%8F%D0%B2%D0%BA%D0%B8-%D0%B8%D0%B7-%D0%BD%D0%B5%D1%80%D0%B0%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE\"\u003e\u003c/a\u003e\n#### Класс `AmoIncomingLead` - базовая модель заявки из неразобранного\n\nРабота с заявками из неразобранного существенно отличается от работы с другими сущностями amoCRM.  \nСогласно официальной документации:\n\u003e Изначально неразобранное было в отдельном хранилище и являлось отдельной сущностью именно поэтому до сих пор в интерфейсах amoCRM и в API есть особенности которые отличают поведение сделки в статусе Неразобранное от сделок в других статусах.\n\n⚠ \u0026nbsp; Поэтому для моделей заявок из неразобранного не работают следующие методы класса `AmoObject`:\n\n- `fillById()`;\n- `getCustomFields()`;\n- `getCustomFieldValueById()`;\n- `setCustomFields()`;\n- `addTags()`;\n- `delTags()`;\n- `AmoAPI::saveObjects()`;\n- `AmoAPI::saveObjectsWithLimit()`.\n\n\u003ca id=\"%D0%9E%D0%B1%D1%89%D0%B8%D0%B5-%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D1%8B-%D0%B4%D0%BB%D1%8F-%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D1%8B-%D1%81-%D0%B7%D0%B0%D1%8F%D0%B2%D0%BA%D0%B0%D0%BC%D0%B8-%D0%B8%D0%B7-%D0%BD%D0%B5%D1%80%D0%B0%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE\"\u003e\u003c/a\u003e\n##### Общие методы для работы с заявками из неразобранного\n\nАбстрактный базовый класс модели заявки из неразобранного - `AmoIncomingLead` содержит следующие методы:\n\n- `fillByUid(int|string $uid, array $params = []) :AmoObject` Заполняет модель заявки данными по UID заявки.\n    + `$uid` - UID сущности;\n    + `$params` - дополнительные параметры, передаваемые в GET-запросе к amoCRM.\n- `setIncomingLeadInfo(array $params) :AmoIncomingLead` Устанавливает параметры заявки из неразобранного.\n    + `$params` - параметры неразобранного.\n- `addIncomingLead(AmoLead|array $lead) :AmoIncomingLeadSip` Добавляет параметры сделки.\n    + `$lead` - объект класса `AmoLead` или массив параметров сделки.\n- `addIncomingContact(AmoContact|array $contact) :AmoIncomingLead` Добавляет параметры контакта.\n    + `$contact` - объект класса `AmoContact` или массив параметров контакта.\n- `addIncomingCompany(AmoCompany|array $company) :AmoIncomingLead` Добавляет параметры компании.\n    + `$company` - объект класса `AmoCompany` или массив параметров компании.\n- `save(bool $returnResponse = false)` Добавляет новую заявку в неразобранное и возвращает массив, содержащий UID заявки.\n    + `$returnResponse` - вернуть ответ сервера вместо UID.\n\nСтатические методы для пакетного добавления заявок в amoCRM, а также для принятия или отклонения неразобранных заявок находятся в классе `AmoAPI`.\n\n\u003ca id=\"%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amoincomingleadform---%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D0%B7%D0%B0%D1%8F%D0%B2%D0%BA%D0%B8-%D0%B8%D0%B7-%D0%BD%D0%B5%D1%80%D0%B0%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE-%D0%BF%D1%80%D0%B8-%D0%B4%D0%BE%D0%B1%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B8-%D0%B8%D0%B7-%D0%B2%D0%B5%D0%B1-%D1%84%D0%BE%D1%80%D0%BC%D1%8B\"\u003e\u003c/a\u003e\n##### Класс `AmoIncomingLeadForm` - модель заявки из неразобранного при добавлении из веб-формы\n\nДочерний класс `AmoIncomingLeadForm` не имеет собственных специфических методов.\n\n\u003ca id=\"%D0%9A%D0%BB%D0%B0%D1%81%D1%81-amoincomingleadsip---%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C-%D0%B7%D0%B0%D1%8F%D0%B2%D0%BA%D0%B8-%D0%B8%D0%B7-%D0%BD%D0%B5%D1%80%D0%B0%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE-%D1%81-%D1%82%D0%B8%D0%BF%D0%BE%D0%BC-%D0%B2%D1%85%D0%BE%D0%B4%D1%8F%D1%89%D0%B8%D0%B9-%D0%B7%D0%B2%D0%BE%D0%BD%D0%BE%D0%BA\"\u003e\u003c/a\u003e\n##### Класс `AmoIncomingLeadSip` - модель заявки из неразобранного с типом входящий звонок\n\nДочерний класс `AmoIncomingLeadSip` не имеет собственных специфических методов.\n\n\u003ca id=\"%D0%9C%D0%B5%D1%82%D0%BE%D0%B4%D1%8B-%D0%B4%D0%BB%D1%8F-%D0%B7%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BA%D0%B8-%D1%81%D1%83%D1%89%D0%BD%D0%BE%D1%81%D1%82%D0%B5%D0%B9\"\u003e\u003c/a\u003e\n### Методы для загрузки сущностей\n\nКласс `AmoAPI` содержит следующие общие статические методы для загрузки сущностей:\n\n- `static getAll\u003cEntities\u003e (array $params, bool $returnResponse = false, string $subdomain = null) :\\Generator`\n    Загружает ВСЕ сущности заданного типа \u003cEntities\\\u003e c возможностью фильтрации.  \n    Возвращает объект типа \\Generator для последующей выборки параметров сущностей.\n    - `\u003cEntities\u003e`:\n        - Contacts\n        - Companies\n        - Leads\n        - Tasks\n        - Notes\n        - CatalogElements\n        - IncomingLeads\n    - `$params` - параметры фильтрации;\n    - `$returnResponse` - возвращать полный ответ сервера amoCRM вместо массива параметров сущностей;\n    - `$subdomain` - поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.\n- `static get\u003cEntities\u003e(array $params, bool $returnResponse = false, string $subdomain = null) :?array`  \n    Загружает сущности заданного типа \u003cEntities\\\u003e c возможностью фильтрации и постраничной выборки.  \n    Возвращает массив параметров сущностей для заполнения моделей или null.\n    - `\u003cEntities\u003e`:\n        - Contacts\n        - Companies\n        - Leads\n        - Tasks\n        - Notes\n        - Webhooks\n        - Widgets\n        - IncomingLeads\n        - IncomingLeadsSummary\n        - Pipelines\n        - Catalogs\n        - CatalogElements\n    - `$params` - параметры фильтрации и постраничной выборки;\n    - `$returnResponse` - возвращать полный ответ сервера amoCRM вместо массива параметров сущностей;\n    - `$subdomain` - поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.\n\n\n\u003ca id=\"%D0%9C%D0%B5%D1%82%D0%BE%D0%B4%D1%8B-%D0%B4%D0%BB%D1%8F-%D0%BF%D0%B0%D0%BA%D0%B5%D1%82%D0%BD%D0%BE%D0%B3%D0%BE-%D1%81%D0%BE%D1%85%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D1%8F-%D1%81%D1%83%D1%89%D0%BD%D0%BE%D1%81%D1%82%D0%B5%D0%B9\"\u003e\u003c/a\u003e\n### Методы для пакетного сохранения сущностей\n\nКласс `AmoAPI` содержит статические методы для пакетного сохранения (добавления или обновления) за один запрос до 500\nсущностей различного типа для одного поддомена amoCRM.\n\nСогласно [официальной документации](https://www.amocrm.ru/developers/content/api/recommendations):\n\u003e Максимальное кол-во создаваемых/изменяем сущностей не более 500, для более оптимальной работы интеграции и избежания ошибок, рекомендуется не более 250. В случае получения 504 ошибки рекомендуется уменьшить количество передаваемых сущностей в запросе и повторить запрос.\n\n- `static saveObjects(array $amoObjects, bool $returnResponses = false, string $subdomain = null) :array`  \n    Добавляет или обновляет сущности в amoCRM. Возвращает массив параметров сущностей.\n    - `$amoObjects` Массив объектов классов-моделей (не более 500 объектов одного типа): `AmoContact`, `AmoCompany`,...;\n    - `$returnResponses` - возвращать массив ответов сервера amoCRM вместо массива параметров сущностей;\n    - `$subdomain` - поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.\n- `static saveObjectsWithLimit(array $amoObjects, bool $returnResponses = false, string $subdomain = null, $limit = 250) :array`  \n    Добавляет или обновляет сущности в amoCRM с ограничением на число сущностей в одном запросе к API. Возвращает массив параметров сущностей.\n    - `$amoObjects` Массив объектов классов-моделей: `AmoContact`, `AmoCompany`,...;\n    - `$returnResponses` - возвращать массив ответов сервера amoCRM вместо массива параметров сущностей;\n    - `$subdomain` - поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации;\n    - `$limit` - максимальное число сущностей в одном запросе к API.\n\n\n\u003ca id=\"%D0%9C%D0%B5%D1%82%D0%BE%D0%B4%D1%8B-%D0%B4%D0%BB%D1%8F-%D0%BF%D0%B0%D0%BA%D0%B5%D1%82%D0%BD%D0%BE%D0%B3%D0%BE-%D1%83%D0%B4%D0%B0%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F-%D1%81%D1%83%D1%89%D0%BD%D0%BE%D1%81%D1%82%D0%B5%D0%B9\"\u003e\u003c/a\u003e\n### Методы для пакетного удаления сущностей\n\nКласс `AmoAPI` содержит статический метод для пакетного удаления списков и элементов списков:\n\n- `static delteObjects(array $amoObjects, bool $returnResponses = false, string $subdomain = null) :array`  \n    Удаляет сущности в amoCRM. Возвращает пустой массив параметров сущностей.\n    - `$amoObjects` Массив объектов классов-моделей: `AmoCatalog` или `AmoCatalogElement`;\n    - `$returnResponses` - возвращать массив ответов сервера amoCRM вместо пустого массива параметров сущностей;\n    - `$subdomain` - поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.\n\n\u003ca id=\"%D0%9C%D0%B5%D1%82%D0%BE%D0%B4%D1%8B-%D0%B4%D0%BB%D1%8F-webhooks\"\u003e\u003c/a\u003e\n### Методы для webhooks\n\nКласс `AmoAPI` содержит статические методы для добавления и удаления webhooks:\n\n- `static addWebhooks(array $params, bool $returnResponse = false, string $subdomain = null) :array`  \n    Добавляет один webhook или несколько webhooks (не более 100).\n    - `params` - параметры webhook или массив параметров webhooks;\n    - `$returnResponse` - возвращать массив ответов сервера amoCRM вместо массива параметров webhook;\n    - `$subdomain` - поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.\n- `static deleteWebhooks(array $params, bool $returnResponse = false, string $subdomain = null) :array`  \n    Удаляет один webhook или несколько webhooks (не более 100).\n    - `params` - параметры webhook или массив параметров webhooks;\n    - `$returnResponse` - возвращать массив ответов сервера amoCRM вместо массива параметров webhook;\n    - `$subdomain` - поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.\n\n\u003ca id=\"%D0%9C%D0%B5%D1%82%D0%BE%D0%B4%D1%8B-%D0%B4%D0%BB%D1%8F-%D0%BD%D0%B5%D1%80%D0%B0%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE\"\u003e\u003c/a\u003e\n### Методы для неразобранного\n\nКласс `AmoAPI` содержит следующие статические методы для работы с заявками из неразобранного:\n\n- `static saveIncomingObjects(AmoIncomingLeadForm|AmoIncomingLeadSip|array $amoObjects, bool $returnResponses = false, string $subdomain = null) :array`  \n    Пакетно добавляет заявки в неразобранное. Возвращает массив параметров UID неразобранного.\n    - `$amoObjects` - объект классов-моделей `AmoIncomingLeadForm` или `AmoIncomingLeadSip` или массив этих объектов;\n    - `$returnResponses` - возвращать массив ответов сервера amoCRM вместо массива UID;\n    - `$subdomain` - поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.\n- `static saveIncomingObjectsWithLimit(AmoIncomingLeadForm|AmoIncomingLeadSip|array $amoObjects, bool $returnResponses = false, string $subdomain = null, $limit = 250) :array`  \n    Пакетно добавляет заявки в неразобранное с ограничением на число заявок в одном запросе к API. Возвращает массив UID неразобранного.\n    - `$amoObjects` - объект классов-моделей `AmoIncomingLeadForm` или `AmoIncomingLeadSip` или массив этих объектов;\n    - `$returnResponses` - возвращать массив ответов сервера amoCRM вместо массива UID;\n    - `$subdomain` - поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации;\n    - `$limit` - максимальное число заявок в одном запросе к API.\n- `static acceptIncomingLeads(array $params, bool $returnResponse = false, $subdomain = null) :array` Принимает неразобранные заявки.\n    + `params` - параметры заявок;\n    + `$returnResponse` - возвращать ответ сервера amoCRM вместо массива параметров принятой заявки;\n    + `$subdomain` - поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.\n- `static declineIncomingLeads(array $params, bool $returnResponse = false, $subdomain = null) :array` Отклоняет неразобранные заявки.\n    + `params` - параметры заявок;\n    + `$returnResponse` - возвращать ответ сервера amoCRM вместо массива параметров отклоненной заявки;\n    + `$subdomain` - поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.\n\n\u003ca id=\"%D0%94%D0%BE%D0%BF%D0%BE%D0%BB%D0%BD%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5-%D0%BC%D0%B5%D1%82%D0%BE%D0%B4%D1%8B\"\u003e\u003c/a\u003e\n### Дополнительные методы\n\nДополнительные статические методы класса `AmoAPI`:\n\n- `static getAccount(string $with = '', string $subdomain = null) :array`  \n    Возвращает информацию об аккаунте amoCRM.\n    - `$with` - Разделенный запятыми список возвращаемых дополнительных параметров аккаунта, включающий:\n        - `custom_fields` - дополнительные поля сущностей;\n        - `users` - пользователи;\n        - `pipelines` - воронки;\n        - `groups` - группы пользователей;\n        - `note_types` - типы событий (примечаний);\n        - `task_types` - типы задач.\n    - `$subdomain` - поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.\n- `static getAccountDomain(string $subdomain = null) :array`  \n    Возвращает информацию о домене аккаунта amoCRM при авторизации по протоколу oAuth2.0.\n    - `$subdomain` - поддомен или полный домен amoCRM. Если null, то используется поддомен последней выполненной авторизации.\n- `static getLastResponse(bool $unescapeUnicode = true) :?string`  \n    Возвращает последний ответ сервера amoCRM в сыром виде.\n    - `$unescapeUnicode` - Декодировать символы UTF-8 \\uXXXX в ответе сервера.\n- `static request(string $query, string $type = 'GET', array $params = [], string $subdomain = null) :?array`\n    Позволяет выполнить RAW запрос к API amoCRM.  \n    - `$query` - путь в URL запроса;\n    - `$type` - метод запроса 'GET', 'POST' или 'AJAX';\n    - `$params` - параметры запроса;\n    - `$subdomain` - поддомен или полный домен amoCRM. Если null, то используется поддомен последней авторизации.\n- `static getAmoDomain(string $subdomain) :string`  \n    Возвращает полное имя домена amoCRM.\n    - `$subdomain` - поддомен или полный домен amoCRM.\n\n\u003ca id=\"%D0%91%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0-%D0%BE%D0%B4%D0%BD%D0%BE%D0%B2%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE-%D0%BE%D0%B1%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F-%D0%BE%D0%B4%D0%BD%D0%BE%D0%B9-%D1%81%D1%83%D1%89%D0%BD%D0%BE%D1%81%D1%82%D0%B8\"\u003e\u003c/a\u003e\n## Блокировка одновременного обновления одной сущности\n\nПри одновременном обновлении одной и той же сущности (сделки, контакта, компании и т.д. с одинаковым ID)\nв разных процессах или потоках исполнения в API amoCRM может возникать ошибка *\"Last modified date is older than in database\"*\nиз-за передаваемого вместе с запросом на обновление значения `updated_at` сущностей.\n\nДля предотвращения возникновения данной ошибки в методе `save()` реализован механизм блокировки одновременного обновления одной сущности.\nДо окончания обновления сущности в первом по времени запущенном процессе (потоке исполнения), то есть до получения ответа от API amoCRM,\nдругие процессы, конкурирующие за обновление той же сущности, приостанавливаются и предпринимают повторные попытки выполнить обновление сущности \nкаждые `AmoAPI::$lockEntityTimeout` секунд с максимально допустимым числом попыток `AmoAPI::$lockEntityAttempts`.\n\n\u003ca id=\"%D0%A2%D1%80%D0%BE%D1%82%D1%82%D0%BB%D0%B8%D0%BD%D0%B3-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%BE%D0%B2-%D0%BA-api\"\u003e\u003c/a\u003e\n## Троттлинг запросов к API\n\nДля предотвращения превышения максимально допустимого числа запросов к API amoCRM ([не более 7 запросов в секунду](https://www.amocrm.ru/developers/content/api/recommendations))\nв рамках одного процесса или потока исполнения в библиотеке реализован простой алгоритм троттлинга запросов,\nоснованный на вычислении времени, прошедшего с момента отправки последнего запроса к API, и приостановке процесса \nдо истечения `1/AmoAPI::$throttle` секунд.\n\n\u003ca id=\"%D0%9E%D1%82%D0%BB%D0%B0%D0%B4%D0%BE%D1%87%D0%BD%D1%8B%D0%B9-%D1%80%D0%B5%D0%B6%D0%B8%D0%BC-%D0%B8-%D0%BB%D0%BE%D0%B3%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5\"\u003e\u003c/a\u003e\n## Отладочный режим и логирование\n\nПри включении отладочного режима `AmoAPI::$debug = true` информация о каждом запросе/ответе к API amoCRM выводится в STDOUT.  \n\nДля логирования каждого запроса/ответа к API amoCRM может быть использован произвольный класс-логгер, реализующий стандарт [PSR-3](https://www.php-fig.org/psr/psr-3/),\nили простейший класс-логгер `AmoAPIDebugLogger`. Объект класса-логгера устанавливается в свойстве `AmoAPI::$debugLogger`.\nЛогирование выполняется независимо от состояния отладочного режима `AmoAPI::$debug`.\nПри каждом запросе/ответе к API в классе-логгере вызывается метод `debug()`.  \n\nВ конструктор класса `AmoAPIDebugLogger` может быть передано имя лог-файла:\n\n- `__construct(string $logFile = 'logs/debug.log')`\n    + `$logFile` - лог-файл.\n\n\u003ca id=\"%D0%9E%D0%B1%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B0-%D0%BE%D1%88%D0%B8%D0%B1%D0%BE%D0%BA\"\u003e\u003c/a\u003e\n## Обработка ошибок\n\nПри возникновении ошибок выбрасывается исключение с объектом класса `\\AmoCRM\\AmoAPIException`.  \nКласс-исключение `AmoAPIException` содержит следующие вспомогательные методы:\n\n- `getErrors() :array` Возвращает массив сообщений об ошибках (errors) из ответа сервера amoCRM;\n- `getItems() :array` Возвращает массив параметров сущностей (items) из ответа сервера amoCRM.\n\n\n\u003ca id=\"%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D1%8B\"\u003e\u003c/a\u003e\n## Примеры\n\n\u003ca id=\"%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D0%BA%D0%BE%D0%BD%D1%82%D0%B0%D0%BA%D1%82%D0%B0%D0%BC%D0%B8\"\u003e\u003c/a\u003e\n### Работа с контактами\n\n```php\nuse AmoCRM\\{AmoAPI, AmoContact, AmoAPIException};\n\ntry {\n    // Авторизация\n    $subdomain = 'testsubdomain';\n    AmoAPI::oAuth2($subdomain);\n\n    // Загрузка ВСЕХ контактов с возможностью фильтрации\n    $generator = AmoAPI::getAllContacts([\n        'query' =\u003e 'Ганс'\n    ]);\n    foreach ($generator as $items) {\n        foreach ($items as $item) {\n            print_r($item);\n        }\n    }\n\n    // Загрузка контактов с возможностью фильтрации и постраничной выборки\n    $items = AmoAPI::getContacts([\n        'limit_rows'   =\u003e 100,\n        'limit_offset' =\u003e 1000\n    ]);\n    foreach ($items as $item) {\n        print_r($item);\n    }\n\n    // -------------------------------------------------------------------------\n\n    // Создание нового контакта\n    $contact1 = new AmoContact([\n        'name'                =\u003e 'Ганс-Дитрих Геншер',\n        'responsible_user_id' =\u003e 12345678\n    ]);\n\n    // Установка дополнительных полей\n    $contact1-\u003esetCustomFields([\n        '6532343' =\u003e 41,\n        '123456' =\u003e [[\n            'value' =\u003e '+79451112233',\n            'enum'  =\u003e 'WORK'\n        ]],\n        '123467' =\u003e [[\n            'value' =\u003e 'hans@example.com',\n            'enum'  =\u003e 'WORK'\n        ]]\n    ]);\n\n    // Сохранение контакта и получение его ID\n    $contact1Id = $contact1-\u003esave();\n\n    // Обновление существующего контакта и получение ответа сервера amoCRM\n    $contact2 = new AmoContact([\n        'id'         =\u003e 12300344,\n        'name'       =\u003e 'Улоф Йоаким Пальме'\n    ]);\n    $contact2-\u003efirst_name = 'Улоф';\n    $contact2-\u003elast_name  = 'Пальме';\n    print_r($contact1-\u003esave($returnResponse = true));\n\n    // Пакетное добавление и/или обновление контактов\n    $items = AmoAPI::saveObjects([ $contact1, $contact2 ]);\n    foreach ($items as $item) {\n        print_r($item);\n    }\n\n    // -------------------------------------------------------------------------\n\n    // Заполнение модели контакта по ID контакта\n    $contact3 = new AmoContact();\n    $contact3-\u003efillById(12345679);\n\n    // Получение всех дополнительных полей контакта\n    print_r($contact3-\u003ecustom_fields);\n\n    // Получение всех параметров контакта из модели\n    print_r($contact3-\u003egetParams());\n\n    // Получение дополнительных полей контакта по ID полей\n    print_r($contact3-\u003egetCustomFields([ 123456, 123467 ]));    \n\n    // Получение первого значения дополнительного поля контакта по ID поля\n    print_r($contact3-\u003egetCustomFieldValueById(155114));\n\n    // Получение всех значений дополнительного поля контакта по ID поля\n    print_r($contact3-\u003egetCustomFieldValueById(155116, $returnFirst = false));\n\n    // Получение первого ENUM дополнительного поля контакта по ID поля\n    print_r($contact3-\u003egetCustomFieldValueById(155116, $returnFirst = true, $returnValue = 'enum'));\n\n    // Получение всех ENUM дополнительного поля контакта по ID поля\n    print_r($contact3-\u003egetCustomFieldValueById(155116, $returnFirst = false, $returnValue = 'enum'));\n\n    // -------------------------------------------------------------------------\n\n    // Привязка сделок к контакту по ID сделок\n    $contact3-\u003eaddLeads([ 12380925, 12364352 ]);\n\n    // Привязка покупателей к контакту по ID покупателей\n    $contact3-\u003eaddCustomers([ 1237374, 1239658 ]);\n\n    // Добавление тегов к контакту\n    $contact3-\u003eaddTags([ 'сотрудник', 'стажер' ]);\n\n    // Удаление тегов контакта\n    $contact3-\u003edelTags('курьер');\n\n    // Сохранение контакта\n    $contact3-\u003esave();\n\n    // -------------------------------------------------------------------------\n\n    $items = AmoAPI::getContacts([\n        'responsible_user_id' =\u003e 12373452\n    ]);\n\n    // Пакетная привязка сделки к контактам\n    $contacts = [];\n    foreach ($items as $item) {\n        $contacts[] = (new AmoContact($item))-\u003eaddLeads(12380925);\n    }\n\n    // Пакетное сохранение контактов\n    AmoAPI::saveObjects($contacts);\n\n} catch (AmoAPIException $e) {\n    printf('Ошибка (%d): %s' . PHP_EOL, $e-\u003egetCode(), $e-\u003egetMessage());\n}\n```\n\n\u003ca id=\"%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D0%BA%D0%BE%D0%BC%D0%BF%D0%B0%D0%BD%D0%B8%D1%8F%D0%BC%D0%B8\"\u003e\u003c/a\u003e\n### Работа с компаниями\n\n```php\nuse AmoCRM\\{AmoAPI, AmoCompany, AmoAPIException};\n\ntry {\n    // Авторизация\n    $subdomain = 'testsubdomain';\n    AmoAPI::oAuth2($subdomain);\n\n    // Загрузка ВСЕХ компаний с возможностью фильтрации\n    $generator = AmoAPI::getAllCompanies([\n        'query'        =\u003e 'OOO',\n        'limit_offset' =\u003e 12000        \n    ]);\n    foreach ($generator as $items) {\n        foreach ($items as $item) {\n            print_r($item);\n        }\n    }\n\n    // Загрузка компаний с возможностью фильтрации и постраничной выборки\n    $items = AmoAPI::getCompanies([\n        'responsible_user_id' =\u003e 12357492,\n        'limit_rows'          =\u003e 250,\n        'limit_offset'        =\u003e 1000\n    ]);\n    foreach ($items as $item) {\n        print_r($item);\n    }\n\n    // -------------------------------------------------------------------------\n\n    // Создание новой компании\n    $company1 = new AmoCompany([\n        'name'                =\u003e 'ООО МММ',\n        'responsible_user_id' =\u003e 12358394,\n    ]);\n\n    // Установка дополнительных полей\n    $company1-\u003esetCustomFields([\n        '2390423' =\u003e 'Город Москва',\n        '123456' =\u003e [[\n            'value' =\u003e '+79457778899',\n            'enum'  =\u003e 'WORK'\n        ]],\n        '123467' =\u003e [[\n            'value' =\u003e 'mmm@example.com',\n            'enum'  =\u003e 'WORK'\n        ]]\n    ]);\n\n    // Привязка контакта\n    $company1-\u003eaddContacts(12375435);\n\n    // Привязка сделки\n    $company1-\u003eaddLeads(12349693);\n\n    // Привязка покупателя\n    $company1-\u003eaddCustomers(1237374);\n\n    // Добавление тега\n    $company1-\u003eaddTags('Акционер');\n\n    // Сохранение компании и получение ее ID\n    $companyId = $company1-\u003esave();\n\n    // Обновление существующей компании и получение ответа сервера amoCRM\n    $company2 = new AmoCompany([\n        'id'         =\u003e 12375435,\n        'created_by' =\u003e 12396034,\n        'name'       =\u003e 'ООО Рога и Копыта',\n    ]);\n    $response = $company2-\u003esave($returnResponse = true);\n\n    // Пакетное добавление и/или обновление компаний\n    $items = AmoAPI::saveObjects([ $company1, $company2 ]);\n    foreach ($items as $item) {\n        print_r($item);\n    }\n\n    // -------------------------------------------------------------------------\n\n    // Заполнение модели компании по ID\n    $company3 = new AmoCompany();\n    $company3-\u003efillById(12375435);\n\n    // Получение всех параметров компании из модели\n    print_r($company3-\u003egetParams());\n\n    // Получение дополнительных полей компании по ID полей\n    print_r($company3-\u003egetCustomFields([ 123456, 123467, 2390423 ]));    \n\n    // Получение первого значения дополнительного поля компании по ID поля\n    print_r($company3-\u003egetCustomFieldValueById(2390423));\n\n    // Получение всех значений дополнительного поля компании по ID поля\n    print_r($company3-\u003egetCustomFieldValueById(2390423, $returnFirst = false));\n\n    // Получение первого subtype дополнительного поля компании по ID поля\n    print_r($company3-\u003egetCustomFieldValueById(2390423, $returnFirst = true, $returnValue = 'subtype'));\n\n    // Получение первого ENUM дополнительного поля компании по ID поля\n    print_r($company3-\u003egetCustomFieldValueById(2390423, $returnFirst = true, $returnValue = 'enum'));\n\n    // -------------------------------------------------------------------------\n\n    $items = AmoAPI::getCompanies([\n        'responsible_user_id' =\u003e 12358394\n    ]);\n\n    // Пакетная привязка сделки к компаниям\n    $companies = [];\n    foreach ($items as $item) {\n        $companies[] = (new AmoCompany($item))-\u003eaddLeads([ 12380925 ]);\n    }\n\n    // Пакетное сохранение компаний\n    AmoAPI::saveObjects($companies);\n\n} catch (AmoAPIException $e) {\n    printf('Ошибка (%d): %s' . PHP_EOL, $e-\u003egetCode(), $e-\u003egetMessage());\n}\n```\n\n\u003ca id=\"%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81%D0%BE-%D1%81%D0%B4%D0%B5%D0%BB%D0%BA%D0%B0%D0%BC%D0%B8\"\u003e\u003c/a\u003e\n### Работа со сделками\n\n\u003e Работа с заявками из неразобранного существенно отличается от работы со сделками.\nДля них используются [специальные методы](#%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D0%B7%D0%B0%D1%8F%D0%B2%D0%BA%D0%B0%D0%BC%D0%B8-%D0%B8%D0%B7-%D0%BD%D0%B5%D1%80%D0%B0%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE).\n\n```php\nuse AmoCRM\\{AmoAPI, AmoLead, AmoAPIException};\n\ntry {\n    // Авторизация\n    $subdomain = 'testsubdomain';\n    AmoAPI::oAuth2($subdomain);\n\n    // Загрузка ВСЕХ сделок с возможностью фильтрации\n    $generator = AmoAPI::getAllLeads([\n        'responsible_user_id' =\u003e 12357492\n    ]);\n    foreach ($generator as $items) {\n        foreach ($items as $item) {\n            print_r($item);\n        }\n    }\n\n    // Загрузка сделок с возможностью фильтрации и постраничной выборки\n    $items = AmoAPI::getLeads([\n        'limit_rows'          =\u003e 250,\n        'limit_offset'        =\u003e 2000\n    ]);\n    foreach ($items as $item) {\n        print_r($item);\n    }\n\n    // -------------------------------------------------------------------------\n\n    // Создание новой сделки\n    $lead1 = new AmoLead([\n        'name'                =\u003e 'Заказ № 964023',\n        'responsible_user_id' =\u003e 12358394,\n        'pipeline'            =\u003e [ 'id' =\u003e 45232121 ],\n        'status_id'           =\u003e 142,\n        'sale'                =\u003e 15000\n   ]);\n\n    // Установка дополнительных полей\n    $lead1-\u003esetCustomFields([\n        '3434323' =\u003e 'Акционерное общество',\n        '3434327' =\u003e [ 1121, 1122, 1123 ]\n    ]);\n\n    // Привязка контакта\n    $lead1-\u003eaddContacts(12375435);\n\n    // Привязка компании\n    $lead1-\u003eaddCompany(12364643);\n\n    // Установка элементов списка\n    $lead1-\u003esetCatalogElements([\n        93492 =\u003e [\n            9898 =\u003e 10,\n            9899 =\u003e 5\n        ]\n    ]);\n\n    // Добавление тега\n    $lead1-\u003eaddTags('Акционер');\n\n    // Сохранение сделки и получение ее ID\n    $leadId = $lead1-\u003esave();\n\n    // Обновление существующей компании и получение ответа сервера amoCRM\n    $lead2 = new AmoLead([\n        'id'         =\u003e 123057838,\n        'sale'       =\u003e 175000\n    ]);\n    $response = $lead2-\u003esave($returnResponse = true);\n\n    // Пакетное добавление и/или обновление сделок\n    $items = AmoAPI::saveObjects([ $lead1, $lead2 ]);\n    foreach ($items as $item) {\n        print_r($item);\n    }\n\n    // -------------------------------------------------------------------------\n\n    // Заполнение модели сделки по ID\n    $lead3 = new AmoLead();\n    $lead3-\u003efillById(12328958);\n\n    // Отвязка контакта от сделки\n    $lead3-\u003eremoveContacts(12345678);\n\n    // Отвязка компании от сделки\n    $lead3-\u003eremoveCompany(12345671);\n\n    // Получение параметров сделки из модели\n    print_r($lead3-\u003egetParams());\n\n    // Получение дополнительных полей сделки по ID полей\n    print_r($lead3-\u003egetCustomFields([ 123456, 123467, 2390423 ]));    \n\n    // Получение первого значения дополнительного поля сделки по ID поля\n    print_r($lead3-\u003egetCustomFieldValueById(2390423));\n\n    // Получение всех значений дополнительного поля сделки по ID поля\n    print_r($lead3-\u003egetCustomFieldValueById(2390423, $returnFirst = false));\n\n    // Получение всех ENUM дополнительного поля сделки по ID поля\n    print_r($lead3-\u003egetCustomFieldValueById(2390423, $returnFirst = true, $returnValue = 'enum'));\n\n    // -------------------------------------------------------------------------\n\n    $leads = AmoAPI::getLeads([\n        'responsible_user_id' =\u003e 12358394\n    ]);\n\n    // Пакетная привязка компании к сделкам\n    $leads = [];\n    foreach ($items as $item) {\n        $leads[] = (new AmoLead($item))-\u003eaddCompany(12380925);\n    }\n\n    // Пакетное сохранение сделок\n    AmoAPI::saveObjects($leads);\n\n} catch (AmoAPIException $e) {\n    printf('Ошибка (%d): %s' . PHP_EOL, $e-\u003egetCode(), $e-\u003egetMessage());\n}\n```\n\n\u003ca id=\"%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D1%81%D0%BE%D0%B1%D1%8B%D1%82%D0%B8%D1%8F%D0%BC%D0%B8\"\u003e\u003c/a\u003e\n### Работа с событиями\n\n```php\nuse AmoCRM\\{AmoAPI, AmoNote, AmoAPIException};\n\ntry {\n    // Авторизация\n    $subdomain = 'testsubdomain';\n    AmoAPI::oAuth2($subdomain);\n\n    // Загрузка ВСЕХ событий, привязанных к сделкам, с возможностью фильтрации\n    $generator = AmoAPI::getAllNotes([\n        'type'       =\u003e 'lead',\n        'note_type'  =\u003e AmoNote::COMMON_NOTETYPE\n    ]);\n    foreach ($generator as $items) {\n        foreach ($items as $item) {\n            print_r($item);\n        }\n    }\n\n    // Загрузка событий, привязанных к контактам, с возможностью фильтрации и постраничной выборки\n    $items = AmoAPI::getLeads([\n        'type'           =\u003e 'contact',\n        'limit_rows'     =\u003e 250,\n        'limit_offset'   =\u003e 2000\n    ]);\n    foreach ($items as $item) {\n        print_r($item);\n    }\n\n    // -------------------------------------------------------------------------\n    \n    // Создание нового события типа \"обычное примечание\", привязанного к сделке\n    $note = new AmoNote([\n        'element_id'   =\u003e 12328687,\n        'note_type'    =\u003e AmoNote::COMMON_NOTETYPE,\n        'element_type' =\u003e AmoNOTE::LEAD_TYPE,\n        'text'         =\u003e 'Текст примечания к сделке'\n    ]);\n\n    // Сохранение события и получение его ID\n    $noteId = $note-\u003esave();\n\n    // Обновление существующего события\n    $note2 = new AmoNote([\n        'id'   =\u003e 12300958,\n        'text' =\u003e 'Обновленный текст события'\n    ]);\n\n    // Заполнение модели события по ID и изменение текста события\n    $note3 = new AmoNote();\n    $note3-\u003efillById(12347842);\n    $note3-\u003etext = 'Новый тест события';\n\n    // Получение параметров события из модели\n    print_r($note3-\u003egetParams());\n\n    // Пакетное сохранение событий\n    AmoAPI::saveObjects([ $note2, $note3 ]);\n\n} catch (AmoAPIException $e) {\n    printf('Ошибка (%d): %s' . PHP_EOL, $e-\u003egetCode(), $e-\u003egetMessage());\n}\n```\n\n\u003ca id=\"%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D0%B7%D0%B0%D0%B4%D0%B0%D1%87%D0%B0%D0%BC%D0%B8\"\u003e\u003c/a\u003e\n### Работа с задачами\n\n```php\nuse AmoCRM\\{AmoAPI, AmoTask, AmoAPIException};\n\ntry {\n    // Авторизация\n    $subdomain = 'testsubdomain';\n    AmoAPI::oAuth2($subdomain);\n\n    // Загрузка ВСЕХ задач, привязанных к сделкам, с возможностью фильтрации\n    $generator = AmoAPI::getAllTasks([\n        'type'   =\u003e 'lead',\n        'filter' =\u003e [\n            'task_type' =\u003e [ AmoTask::CALL_TASKTYPE, AmoTask::MAIL_TASKTYPE ]\n        ]\n    ]);\n    foreach ($generator as $items) {\n        foreach ($items as $item) {\n            print_r($item);\n        }\n    }\n\n    // Загрузка задач, с возможностью фильтрации и постраничной выборки\n    $items = AmoAPI::getTasks([\n        'responsible_user_id' =\u003e 12381202,\n        'limit_rows'          =\u003e 100,\n        'limit_offset'        =\u003e 800\n    ]);\n    foreach ($items as $item) {\n        print_r($item);\n    }\n\n    // -------------------------------------------------------------------------\n\n    // Создание новой задачи типа \"написать письмо\", привязанной к контакту\n    $task = new AmoTask([\n        'task_type'        =\u003e AmoTASK::MAIL_TASKTYPE,\n        'element_type'     =\u003e AmoTask::CONTACT_TYPE,\n        'element_id'       =\u003e 12367433,\n        'text'             =\u003e 'Необходимо написать письмо',\n        'complete_till_at' =\u003e 1508706000\n    ]);\n\n    // Сохранение задачи и получение её ID\n    $taskId = $task-\u003esave();\n\n    // Обновление существующей задачи\n    $task2 = new AmoTask([\n        'id'   =\u003e 12311954,\n        'text' =\u003e 'Обновленный текст задачи'\n    ]);\n\n    // Привязка сделки к задаче по ID\n    $task2-\u003eaddLead(12389536);\n\n    // Заполнение модели задачи по ID и изменение текста задачи\n    $task3 = new AmoTask();\n    $task3-\u003efillById(12327872);\n    $task3-\u003etext = 'Новый тест события';\n\n    // Получение параметров задачи из модели\n    print_r($task3-\u003egetParams());\n\n    // Пакетное сохранение задач\n    AmoAPI::saveObjects([ $task2, $task3 ]);\n\n} catch (AmoAPIException $e) {\n    printf('Ошибка (%d): %s' . PHP_EOL, $e-\u003egetCode(), $e-\u003egetMessage());\n}\n```\n\n\u003ca id=\"%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81%D0%BE-%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%B0%D0%BC%D0%B8-%D0%BA%D0%B0%D1%82%D0%B0%D0%BB%D0%BE%D0%B3%D0%B0%D0%BC%D0%B8\"\u003e\u003c/a\u003e\n### Работа со списками (каталогами)\n```php\nuse AmoCRM\\{AmoAPI, AmoCatalog, AmoAPIException};\n\ntry {\n    // Авторизация\n    $subdomain = 'testsubdomain';\n    AmoAPI::oAuth2($subdomain);\n\n    // Загрузка перечня списков с возможностью фильтрации\n    $items = AmoAPI::getCatalogs();\n    foreach ($items as $item) {\n        print_r($item);\n    }\n\n    // Создание нового списка\n    $catalog = new AmoCatalog([\n        'name' =\u003e 'Товары на складе'\n    ]);\n\n    // Сохранение списка и получение его ID\n    $catalogId = $catalog-\u003esave();\n\n    // Обновление существующего списка\n    $catalog2 = new AmoCatalog([\n        'id'   =\u003e 7185,\n        'name' =\u003e 'Не товары'\n    ]);\n\n    // Заполнение модели списка по ID и изменение названия списка \n    $catalog3 = new AmoCatalog();\n    $catalog3-\u003efillById(7187);\n    $catalog3-\u003ename = 'Актуальные товары';\n\n    // Получение параметров списка из модели\n    print_r($catalog3-\u003egetParams());\n\n    // Пакетное сохранение списков\n    AmoAPI::saveObjects([ $catalog2, $catalog3 ]);\n\n    // Пакетное удаление списков\n    AmoAPI::deleteObjects([ $catalog2, $catalog3 ]);\n\n} catch (AmoAPIException $e) {\n    printf('Ошибка (%d): %s' . PHP_EOL, $e-\u003egetCode(), $e-\u003egetMessage());\n}\n```\n\n\u003ca id=\"%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%B0%D0%BC%D0%B8-%D1%81%D0%BF%D0%B8%D1%81%D0%BA%D0%BE%D0%B2-%D0%BA%D0%B0%D1%82%D0%B0%D0%BB%D0%BE%D0%B3%D0%BE%D0%B2\"\u003e\u003c/a\u003e\n### Работа с элементами списков (каталогов)\n\n```php\nuse AmoCRM\\{AmoAPI, AmoCatalogElement, AmoAPIException};\n\ntry {\n    // Авторизация\n    $subdomain = 'testsubdomain';\n    AmoAPI::oAuth2($subdomain);\n\n    // Загрузка ВСЕХ элементов заданного списка с возможностью фильтрации\n    $generator = AmoAPI::getAllCatalogElements([\n        'catalog_id' =\u003e 4422,\n        'term'   =\u003e 'Маркер'\n    ]);\n    foreach ($generator as $items) {\n        foreach ($items as $item) {\n            print_r($item);\n        }\n    }\n\n    // Загрузка элементов заданного списка с фильтрацией с постраничной выборкой\n    $items = AmoAPI::getCatalogElements([\n        'catalog_id' =\u003e 4422,\n        'term'       =\u003e 'Фломастер',\n        'page'       =\u003e 21\n    ]);\n    foreach ($items as $item) {\n        print_r($item);\n    }\n\n    // -------------------------------------------------------------------------\n\n    // Создание нового элемента каталога\n    $element = new AmoCatalogElement([\n        'catalog_id' =\u003e 4422,\n        'name'       =\u003e 'Ручка гелевая'\n    ]);\n\n    // Установка дополнительных полей\n    $element-\u003esetCustomFields([\n        '20423' =\u003e 'Артикул 14567323',\n        '24233' =\u003e 120\n    ]);\n\n    // Сохранение элемента списка и получение его ID\n    $elementId = $element-\u003esave();\n\n    // Обновление существующего элемента списка\n    $element2 = new AmoCatalogElement([\n        'id'   =\u003e 12312312,\n        'text' =\u003e 'Ручка перьевая'\n    ]);\n\n    // Заполнение модели элемента списка по ID и изменение имени элемента\n    $element3 = new AmoCatalogElement();\n    $element3-\u003efillById(12398096);\n    $element3-\u003ename = 'Карандаш';\n\n    // Получение параметров элемента списка из модели\n    print_r($element3-\u003egetParams());\n\n    // Пакетное сохранение элементов\n    AmoAPI::saveObjects([ $element2, $element3 ]);\n\n    // Пакетное удаление элементов\n    AmoAPI::deleteObjects([ $element2, $element3 ]);\n\n} catch (AmoAPIException $e) {\n    printf('Ошибка (%d): %s' . PHP_EOL, $e-\u003egetCode(), $e-\u003egetMessage());\n}\n```\n\n\u003ca id=\"%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-webhooks\"\u003e\u003c/a\u003e\n### Работа с webhooks\n\n```php\nuse AmoCRM\\{AmoAPI, AmoAPIException};\n\ntry {\n\n    // Авторизация\n    $subdomain = 'subdomain';\n    AmoAPI::oAuth2($subdomain);\n\n    // Получаем список установленных webhooks\n    $webhooks = AmoAPI::getWebhooks();\n    print_r($webhooks);\n\n    // Добавляем webhook\n    AmoAPI::addWebhooks([\n        'url'    =\u003e 'https://example.com/webhook/',\n        'events' =\u003e [ 'add_lead' ]\n    ]);\n\n    // Удаляем webhook\n    AmoAPI::deleteWebhooks([\n        'url'    =\u003e 'https://example.com/webhook/',\n        'events' =\u003e [ 'add_lead' ]\n    ]);\n\n    // Добавляем несколько webhooks\n    AmoAPI::addWebhooks([\n        [\n            'url'    =\u003e 'https://example1.com/webhook/',\n            'events' =\u003e [ 'add_lead' ]\n        ],\n        [\n            'url'    =\u003e 'https://example2.com/webhook/',\n            'events' =\u003e [ 'update_lead' ]\n        ]\n    ]);\n\n    // Удаляем несколько webhooks\n    AmoAPI::deleteWebhooks([\n        [\n            'url'    =\u003e 'https://example1.com/webhook/',\n            'events' =\u003e [ 'add_lead' ]\n        ],\n        [\n            'url'    =\u003e 'https://example2.com/webhook/',\n            'events' =\u003e [ 'update_lead' ]\n        ]\n    ]);\n\n} catch (AmoAPIException $e) {\n    printf('Ошибка (%d): %s' . PHP_EOL, $e-\u003egetCode(), $e-\u003egetMessage());\n}\n```\n\n\u003ca id=\"%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D0%B7%D0%B0%D1%8F%D0%B2%D0%BA%D0%B0%D0%BC%D0%B8-%D0%B8%D0%B7-%D0%BD%D0%B5%D1%80%D0%B0%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%BD%D0%BD%D0%BE%D0%B3%D0%BE\"\u003e\u003c/a\u003e\n### Работа с заявками из","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrey-tech%2Famocrm-api-php","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandrey-tech%2Famocrm-api-php","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrey-tech%2Famocrm-api-php/lists"}