рынок услуг API для продавцов
Этап 1: товары и приёмка

API для продавцов: подключите SKU, заявки на приёмку закупок и остатки склада в Шэньчжэне к своей системе

Для компаний, торгующих на Shopee, Coupang и momo. Передавайте через API штрихкоды товаров, созданные при размещении карточек, при закупке заранее сообщайте трек-номера и содержимое, а при поступлении груза на склад в Шэньчжэне автоматически создаётся наряд, товары маркируются, поштучно сканируются и размещаются на хранение — остатки и расхождения передаются вам в реальном времени.

Компании

Кто может подключиться (нужен 8-значный налоговый номер Тайваня)

200

Максимум SKU в одном пакетном запросе

WO-SK

Наряд на маркировку при поступлении

60 / мин

Лимит запросов на ключ по умолчанию

1 Обзор

Этап 1 охватывает «товары и приёмку»: от создания SKU до размещения товара на складе в Шэньчжэне в виде остатков.

Что уже доступно

  • Массово создавать и обновлять SKU (ключ — ваш seller_sku) с отдельным штрихкодом товара для каждого цвета и размера и привязывать их к вариантам товаров на Shopee / Coupang / momo.
  • Автоматически проверять требования к ввозу по 11-значному коду таможенного тарифа и отмечать товары, которым нужна обязательная проверка или разрешение либо ввоз которых запрещён.
  • При закупке заранее сообщать трек-номера и содержимое каждой коробки; при поступлении на склад в Шэньчжэне автоматически создаётся наряд на маркировку WO-SK, и склад поштучно маркирует, сканирует и размещает товар.
  • Запрашивать остатки по складам и журнал движения остатков, а также получать через webhook в реальном времени события о поступлении, завершении приёмки, расхождениях в количестве и изменении остатков.

Процесс приёмки

  1. Создание SKU: передайте штрихкоды товаров, варианты, наименования для декларации и коды тарифа.
  2. Заявка на приёмку: передайте трек-номера и ожидаемое количество по каждому SKU.
  3. Поступление на склад в Шэньчжэне: после сканирования трек-номера автоматически создаётся и печатается наряд WO-SK.
  4. Маркировка и размещение: склад печатает штрихкоды товаров, поштучно наклеивает их и сканирует для подсчёта.
  5. Приёмка завершена: фактически принятое количество зачисляется в остатки склада в Шэньчжэне, повреждённые единицы учитываются отдельно, а расхождения отправляются в вашу систему.
О требованиях к ввозу: система определяет их автоматически по кодам требований к ввозу из тарифных данных Таможенного управления Тайваня, и результат носит справочный характер. Нужна ли товару на самом деле проверка, разрешение или полная таможенная декларация, определяется по итогам рассмотрения таможней и нашим партнёрским таможенным брокером. Товарные запасы продавца предназначены для продажи, поэтому на них не распространяются льготы для личного пользования.

Планируемые функции

Массовые заказы на отгрузку, партии отгрузки с автоматической группировкой по правилам декларирования, а также заранее размещённые запасы, сортировка и транспортные этикетки маркетплейсов на складе в Таоюане. О запуске будет объявлено на этой странице.

2 Доступ и ключи

API для продавцов доступен только зарегистрированным компаниям; каждый ключ привязан к одобренному аккаунту продавца.

Как подключиться

  1. В личном кабинете добавьте декларанта типа «компания» и укажите 8-значный налоговый номер Тайваня.
  2. Свяжитесь со службой поддержки HowBridge, чтобы подключить API для продавцов; ключ выдаётся после одобрения.
  3. Ключ показывается только один раз. Храните его в переменной окружения на сервере и никогда не размещайте в браузере или приложении.
  4. Если нужны webhook, сначала настройте и подтвердите URL на странице API в личном кабинете, затем подпишитесь на события продавца.
Все запросы отправляются с заголовком Authorization: Bearer <ключ>. Токены, полученные при обычном входе в приложение или на сайт, не могут вызывать API для продавцов.
Authorization: Bearer 12|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Accept: application/json

3 Общие правила

Эти правила действуют для всех эндпоинтов.

Base URL

https://0523.tw/api/v1/merchant

Формат и язык

Запросы и ответы передаются в формате JSON. Сообщения об ошибках по умолчанию возвращаются на традиционном китайском; с заголовком Accept-Language: en — на английском. В логике программы всегда опирайтесь на error.code, который всегда на английском.

Структура ответа

При успехе возвращается {"success": true, "data": …, "meta": …}; при ошибке — {"success": false, "error": {"code", "message", "errors", "context"}}, где errors содержит сведения по каждому полю. Единственное исключение — отсутствующий или недействительный ключ: HTTP 401 с телом {"message": "Unauthenticated."}.

{
  "success": false,
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "…",
    "errors": [
      { "code": "TRACKING_IN_USE", "field": "packages.0.tracking_no", "message": "…" }
    ]
  }
}

Лимиты запросов

60 запросов в минуту и 5000 в сутки на ключ (на тарифе для высокой нагрузки — 300 в минуту и 50 000 в сутки); пакетный запрос считается за один. Для получения данных в реальном времени подпишитесь на webhook вместо периодического опроса.

Заголовок ответаОписание
X-RateLimit-LimitЛимит в минуту
X-RateLimit-RemainingОсталось запросов в текущей минуте
X-RateLimit-Limit-Day
X-RateLimit-Remaining-Day
Суточный лимит и остаток запросов
Retry-AfterЧерез сколько секунд можно повторить запрос после превышения лимита

Идемпотентность (Idempotency-Key)

Запросы на запись принимают заголовок Idempotency-Key (8–128 символов: латинские буквы, цифры и _-:.). Если после сетевого тайм-аута повторить запрос с тем же ключом и тем же содержимым, вернётся первоначальный ответ с заголовком Idempotent-Replayed: true; тот же ключ с другим содержимым вернёт 422. Записи хранятся 24 часа.

Пакетные ответы

Пакетные эндпоинты возвращают результат по каждой записи: 200 — все успешно, 207 — часть с ошибками, 422 — все с ошибками. У каждой записи есть index, status (created / updated / failed) и причина ошибки.

Допустимые символы идентификаторов

seller_sku может содержать только латинские буквы, цифры и ._- (1–64 символа); штрихкод товара может также содержать / и + (3–64 символа). Регистр не учитывается.

4 SKU товаров

Уникальный ключ SKU — ваш seller_sku: повторная отправка того же seller_sku обновляет SKU и изменяет только переданные поля.

Массовое создание и обновление SKU

POST/api/v1/merchant/skus/batch

До 200 записей за запрос. Каждая запись обрабатывается независимо, ошибка в одной не влияет на остальные.

ПолеТипОбязательноОписание
seller_skustringОбязательноВаш код SKU, например артикул варианта товара на Shopee.
product_namestringОбязательно при созданииНазвание товара. SKU с одинаковым названием группируются в один товар.
barcodestringНеобязательноШтрихкод товара: по нему склад печатает этикетки и сканирует товар при размещении. У разных цветов и размеров штрихкоды должны различаться. Если штрихкода нет, оставьте поле пустым — система создаст системный штрихкод. Если длина превышает 16 символов, на этикетке печатается системный штрихкод.
gtinstringНеобязательноМеждународный штрихкод GTIN (8 / 12 / 13 / 14 цифр, контрольная цифра проверяется). Для варианта Shopee «у товара нет GTIN» передайте 00.
specobjectНеобязательноХарактеристики варианта, например {"color": "чёрный", "size": "M"}, не более 5.
declared_name_zh
declared_name_en
stringНеобязательноНаименование для декларации (на китайском / английском): укажите материал и назначение, не пишите «образец» или «подарок».
declared_unit_valuenumberНеобязательноЗаявленная стоимость единицы — ваша закупочная цена у поставщика, а не цена продажи на маркетплейсе.
declared_currencystringНеобязательноCNY, TWD или USD; обязательно, если указана стоимость единицы.
hs_codestringНеобязательно11-значный код товарной классификации, по которому система проверяет требования к ввозу.
origin_countrystringНеобязательноISO-код страны происхождения, по умолчанию CN.
weight_gintegerНеобязательноВес единицы (граммы).
dimensions_cmarrayНеобязательноДлина, ширина и высота (сантиметры), например [20, 15, 3].
battery_typestringНеобязательноnone, contained (встроенный), packed (в комплекте), standalone (отдельный аккумулятор).
channelsarrayНеобязательноПривязки к товарам на маркетплейсах, не более 20: platform (shopee / coupang / momo / other), shop_id, item_id, model_id, platform_sku.

Пример запроса (POST JSON)

curl -X POST https://0523.tw/api/v1/merchant/skus/batch \
  -H "Authorization: Bearer $LUCKY_MERCHANT_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: sku-sync-20260917-001" \
  -d '{
  "items": [
    {
      "seller_sku": "TEE-RED-S",
      "barcode": "4710000000011",
      "product_name": "Cotton T-shirt",
      "spec": { "color": "red", "size": "S" },
      "declared_name_en": "Cotton knitted T-shirt",
      "declared_unit_value": 18.5,
      "declared_currency": "CNY",
      "hs_code": "61091000006",
      "weight_g": 160,
      "channels": [ { "platform": "shopee", "shop_id": "123456", "item_id": "2233", "model_id": "445566" } ]
    }
  ]
}'

Ответ 200

{
  "success": true,
  "data": [
    {
      "index": 0,
      "seller_sku": "TEE-RED-S",
      "status": "created",
      "sku": {
        "seller_sku": "TEE-RED-S",
        "barcode": "4710000000011",
        "system_barcode": null,
        "pick_code": "131999",
        "hs_code": "61091000006",
        "regulation": { "status": "ok", "import_codes": [], "reasons": [] },
        "channels": [ { "platform": "shopee", "shop_id": "123456", "item_id": "2233", "model_id": "445566", "platform_sku": null } ]
      }
    }
  ],
  "meta": { "summary": { "created": 1, "updated": 0, "failed": 0 } }
}

Проверка требований к ввозу (regulation.status)

okКодов требований к ввозу нет.
review_requiredТребование распространяется только на часть товаров (например, C02 «часть товаров данной позиции подлежит обязательной проверке»); нужно уточнить по фактическому назначению товара.
formal_requiredДействуют требования к ввозу (проверка, карантин, разрешения и т. п.); упрощённое декларирование использовать нельзя.
blockedТовар из материкового Китая, запрещённый к ввозу (MW0, страна происхождения — материковый Китай); его нельзя включить в заявку на приёмку.
unclassifiedКод тарифа ещё не указан, проверка невозможна.

Список SKU

GET/api/v1/merchant/skus

Фильтры: seller_sku, barcode, regulation_status, updated_since (ISO 8601); пагинация — page / per_page (не более 100).

Один SKU

GET/api/v1/merchant/skus/{seller_sku}

Обновление привязок к маркетплейсам

PUT/api/v1/merchant/skus/{seller_sku}/channels

Переданный список полностью заменяет существующие привязки; один и тот же вариант товара на маркетплейсе нельзя привязать к двум SKU.

Скачать этикетки со штрихкодом

GET/api/v1/merchant/skus/{seller_sku}/label.pdf?qty=10

Возвращает PDF с этикетками 40×30 мм; qty — количество этикеток (1–1000). Склад в Шэньчжэне при маркировке печатает такие же этикетки; этот метод нужен, если вы хотите промаркировать товар самостоятельно до отправки.

5 Заявки на приёмку

После отправки закупки передайте трек-номера и содержимое посылок в заявке на приёмку. В одной заявке может быть несколько трек-номеров, и для каждого указываются SKU и количество.

Создать заявку на приёмку

POST/api/v1/merchant/inbound-orders

Заявка проверяется целиком: при любой ошибке ничего не создаётся. Трек-номер может одновременно входить только в одну активную заявку на приёмку; повторяющиеся SKU в одной посылке объединяются с суммированием количества.

ПолеТипОбязательноОписание
reference_nostringОбязательноНомер вашего заказа на закупку или заявки на приёмку, уникальный в пределах продавца (латинские буквы, цифры и ._-/).
supplier_order_nostringНеобязательноНомер заказа у поставщика, например номер заказа на 1688.
warehouse_codestringНеобязательноСклад приёмки; сейчас принимается только SZ (склад в Шэньчжэне).
notesstringНеобязательноПримечание (не более 1000 символов).
packagesarrayОбязательноСписок посылок, не более 50.
packages[].tracking_nostringОбязательноТрек-номер китайской курьерской службы.
packages[].carrierstringНеобязательноКод курьерской службы, например yto или sf.
packages[].itemsarrayОбязательноСодержимое посылки: seller_sku и qty, всего не более 500 строк на заявку.

Пример запроса (POST JSON)

curl -X POST https://0523.tw/api/v1/merchant/inbound-orders \
  -H "Authorization: Bearer $LUCKY_MERCHANT_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: po-20260917-0001" \
  -d '{
  "reference_no": "PO-20260917-0001",
  "supplier_order_no": "1688-3312456789",
  "packages": [
    {
      "tracking_no": "YT1234567890123",
      "carrier": "yto",
      "items": [
        { "seller_sku": "TEE-RED-S", "qty": 40 },
        { "seller_sku": "TEE-RED-M", "qty": 60 }
      ]
    }
  ]
}'
Защита от повторной отправки: повторное создание с тем же reference_no возвращает 409 INBOUND_REFERENCE_EXISTS, а в error.context.inbound_order_id передаётся id исходной заявки. Для безопасного повтора передавайте Idempotency-Key.

Статусы заявки на приёмку

createdЗаявка создана, посылки ещё не поступили.
partially_arrivedЧасть посылок поступила на склад в Шэньчжэне.
arrivedВсе посылки поступили, идут маркировка и размещение.
completedРазмещение завершено, количество совпадает с заявкой.
completed_with_discrepancyЗавершено, но есть недостача, излишки или повреждения.
cancelledОтменена.

Статусы посылки

awaiting_arrivalОжидает поступления.
labelingПоступила на склад, наряд создан, идут маркировка и размещение.
receivedРазмещение завершено.
mismatchПринадлежность посылки, зафиксированная при поступлении, не совпадает с вашей заявкой; служба поддержки проводит проверку.
cancelledОтменена или аннулирована; трек-номер освобождён.

Список заявок на приёмку

GET/api/v1/merchant/inbound-orders

GET/api/v1/merchant/inbound-orders/{id}

Фильтры: status, reference_no, updated_since. Для каждой посылки возвращаются заявленное, фактически принятое и повреждённое количество, а также расхождение.

Отменить заявку на приёмку

POST/api/v1/merchant/inbound-orders/{id}/cancel

Отменить заявку можно, только пока ни одна посылка не поступила на склад; после отмены трек-номера можно снова указать в заявке.

6 Остатки

Остатки ведутся раздельно по складам: SZ — склад в Шэньчжэне, TY — склад в Таоюане (остатки склада в Таоюане станут доступны вместе с функциями отгрузки).

Запрос остатков

GET/api/v1/merchant/inventory?warehouse_code=SZ

Фильтры: warehouse_code и seller_sku[] (не более 200).

on_handКоличество на складе.
reservedКоличество, зарезервированное под заказы.
availableДоступное количество = на складе − зарезервировано.
damagedКоличество повреждённых единиц; отгрузке не подлежат.

Ответ 200

{
  "success": true,
  "data": [
    { "seller_sku": "TEE-RED-S", "barcode": "4710000000011", "warehouse_code": "SZ",
      "on_hand": 38, "reserved": 0, "available": 38, "damaged": 2, "updated_at": "2026-09-17T15:20:11+08:00" }
  ],
  "meta": { "total": 1, "page": 1, "per_page": 100, "last_page": 1 }
}

Журнал движения остатков

GET/api/v1/merchant/inventory/movements?after_id=0&limit=200

Записи о движении только добавляются и никогда не изменяются. Листайте вперёд с курсором after_id (не более 500 записей за запрос) и сохраняйте meta.next_after_id из ответа, чтобы продолжить сверку.

7 События webhook

События отправляются на ваш URL в момент их возникновения — опрашивать API не нужно.

Настройка

  1. Укажите URL для webhook на странице API в личном кабинете (только https) и пройдите проверку владения: ваш эндпоинт должен ответить HTTP 200 с телом {"challenge": "полученное значение"}.
  2. Вызовите PUT /api/v1/merchant/webhook/events, чтобы подписаться на события продавца. Последующая смена URL в личном кабинете не сбрасывает эти подписки.
curl -X PUT https://0523.tw/api/v1/merchant/webhook/events \
  -H "Authorization: Bearer $LUCKY_MERCHANT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"events": ["inbound.arrived", "inbound.received", "inbound.discrepancy", "inventory.changed"]}'

Список событий

sku.regulation_flaggedРезультат проверки требований к ввозу для SKU изменился на «требует уточнения», «требуется полная таможенная декларация» или «ввоз запрещён».
inbound.arrivedПосылка поступила на склад в Шэньчжэне, наряд создан.
inbound.mismatchПринадлежность посылки, зафиксированная при поступлении, не совпадает с заявкой; служба поддержки проводит проверку.
inbound.receivedРазмещение посылки завершено; содержит заявленное, фактически принятое и повреждённое количество по каждому SKU.
inbound.discrepancyРазмещённое количество отличается от заявленного или есть повреждения (отправляется одновременно с inbound.received).
inventory.changedОстатки изменились; содержит актуальные остатки затронутых SKU.

inbound.received

{
  "event": "inbound.received",
  "delivery_id": "5b0f1c2e-8f3a-4d7e-9c21-0a6b2d4e8f10",
  "created_at": "2026-09-17T15:20:11+08:00",
  "data": {
    "inbound_order_id": 128,
    "reference_no": "PO-20260917-0001",
    "order_status": "completed_with_discrepancy",
    "tracking_no": "YT1234567890123",
    "work_order": "WO-SK-315",
    "warehouse_code": "SZ",
    "items": [
      { "seller_sku": "TEE-RED-S", "expected_qty": 40, "received_qty": 38, "damaged_qty": 2, "difference": 0 },
      { "seller_sku": "TEE-RED-M", "expected_qty": 60, "received_qty": 59, "damaged_qty": 0, "difference": -1 }
    ],
    "received_at": "2026-09-17T15:20:10+08:00"
  }
}

Проверка подписи

Каждая отправка содержит X-Lucky-Event, X-Lucky-Delivery-Id и X-Lucky-Signature: t=метка_времени,v1=подпись. Вычислите HMAC-SHA256 от «метка времени + . + исходное тело» с вашим webhook secret, сравните результат с v1 и отклоняйте метки времени старше 5 минут. При повторных отправках одного события delivery_id не меняется, поэтому его можно использовать для устранения дублей.

При ответе, отличном от 2xx, отправка повторяется через 1 минуту, 5 минут, 30 минут, 2 часа и 6 часов; после 20 неудачных попыток подряд webhook автоматически отключается, и его нужно заново настроить в личном кабинете.

// PHP
$body   = file_get_contents('php://input');
$header = $_SERVER['HTTP_X_LUCKY_SIGNATURE'] ?? '';
parse_str(str_replace(',', '&', $header), $sig);   // ['t' => '1789…', 'v1' => 'ab12…']

$expected = hash_hmac('sha256', ($sig['t'] ?? '') . '.' . $body, getenv('LUCKY_WEBHOOK_SECRET'));

if (! hash_equals($expected, $sig['v1'] ?? '') || abs(time() - (int) ($sig['t'] ?? 0)) > 300) {
    http_response_code(400);
    exit;
}
$event = json_decode($body, true);   // de-duplicate by $event['delivery_id']
http_response_code(200);

8 Коды ошибок

error.code всегда на английском. Ниже приведены частые ошибки.

HTTPerror.codeОписание
401—Ключ не передан, недействителен или истёк (тело: {"message": "Unauthenticated."}).
403MERCHANT_TOKEN_REQUIREDУ этого токена нет доступа к API для продавцов (например, токен, полученный при обычном входе в аккаунт).
403MERCHANT_NOT_APPROVED
MERCHANT_SUSPENDED
Аккаунт ещё не одобрен как продавец, или продавец приостановлен.
403APP_SUSPENDED
APP_REVOKED
APP_NOT_FOUND
API-приложение, к которому относится ключ, приостановлено или отозвано.
422VALIDATION_FAILED
PRODUCT_NAME_REQUIRED
Неверный формат данных; подробности по полям — в error.errors.
422BATCH_TOO_LARGEКоличество записей в пакете превышает лимит.
207 / 409SKU_BARCODE_DUPLICATE
SKU_BARCODE_CONFLICT
Штрихкод товара уже используется другим SKU или совпадает с системным штрихкодом либо кодом комплектации другого SKU.
207 / 422GTIN_INVALID
HS_CODE_NOT_FOUND
Неверная контрольная цифра GTIN, или код тарифа не существует.
404 / 422SKU_NOT_FOUND
SKU_IMPORT_BLOCKED
SKU не найден, или товар запрещён к ввозу и его нельзя включить в заявку на приёмку.
409INBOUND_REFERENCE_EXISTSЗаявка на приёмку с таким номером уже существует.
422TRACKING_IN_USE
TRACKING_FORECASTED_BY_OTHER
TRACKING_ALREADY_WAREHOUSED
TRACKING_NOT_AVAILABLE
Трек-номер уже входит в активную заявку на приёмку, уже заявлен другим клиентом или уже поступил на склад на имя другого клиента.
409INBOUND_NOT_CANCELLABLEПосылка уже поступила на склад, заявку на приёмку отменить нельзя.
400 / 409 / 422IDEMPOTENCY_KEY_INVALID
IDEMPOTENCY_IN_PROGRESS
IDEMPOTENCY_KEY_REUSED
Неверный формат Idempotency-Key, ключ использован с другим содержимым, или предыдущий запрос ещё обрабатывается.
409CONFLICT_RETRYЭту запись сейчас изменяет другой запрос; повторите попытку чуть позже.
429RATE_LIMIT_EXCEEDEDЛимит запросов превышен; подождите время, указанное в Retry-After, и повторите запрос.

9 Примеры кода

Запускайте приведённые ниже примеры на сервере и никогда не размещайте ключ во фронтенд-коде.

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;

$api = Http::withToken(config('services.lucky.merchant_key'))
    ->acceptJson()
    ->baseUrl('https://0523.tw/api/v1/merchant')
    ->timeout(20);

// 1) Sync SKUs (up to 200 per request)
$res = $api->withHeaders(['Idempotency-Key' => (string) Str::uuid()])
    ->post('/skus/batch', ['items' => $items]);

foreach ($res->json('data') as $row) {
    if ($row['status'] === 'failed') {
        logger()->warning('SKU failed', $row['errors']);
    }
}

// 2) Forecast an inbound order
$order = $api->withHeaders(['Idempotency-Key' => 'po-' . $po->id])
    ->post('/inbound-orders', [
        'reference_no' => $po->number,
        'packages'     => [[
            'tracking_no' => $po->tracking_no,
            'items'       => [['seller_sku' => 'TEE-RED-S', 'qty' => 40]],
        ]],
    ])->throw()->json('data');

// 3) Read Shenzhen stock
$stock = $api->get('/inventory', ['warehouse_code' => 'SZ'])->json('data');

10 Техподдержка

Если при интеграции возникли проблемы, сообщите время запроса, эндпоинт и error.code — так нам будет проще найти причину.

Официальный аккаунт LINE @0523tw

Техническая почта howyunqisoftware@gmail.com

Версия v1, этап 1 (2026-09-17): SKU товаров, заявки на приёмку, маркировка и размещение на складе в Шэньчжэне, запрос остатков, webhook.

Связаться с поддержкой для подключения