для разработчиков На сайт Rentu

Частые ошибки интеграции

Восемь мест, где цифры расходятся или интеграция ломается на ровном месте. Все проверены на реальных внедрениях.

Копейки делят дважды#

Все денежные поля приходят целыми копейками: income_sum, turnover, average_check_sum, revenue_per_area, суммы по ставкам НДС. Ошибка возникает, когда одну часть кода написал один человек, а витрину строил другой, и деление на 100 случается в обоих местах.

Признак: выручка занижена ровно в сто раз, а иногда только в части отчётов. Границу стоит держать в одном месте: перевод в рубли делать только при показе человеку, внутри считать в копейках. Целые копейки к тому же не теряют точность при сложении.

«Вчера» берут по своим часам#

Границы суток API считает в таймзоне торгового центра. Если ночной сценарий берёт date.today() - 1 по времени своего сервера, то для центра в другом часовом поясе это может оказаться позавчера или сегодня.

Для дальневосточного центра новый день наступает на семь часов раньше московского. Ночная выгрузка, запущенная в 00:30 по Москве, для такого центра просит день, который там ещё не закончился, и на Basic получает fresh_data_requires_pro.

Зона приходит в поле time_zone каждого центра и в meta.time_zone большинства методов. Дату стоит считать от неё:

python
from zoneinfo import ZoneInfo
import datetime as dt

today = dt.datetime.now(ZoneInfo(sc["time_zone"])).date()
yesterday = today - dt.timedelta(days=1)

Товарооборот считают сами#

Аренда часто привязана к товарообороту, и его пытаются получить как «выручка минус возвраты». Совпадёт это редко. Из товарооборота по правилам центра могут вычитаться НДС, авансы, предоплаты и зачёты; доля вычитаемых возвратов ограничена процентом, который задан в настройках.

Готовое значение лежит в поле turnover. Правила, по которым оно посчитано, отдаёт настройки товарооборота: по ним удобно объяснить арендатору, почему цифра отличается от его кассовой.

Если выгрузка недельной давности разошлась с текущими цифрами, стоит посмотреть last_recalculation_date в настройках. Пересчёт задним числом меняет товарооборот за прошедшие дни, и это нормальное поведение платформы.

409 на событиях считают ошибкой#

POST /events возвращает 409 already_exists_in_sc, когда событие с такими же названием, типом и обеими датами в этом центре уже есть. Это не сбой, а ответ «уже создано».

Интеграции, которые синхронизируют календарь целиком, часто падают на этом коде и прерывают весь проход. Правильная реакция: считать событие созданным и идти дальше.

python
try:
    api.request("POST", f"/sc/{sc_id}/events", json=event)
except RentuError as error:
    if error.code != "already_exists_in_sc":
        raise

Ветвятся по HTTP-статусу#

За одним статусом стоит несколько машинных кодов, и реакция на них разная. Самый болезненный случай 403: под ним живут forbidden_sc (у сотрудника нет прав) и plan_required (нужен другой тариф). Первое чинится ролями, второе деньгами, и сообщение пользователю должно быть разным.

Так же с 404: not_found означает неверный идентификатор, а traffic_not_configured означает, что в центре не установлено оборудование подсчёта и метод не заработает, сколько ни повторяй.

Ветвиться нужно по error.code. Полная таблица в разделе Ошибки.

Повторяют то, что повторять бесполезно#

Универсальный retry на любой не-двухсотый ответ съедает лимит частоты и маскирует настоящую причину. Повторять имеет смысл ровно пять кодов:

КодКогда повторять
token_expiredПосле получения нового токена
rate_limitedЧерез Retry-After секунд
rights_unavailableС нарастающей паузой
traffic_unavailableС нарастающей паузой
internal_errorС нарастающей паузой

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

Пустой ответ принимают за сбой#

{"success": true, "data": []} при 200 это законный ответ. У посещаемости он означает, что центр или точка не покрыты зоной подсчёта, у аномалий что за период ничего не нашлось, у продаж что не было чеков.

Важно отличать его от traffic_unavailable: там действительно сбой подсистемы и повтор поможет, здесь оборудования просто нет и ждать нечего.

Заводят второй ключ ради скорости#

Лимит частоты считается по торговому центру, а не по ключу. Сотрудники одного центра делят общий бюджет запросов, поэтому второй ключ не ускорит выгрузку: счётчик у неё тот же самый. Если выгрузка упирается в потолок, значит нужен другой тариф центра.

Заодно: выпустить второй ключ на того же сотрудника нельзя, попытка вернёт 409.


Что стоит проверить перед запуском#

  • даты считаются в таймзоне центра, а не сервера;
  • деление на 100 происходит ровно в одном месте;
  • обработка ветвится по error.code;
  • 429 уважает Retry-After, 503 уходит в паузу с увеличением;
  • 409 на событиях не роняет проход;
  • справочники центров и точек кэшируются, а не запрашиваются перед каждой выгрузкой;
  • токен живёт в памяти процесса и обновляется по expires_in.