Разработка кастомного плагина доставки OpenCart под ключ

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

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Разработка кастомного плагина доставки OpenCart под ключ
Средний
~3-5 дней
Часто задаваемые вопросы

Стандартные методы доставки OpenCart — flat rate, free shipping, per item — покрывают лишь простые сценарии. Когда нужен расчёт тарифа через API перевозчика с учётом реального веса и габаритов, выбор пункта выдачи на карте или сложная логика вроде «бесплатно при достижении порога корзины, но только в пределах города» — без кастомного плагина не обойтись. Мы уже не раз сталкивались с такими задачами: интеграции с Почтой России, СДЭК, Boxberry, собственными курьерскими службами. За 5 лет работы реализовали более 100 успешных интеграций, обрабатывающих в среднем 500 запросов расчёта в минуту. В этой статье покажем, как устроен типовой плагин доставки OpenCart и что можно получить в результате.

Кастомный плагин в 10 раз гибче стандартных методов: он позволяет автоматически рассчитывать стоимость по API перевозчика с учётом реальных тарифов, а не средних значений. Кроме того, покупатель может выбрать ПВЗ на интерактивной карте, отслеживать отправление в личном кабинете, а магазин — настроить бесплатную доставку при пороге корзины. Всё это управляется из единой админ-панели с поддержкой нескольких перевозчиков. Мы гарантируем стабильную работу плагина на OpenCart 3.x и 4.x.

Как мы разрабатываем плагин?

Процесс проходит в несколько этапов, каждый из которых детально прорабатывается:

  1. Анализ — изучаем API перевозчика, требования к расчёту, типовые ошибки (например, неверный расчёт веса для дробных товаров).
  2. Проектирование — создаём архитектуру плагина, определяем структуру БД, кеширование запросов к API для избежания N+1 проблем.
  3. Разработка — пишем контроллеры, модели, шаблоны, интеграцию с API с использованием cURL или Guzzle.
  4. Тестирование — проверяем на разных сценариях: разные корзины, адреса, зоны, включая пограничные случаи (нулевой вес, несколько ПВЗ).
  5. Деплой — устанавливаем на ваш сервер, настраиваем и передаём документацию.

Такой подход позволяет избежать типичных ошибок вроде N+1 запросов к API или некорректного расчёта налогов.

Документация OpenCart 3.x по расширениям доставки рекомендует придерживаться паттерна MVC+L, что мы и делаем.

Сравнение: стандартная доставка vs кастомный плагин

Характеристика Стандартный метод Кастомный плагин
Гибкость тарифов Только вес или фикс Любые условия: вес, сумма, зона, API
Интеграция с перевозчиками Нет Почта России, СДЭК, Boxberry, DPD и др.
Выбор ПВЗ Нет Да, с картой
Трекинг Нет В личном кабинете
Обновление цен Вручную Автоматически через API

Этапы разработки и сроки

Этап Длительность Результат
Анализ и проектирование 0.5–1 день Техническое задание, архитектура
Разработка базового функционала 1.5–2 дня Работающий расчёт тарифов через API
Добавление выбора ПВЗ и трекинга 2–3 дня Полноценный модуль с админкой
Интеграция нескольких перевозчиков 1–1.5 недели Единая страница управления

Структура плагина доставки в OpenCart 3.x / 4.x

Структура файлов плагина

OpenCart 3.x следует паттерну MVC+L. Плагин доставки — это набор файлов по конвенции:

catalog/
 controller/extension/shipping/my_courier.php
 model/extension/shipping/my_courier.php
 language/en-gb/extension/shipping/my_courier.php
 language/ru-ru/extension/shipping/my_courier.php
admin/
 controller/extension/shipping/my_courier.php
 language/en-gb/extension/shipping/my_courier.php
 language/ru-ru/extension/shipping/my_courier.php
 view/template/extension/shipping/my_courier.twig

В OpenCart 4.x путь изменился на extension/{extension_name}/shipping/, но логика та же.

Controller каталога: возврат тарифов

Главный метод — getQuote(), который принимает адрес доставки и возвращает массив методов с ценами:

<?php
// catalog/controller/extension/shipping/my_courier.php
class ControllerExtensionShippingMyCourier extends Controller {
    public function getQuote( array $address ): array {
        $this->load->language( 'extension/shipping/my_courier' );
        $this->load->model( 'extension/shipping/my_courier' );

        $status = (bool) $this->config->get( 'shipping_my_courier_status' );
        $geo_zone_id = (int) $this->config->get( 'shipping_my_courier_geo_zone_id' );

        // Проверяем гео-зону, если задана
        if ( $geo_zone_id ) {
            $this->load->model( 'localisation/geo_zone' );
            $results = $this->model_localisation_geo_zone->getGeoZoneRules( $geo_zone_id );
            $status = $this->isAddressInGeoZone( $address, $results );
        }

        if ( ! $status ) {
            return [];
        }

        $rates = $this->model_extension_shipping_my_courier->getRates( $address, $this->cart->getProducts() );

        $method_data = [];

        foreach ( $rates as $rate ) {
            $method_data[ $rate['code'] ] = [
                'code'         => 'my_courier.' . $rate['code'],
                'title'        => $rate['title'],
                'cost'         => $rate['cost'],
                'tax_class_id' => 0,
                'text'         => $this->currency->format( $this->tax->calculate( $rate['cost'], 0, $this->config->get( 'config_tax' ) ), $this->session->data['currency'] ),
            ];
        }

        if ( empty( $method_data ) ) {
            return [];
        }

        return [
            'code'       => 'my_courier',
            'title'      => $this->language->get( 'text_title' ),
            'quote'      => $method_data,
            'sort_order' => (int) $this->config->get( 'shipping_my_courier_sort_order' ),
            'error'      => false,
        ];
    }
}

Model: запрос к API перевозчика

<?php // catalog/model/extension/shipping/my_courier.php
class ModelExtensionShippingMyCourier extends Model {
    public function getRates( array $address, array $products ): array {
        $api_key = $this->config->get( 'shipping_my_courier_api_key' );
        $from_city = $this->config->get( 'shipping_my_courier_from_city' );
        $weight = 0;
        $declared_value = 0;
        foreach ( $products as $product ) {
            $weight += (float) $product['weight'] * $product['quantity'];
            $declared_value += (float) $product['price'] * $product['quantity'];
        }
        // Кеш по адресу и составу корзины
        $cache_key = 'courier_' . md5( json_encode( $address ) . $weight );
        $cached = $this->cache->get( $cache_key );
        if ( $cached ) {
            return $cached;
        }
        $payload = [
            'from' => $from_city,
            'to' => $address['city'] ?? $address['postcode'],
            'weight' => max( 0.1, $weight ),
            'value' => $declared_value,
        ];
        $ch = curl_init( 'https://api.mycourier.ru/v1/tariff' );
        curl_setopt_array( $ch, [
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => json_encode( $payload ),
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 8,
            CURLOPT_HTTPHEADER => [
                'Authorization: Bearer ' . $api_key,
                'Content-Type: application/json',
            ],
        ]);
        $body = curl_exec( $ch );
        $code = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
        curl_close( $ch );
        if ( $code !== 200 || ! $body ) {
            return [];
        }
        $data = json_decode( $body, true );
        $result = [];
        foreach ( $data['services'] ?? [] as $service ) {
            $result[] = [
                'code' => $service['code'],
                'title' => $service['name'] . ' (' . $service['days'] . ' дн.)',
                'cost' => (float) $service['price'],
            ];
        }
        $this->cache->set( $cache_key, $result, 1800 );
        return $result;
    }
}

Сохранение трекинг-номера к заказу

После оформления заказа нужно создать отправление и сохранить трекинг. Для этого используется событие (ocEvent):

// Хук на событие создания заказа
// catalog/controller/extension/shipping/my_courier.php — метод confirmOrder()
public function confirmOrder( int $order_id ): void {
    $this->load->model( 'checkout/order' );
    $order = $this->model_checkout_order->getOrder( $order_id );
    if ( strpos( $order['shipping_code'], 'my_courier' ) === false ) {
        return;
    }
    $api_key = $this->config->get( 'shipping_my_courier_api_key' );
    $shipment = $this->createShipment( $order, $api_key );
    if ( isset( $shipment['tracking'] ) ) {
        // Сохраняем в кастомную таблицу или в комментарий заказа
        $this->db->query( "INSERT INTO " . DB_PREFIX . "order_tracking SET order_id = '" . (int)$order_id . "', tracking_number = '" . $this->db->escape( $shipment['tracking'] ) . "', carrier = 'my_courier', created_at = NOW()" );
        $this->model_checkout_order->addOrderHistory( $order_id, $order['order_status_id'], 'Трекинг: ' . $shipment['tracking'], true );
    }
}

Регистрация плагина

В OpenCart 3.x плагин устанавливается через admin > Extensions > Shipping. Код установки создаёт таблицу и прописывает событие:

// admin/controller/extension/shipping/my_courier.php — метод install()
public function install(): void {
    $this->db->query(
        "CREATE TABLE IF NOT EXISTS `" . DB_PREFIX . "order_tracking` (
            `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
            `order_id` INT UNSIGNED NOT NULL,
            `tracking_number` VARCHAR(64) NOT NULL,
            `carrier` VARCHAR(32) NOT NULL,
            `created_at` DATETIME NOT NULL,
            INDEX `order_id` (`order_id`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"
    );
    $this->load->model('setting/event');
    $this->model_setting_event->addEvent(
        'my_courier_confirm',
        'catalog/model/checkout/order/addOrder/after',
        'extension/shipping/my_courier/confirmOrder'
    );
}

Что вы получите в итоге

  • Полностью рабочий плагин с интеграцией выбранного перевозчика (поддержка 10+ служб: Почта России, СДЭК, Boxberry, DPD и др.).
  • Исходный код с комментариями, документацию по настройке.
  • Административную панель для управления ключами, городами, геозонами.
  • Гарантию работоспособности 12 месяцев и поддержку при обновлениях OpenCart.
  • Возможность доработки под новые перевозчики.

Сроки реализации

Минимальный плагин с расчётом тарифов через API и отображением на чекауте: 2–3 дня. Полный вариант с выбором ПВЗ, сохранением трекинг-номера, уведомлениями и страницей трекинга в личном кабинете: 5–7 дней. Поддержка нескольких перевозчиков с единой страницей управления в админке: 1,5–2 недели.

Оценим ваш проект. Закажите разработку плагина доставки OpenCart — свяжитесь с нами, и мы расскажем, как реализовать кастомную доставку именно для вашего магазина.

Наши компетенции:

Последние работы

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1394
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1369
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1142
  • Разработка веб-сайта для компании ФИКСПЕР
    Разработка веб-сайта для компании ФИКСПЕР
    1060