Деньги
Центы и строки для показа, карманы депозита, потолок цены, пополнение через API.
Деньги
Все суммы в долларах США и приходят парой: *_minor (целые центы, по ним считайте) и *_usd (строка «10.25», её показывайте). Цена тарифа это ваша закупка: себестоимость поставщика плюс наценка платформы. Цены подписок на срок от курса рубля не зависят. Исключение одно: бессрочная подписка закреплена в рублях (lifetime.price_display_minor), и в долларах она списывается по курсу на момент покупки.
Депозит состоит из двух карманов: paid (внесено пополнениями, вывести нельзя) и earned (заработано на продажах в ботах платформы, выводится). Покупки через API списываются сначала с paid, потом с earned; spendable это их сумма. Нехватка средств отвечает 402 insufficient_balance до обращения к поставщику: подписка при этом не создаётся.
Каждая платная операция возвращает charged_minor (сколько списано) и balance_after_minor (сколько осталось потратить). Сверяйте свой учёт по ним, а не пересчитывайте цену сами.
Потолок цены
Цена может измениться между тем, как вы показали её покупателю, и тем, как отправили запрос: тариф подорожал или, у «Навсегда», сдвинулся курс рубля. Чтобы не списать больше показанного, передайте в любой платной операции max_charge_minor: сумму в центах, которую готовы списать. Если цена выше, операция не выполняется, ответ 409 max_charge_exceeded с полями charge_minor (текущая цена) и max_charge_minor, деньги не списаны.
Где взять цену до операции: покупка и пакеты трафика в GET /plans, продление в GET /subscriptions/{id}/renew-quote (с days для продления на N дней), смена тарифа в GET /subscriptions/{id}/upgrade-quote. Поле необязательное: без него операция идёт по текущей цене, как раньше.
Одно исключение. Если ответ первой попытки потерялся, а запрос к поставщику «Навсегда» уже ушёл, повтор с тем же custom_id потолком не отбивается: покупка, возможно, уже прошла, и отказ с новым custom_id купил бы второй раз. Такой повтор доводит первую попытку до конца, и списание может отличаться от потолка на сдвиг курса за это время.
Депозит через API
POST /deposit выставляет счёт на сумму в центах, ответ содержит invoice_url. Комиссия провайдера прибавляется сверху, на депозит зачислится ровно указанная сумма. Одновременно открытых счетов не больше пяти. Зачисление приходит вебхуком deposit.credited и видно в GET /deposit/{custom_id}.
Статусы пополнения
pendingcreditedexpiredcancelledfailedrefunded