Настройка автоматической передачи заказов поставщику при дропшиппинге 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Настройка автоматической передачи заказов поставщику при дропшиппинге 1С-Битрикс
Простая
~1 рабочий день
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1173
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    745
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Настройка автоматической передачи заказов поставщику при дропшиппинге 1С-Битрикс

Менеджер не должен вручную пересылать письмо поставщику при каждом заказе. Это замедляет обработку, порождает ошибки и не масштабируется. Автоматическая передача — обработчик события создания заказа, который без участия человека маршрутизирует позиции поставщикам.

Событие и точка вызова

Битрикс генерирует событие OnSaleOrderSaved при каждом сохранении заказа. Нас интересует только момент создания нового заказа:

// /local/php_interface/init.php
AddEventHandler(
    'sale',
    'OnSaleOrderSaved',
    function(\Bitrix\Sale\Order $order) {
        // Только новые заказы, не обновления
        if ($order->isNew()) {
            \Local\Dropshipping\OrderDispatcher::dispatch($order);
        }
    }
);

Диспетчер заказов

namespace Local\Dropshipping;

class OrderDispatcher
{
    public static function dispatch(\Bitrix\Sale\Order $order): void
    {
        $grouped = self::groupBasketBySupplier($order->getBasket());

        foreach ($grouped as $supplierId => $lines) {
            $supplier = SupplierRepository::findById($supplierId);
            if (!$supplier) continue;

            $payload = self::buildPayload($order, $supplier, $lines);

            $sent = match ($supplier['UF_CHANNEL']) {
                'webhook' => WebhookSender::send($supplier, $payload),
                'email'   => EmailSender::send($supplier, $order, $lines),
                'ftp'     => FtpSender::send($supplier, $payload),
                default   => false,
            };

            SupplierOrderLog::create([
                'order_id'    => $order->getId(),
                'supplier_id' => $supplierId,
                'status'      => $sent ? 'sent' : 'failed',
                'payload'     => json_encode($payload),
            ]);
        }
    }

    private static function groupBasketBySupplier(
        \Bitrix\Sale\Basket $basket
    ): array {
        $result = [];
        foreach ($basket as $item) {
            $supplierId = SupplierRepository::getByProduct((int)$item->getProductId());
            if ($supplierId) {
                $result[$supplierId][] = $item;
            }
        }
        return $result;
    }
}

Payload для поставщика

Структура данных, которые передаются поставщику, должна однозначно идентифицировать заказ и содержать всё для сборки и отгрузки:

private static function buildPayload(
    \Bitrix\Sale\Order $order,
    array $supplier,
    array $items
): array {
    $props = $order->getPropertyCollection();

    return [
        'order_id'        => $order->getId(),
        'order_date'      => $order->getDateInsert()->format('Y-m-d H:i:s'),
        'delivery_address' => [
            'city'    => $props->getItemByOrderPropertyCode('CITY')?->getValue(),
            'address' => $props->getItemByOrderPropertyCode('ADDRESS')?->getValue(),
            'zip'     => $props->getItemByOrderPropertyCode('ZIP')?->getValue(),
        ],
        'recipient' => [
            'name'  => $props->getItemByOrderPropertyCode('NAME')?->getValue(),
            'phone' => $props->getItemByOrderPropertyCode('PHONE')?->getValue(),
            'email' => $props->getItemByOrderPropertyCode('EMAIL')?->getValue(),
        ],
        'items' => array_map(fn($item) => [
            'sku'      => SupplierRepository::getSupplierSku($item->getProductId(), $supplier['ID']),
            'name'     => $item->getField('NAME'),
            'quantity' => (int)$item->getQuantity(),
            'price'    => (float)$item->getPrice(),
        ], $items),
        'comment'  => $order->getField('USER_DESCRIPTION'),
        'store_id' => $supplier['UF_STORE_ID'],
    ];
}

Повторные попытки при сбоях

Сетевые ошибки случаются. При неудачной передаче заказ попадает в очередь повторных попыток:

// /local/agents/retry_failed_dispatches.php
// Агент запускается каждые 15 минут

$failed = SupplierOrderLog::findFailed(maxAttempts: 3, olderThan: 15);

foreach ($failed as $log) {
    $order    = \Bitrix\Sale\Order::load($log['order_id']);
    $supplier = SupplierRepository::findById($log['supplier_id']);

    $sent = WebhookSender::send($supplier, json_decode($log['payload'], true));
    SupplierOrderLog::incrementAttempts($log['id'], $sent ? 'sent' : 'failed');
}

После трёх неудачных попыток — уведомление менеджеру с деталями ошибки.

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

Состав Срок
Один поставщик, email 2–3 дня
Мультипоставщик, вебхук + email + очередь 1–1.5 недели
С логированием, повторами и уведомлениями менеджеру 2 недели