ПерфектПак · API v1.1
openapi.yaml ↗

Сверка недостач по приёмке

Зачем

«Я отправил 600, вы приняли 480 — где 120?» — самый частый спор между селлером и оператором фулфилмента. API отвечает на него числами, а не перепиской: discrepancy_qty общей суммой и по каждой позиции отдельно, плюс машиночитаемая причина там, где она известна.

Узнать о расхождении

Подпишитесь на receipt.completed — событие приходит один раз, когда приёмка закрыта, независимо от того, сошлось количество или нет:

{
  "id": "evt_7c1b2a",
  "type": "receipt.completed",
  "occurred_at": "2026-08-12T16:45:00+03:00",
  "data": {
    "id": "r_2026_0812_04", "number": "ПР-2026-0812-04",
    "status": "RECEIVED_WITH_DISCREPANCY", "status_label": "Принята с расхождением",
    "expected_qty": 600, "accepted_qty": 480, "discrepancy_qty": 120,
    "created_at": "2026-08-12T08:00:00+03:00", "completed_at": "2026-08-12T16:45:00+03:00"
  }
}
def handle_receipt_completed(event):
    receipt = event["data"]
    if receipt["discrepancy_qty"] > 0:
        fetch_and_report_discrepancy(receipt["id"])

Без вебхука — переберите приёмки за нужный период и отфильтруйте по статусу:

curl "https://api.perfektpak.ru/v1/receipts?status=RECEIVED_WITH_DISCREPANCY" \
  -H "Authorization: Bearer $PP_KEY"

Расхождение по каждой позиции

Общая сумма — в списке; состав по SKU с причиной — в карточке приёмки:

curl https://api.perfektpak.ru/v1/receipts/r_2026_0812_04 \
  -H "Authorization: Bearer $PP_KEY"
{
  "id": "r_2026_0812_04", "number": "ПР-2026-0812-04",
  "status": "RECEIVED_WITH_DISCREPANCY", "status_label": "Принята с расхождением",
  "expected_qty": 600, "accepted_qty": 480, "discrepancy_qty": 120,
  "created_at": "2026-08-12T08:00:00+03:00", "completed_at": "2026-08-12T16:45:00+03:00",
  "items": [
    { "barcode": "4680012340015", "article": "COFFEE-1KG-BRIZ", "name": "Кофе в зёрнах «Утренний Бриз» 1 кг",
      "expected_qty": 400, "accepted_qty": 280, "discrepancy_qty": 120, "shortage_reason": "Недовложение поставщика" },
    { "barcode": "4680012340022", "article": "CREAM-HAND-SILK-75", "name": "Крем для рук «Шёлковые ладони» 75 мл",
      "expected_qty": 200, "accepted_qty": 200, "discrepancy_qty": 0 }
  ]
}

shortage_reason — русский текст из курируемого нами списка (не фиксированный enum: список пополняется), присутствует только у позиций с расхождением. Ветвитесь в коде по discrepancy_qty > 0, а не по наличию поля — используйте shortage_reason только для текста, который увидит человек.

Что делать с расхождением

Расхождение уже отражено в остатке — accepted_qty, а не expected_qty, попадает в приход, и ровно эта же цифра видна в GET /v1/stock и в GET /v1/metrics (receiving.discrepancy_units, receiving.shortages_by_reason — та же разбивка по причинам, но агрегированная за период, для дашборда). Дальнейший разбор — по договору с ПерфектПак — ведётся через менеджера с номером приёмки и позициями из ответа выше на руках, не через API: v1.1 не вводит отдельной ручки для претензии по недостаче.

Что дальше

Если расхождение всплыло в заявке, которую вы сами создали через API — см. статус RECEIVED_WITH_DISCREPANCY в общей цепочке в гайде «Заявка на приёмку из 1С».