Розробка схеми дропшипінгу з постачальниками 1С-Бітрікс

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Пропоновані послуги
Показано 1 з 1 послугУсі 1626 послуг
Розробка схеми дропшипінгу з постачальниками 1С-Бітрікс
Середня
~1-2 тижні
Часті питання

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

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851
  • 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
    585
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    751
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    989

Розробка схеми дропшипінгу з постачальниками 1С-Бітрікс

Дропшипінг на Bitrix — це не готовий модуль, а архітектурне рішення. Неправильно спроєктована схема ламається при додаванні другого постачальника або при зростанні обсягу до 100+ замовлень на день. Правильно спроєктована — працює при 50 постачальниках і тисячі замовлень на добу без ручного втручання.

Модель даних

Центральне питання: як пов'язати товар із постачальником і як зберігати дані для маршрутизації замовлень.

Інфоблок товарів (b_iblock_element, b_iblock_element_property) зберігає роздрібні дані: назву, опис, зображення, характеристики. Це не чіпаємо.

HL-блок Supplier — довідник постачальників:

b_uts_supplier (автогенерована таблиця HL-блока)
├── ID
├── UF_NAME          — назва постачальника
├── UF_EMAIL         — email для повідомлень
├── UF_WEBHOOK_URL   — URL для POST-повідомлень
├── UF_API_KEY       — ключ доступу до API постачальника
├── UF_FEED_URL      — URL фіду залишків (XML/CSV/JSON)
├── UF_FEED_FORMAT   — формат фіду
├── UF_LEAD_TIME     — термін обробки замовлення (днів)
└── UF_ACTIVE        — активність

HL-блок SupplierProduct — зв'язок товарів і постачальників:

b_uts_supplier_product
├── ID
├── UF_PRODUCT_ID       — ID елемента інфоблока (b_iblock_element.ID)
├── UF_SUPPLIER_ID      — ID постачальника (b_uts_supplier.ID)
├── UF_SUPPLIER_SKU     — артикул постачальника
├── UF_PURCHASE_PRICE   — закупівельна ціна
├── UF_CURRENCY         — валюта закупівлі
├── UF_STORE_ID         — склад постачальника (b_catalog_store.ID)
├── UF_MIN_QUANTITY     — мінімальна партія
└── UF_IS_PRIMARY       — основний постачальник (якщо їх кілька)

Склади (b_catalog_store) — по одному на кожного постачальника. Залишки — у b_catalog_store_product. Це стандартний механізм Bitrix, не винаходимо велосипед.

Маршрутизація замовлень

Завдання маршрутизатора: при створенні замовлення розібрати кошик, згрупувати позиції за постачальниками та передати кожному постачальнику його частину.

Ускладнення — один товар може мати кількох постачальників. Потрібна логіка вибору: за ціною, за наявністю, за пріоритетом. Реалізується через UF_IS_PRIMARY плюс перевірка поточного залишку.

namespace Local\Dropshipping;

use Bitrix\Highloadblock\HighloadBlockTable;
use Bitrix\Main\Application;

class SupplierResolver
{
    /**
     * Повертає найкращого постачальника для товару:
     * спочатку основного із залишком > 0, інакше будь-якого із залишком
     */
    public static function resolve(int $productId, int $quantity): ?array
    {
        $conn = Application::getConnection();

        // Знаходимо постачальників, у яких достатньо залишку
        $result = $conn->query("
            SELECT sp.UF_SUPPLIER_ID, sp.UF_SUPPLIER_SKU, sp.UF_PURCHASE_PRICE,
                   sp.UF_IS_PRIMARY, csp.AMOUNT
            FROM b_uts_supplier_product sp
            JOIN b_catalog_store_product csp
                ON csp.PRODUCT_ID = sp.UF_PRODUCT_ID
                AND csp.STORE_ID  = sp.UF_STORE_ID
            WHERE sp.UF_PRODUCT_ID = {$productId}
              AND csp.AMOUNT       >= {$quantity}
            ORDER BY sp.UF_IS_PRIMARY DESC, sp.UF_PURCHASE_PRICE ASC
            LIMIT 1
        ");

        return $result->fetch() ?: null;
    }
}

Передача замовлення постачальнику

Три канали передачі, у порядку пріоритету:

1. Вебхук (REST API постачальника) — найкращий варіант. Ми POST-имо JSON із даними замовлення на URL постачальника, він відповідає підтвердженням:

private static function sendWebhook(string $url, string $apiKey, array $payload): bool
{
    $http = new \Bitrix\Main\Web\HttpClient();
    $http->setHeader('Content-Type', 'application/json');
    $http->setHeader('Authorization', 'Bearer ' . $apiKey);
    $http->setTimeout(10);

    $response = $http->post($url, json_encode($payload));
    $status   = $http->getStatus();

    \Bitrix\Main\Diag\Debug::writeToFile(
        ['url' => $url, 'status' => $status, 'response' => $response],
        'Dropshipping webhook',
        '/local/logs/dropshipping.log'
    );

    return $status === 200;
}

2. Email із HTML-таблицею — коли постачальник не має API. Шаблон листа через CEvent::Send, подія DROPSHIPPING_ORDER_NEW. Таблиця позицій, адреса доставки, сума до перерахування.

3. Файловий обмін через FTP/SFTP — для постачальників, які працюють із 1С. Генеруємо XML у форматі CommerceML і кладемо на FTP постачальника. Він забирає за розкладом.

Синхронізація залишків

Залишки застарівають швидко — проблема всієї дропшипінг-схеми. Три стратегії:

Push від постачальника — постачальник сам повідомляє про зміну залишку через вебхук. Реалізуємо ендпоінт:

// /local/ajax/supplier/update-stock.php
$apiKey    = $_SERVER['HTTP_X_API_KEY'] ?? '';
$supplierId = SupplierAuth::validateKey($apiKey);

if (!$supplierId) {
    http_response_code(403);
    die(json_encode(['error' => 'Unauthorized']));
}

$items = json_decode(file_get_contents('php://input'), true)['items'] ?? [];

foreach ($items as $item) {
    $productId = SupplierProduct::findBySupplierSku($supplierId, $item['sku']);
    if ($productId) {
        StockUpdater::updateSupplierStock($productId, $supplierId, (int)$item['quantity']);
    }
}

echo json_encode(['updated' => count($items)]);

Pull за розкладом — агент Bitrix кожні 30 хвилин завантажує фід постачальника та оновлює залишки. Фіди бувають XML (формат 1С), CSV, JSON.

Резервування — якщо pull неможливий, після створення замовлення одразу зменшуємо залишок на складі постачальника в b_catalog_store_product. Некоректно, але краще, ніж нічого.

Розрахунок маржі

Закупівельна ціна зберігається в UF_PURCHASE_PRICE HL-блока. Роздрібна ціна — у b_catalog_price. Різниця — маржа. Звіт по маржі запитується безпосередньо до бази:

SELECT
    be.NAME                                         AS product_name,
    cp.PRICE                                        AS retail_price,
    sp.UF_PURCHASE_PRICE                            AS purchase_price,
    cp.PRICE - sp.UF_PURCHASE_PRICE                 AS margin_abs,
    ROUND((cp.PRICE - sp.UF_PURCHASE_PRICE)
          / cp.PRICE * 100, 1)                      AS margin_pct
FROM b_iblock_element be
JOIN b_catalog_price cp     ON cp.PRODUCT_ID = be.ID AND cp.CATALOG_GROUP_ID = 1
JOIN b_uts_supplier_product sp ON sp.UF_PRODUCT_ID = be.ID AND sp.UF_IS_PRIMARY = 1
WHERE be.IBLOCK_ID = :catalog_iblock_id
  AND be.ACTIVE   = 'Y'
ORDER BY margin_pct ASC;

Обробка відмов постачальника

Постачальник може відхилити замовлення (немає в наявності, помилка адреси). Потрібен статусний HL-блок для відстеження:

b_uts_supplier_order
├── UF_ORDER_ID        — ID замовлення Bitrix (b_sale_order.ID)
├── UF_SUPPLIER_ID     — ID постачальника
├── UF_STATUS          — pending / confirmed / rejected / shipped / delivered
├── UF_SUPPLIER_ORDER  — номер замовлення у постачальника
├── UF_TRACKING        — трек-номер відправлення
├── UF_REJECT_REASON   — причина відмови
└── UF_DATE_UPDATE     — дата останньої зміни

При статусі rejected запускається агент, який повідомляє менеджера і, якщо є альтернативний постачальник того самого товару, автоматично перенаправляє замовлення.

Терміни реалізації

Конфігурація Склад Термін
Один постачальник, email-повідомлення HL-блоки + обробник + шаблон 1–2 тижні
Кілька постачальників, вебхуки + маршрутизатор + API синхронізації 3–4 тижні
Повна схема з фідами, кабінетом та аналітикою + pull фідів + ОК постачальника + звіт по маржі 6–8 тижнів