Служба доставки и платёжная система - настройка и свой обработчик
Разбираемся, почему служба доставки не видна в заказе, и подключаем свой обработчик доставки или оплаты.
Решение
Смотрим службы доставки и их ограничения:
use Bitrix\Sale\Delivery\Services\Manager;use Bitrix\Sale\Delivery\Restrictions;
foreach (Manager::getActiveList() as $service) { $rules = Restrictions\Manager::getRestrictionsList($service['ID']); printf("%-6s %-28s ограничений=%d\n", $service['ID'], $service['NAME'], count($rules));}Служба показывается заказу, только если прошла все свои ограничения. Ни одно из них не сообщает покупателю о причине отказа: служба просто не появляется в списке.
Проверяем ограничения на конкретном заказе:
$shipment = $order->getShipmentCollection()->getNotSystemItems()->current();foreach (Manager::getRestrictedObjectsList($shipment) as $service) { printf("доступна: %s\n", $service->getName());}Проверка идёт против конкретной отгрузки: её веса, суммы и адреса. Одна и та же служба доступна одному заказу и недоступна соседнему, и это штатное поведение, а не сбой настроек.
Настраиваем приём уведомлений от банка:
# адрес обработчика должен отвечать снаружи без авторизации и переадресацийcurl -I https://example.com/bitrix/tools/sale_ps_result.php# 200 или 302 на сам обработчик - нормально, 401 и 403 - нетБанк зовёт этот адрес сам, без участия покупателя. Закрытый авторизацией или переадресацией на защищённое соединение адрес приводит к тому, что оплата проходит, а заказ остаётся неоплаченным.
Пишем свой обработчик доставки:
namespace Local\Delivery;
use Bitrix\Sale\Delivery\Services\Base;
class PvzHandler extends Base{ public function calculateConcrete(\Bitrix\Sale\Shipment $shipment) { // здесь считается стоимость: обращение к службе, тарифы, коэффициенты return new \Bitrix\Sale\Delivery\CalculationResult(); }
public static function getClassTitle() { return 'Доставка до пункта выдачи'; // название в списке служб админки }}// свой обработчик оплаты устроен так же: описание, класс и шаблон формы// класс регистрируют событием модуля продаж, а не правкой его файловСвой обработчик регистрируется событием модуля продаж и дальше живёт как штатный: получает ограничения, настройки и профили. Переписывать чужой обработчик под себя не нужно - обновление модуля вернёт его к исходному виду.
Ограничения складываются, а не выбираются. Служба с четырьмя ограничениями показывается заказу только тогда, когда прошли все четыре сразу, и достаточно одного несовпадения по весу или по региону, чтобы она исчезла из формы. Поэтому разбор всегда начинают с полного списка ограничений службы, а не с того, которое кажется подозрительным.
Свой обработчик стоит начинать с копии существующего. Жизненный цикл, настройки и профили у всех обработчиков одинаковые, и рабочий пример экономит день чтения документации.
Отладка обработчиков идёт по журналу модуля продаж и по своим записям. Ни служба доставки, ни платёжная система не показывают покупателю причину отказа, поэтому запись входящих данных и результата расчёта в файл экономит основное время разбора.
Типичные проблемы
Служба активна, но в заказе её нет.
Она не проходит одно из ограничений. Проверка идёт против конкретной отгрузки и молча исключает службу из списка.
Оплата прошла, заказ не оплачен.
Уведомление от банка не дошло до обработчика. Адрес закрыт авторизацией, переадресацией или правилами веб-сервера.
После обновления модуля пропал свой обработчик.
Правился штатный обработчик вместо своего. Обновление возвращает файлы модуля к исходному виду.
Стоимость доставки считается неверно.
Вес или габариты товаров не заполнены. Обработчик получает нули и считает по минимальному тарифу.
Служба видна не всем покупателям.
У неё стоит ограничение по группе пользователя. Это штатная настройка, а не сбой прав доступа.
Частые вопросы
Чем профиль службы отличается от самой службы?
Служба - обработчик, профиль - её конкретный тариф или способ. У одной службы бывает несколько профилей с разными сроками и ценами.
Как передать в 1С данные о перевозчике?
Через свойства заказа: они выгружаются вместе с ним. Служба доставки как сущность в учётную систему не уезжает.
Можно ли считать доставку своим кодом без обработчика?
Технически да, событием пересчёта заказа, но такой расчёт не попадёт в ограничения и в интерфейс выбора. Обработчик даёт и то, и другое.
Почему тестовая оплата не проходит на локальном сервере?
Банк должен позвать адрес уведомления снаружи, а локальный сервер ему недоступен. Для проверки нужен адрес, открытый в интернете.
Смежное
- Доставка и оплата - оглавление подтемы
- Служба доставки не показывается на оформлении: разбор причин - когда службы нет на оформлении
- Оформление заказа: настройка компонента и правка шаблона - где покупатель выбирает службу
- Местоположения: импорт, свойство заказа, доставки и индекс - откуда берётся город в ограничениях
- Своё ограничение доставки и оплаты: класс, параметры, регистрация - своё правило видимости службы
- Заказы и статусы - что происходит после оплаты
- Каталог и продажи - устройство магазина целиком
- Оплаты и отгрузки заказа: объекты, признаки, частичные операции - как операции ложатся в заказ
- Вызов внешнего сервиса из кода: таймауты, повторы, журнал - вызовы к службам доставки и платёжным
- Единицы измерения, вес и габариты товара - откуда доставка берёт вес и размеры
- Самовывоз и пункты выдачи: склады, список на оформлении, заказ - отдельный разбор выдачи в точке
- Свой обработчик оплаты: форма, уведомление, отметка платежа - когда готового обработчика нет
- Своя служба доставки с внешним API: регистрация, расчёт, статусы - разбор задачи целиком
- Стоимость доставки считается неверно - что проверить, когда расчёт даёт не ту сумму