Skip to Content
КонцепцииЗаказы
View as Markdown

Заказы

Если CheckoutSession — это то, что видит покупатель, то Order — это то, что важно вам. Это постоянная запись о:

  • Что покупалось (позиции)
  • Сколько было к оплате и сколько фактически оплачено
  • Возвраты в работе и применённые возвраты
  • Ваша внешняя ссылка (external_ref) — обычно ваш собственный ID заказа, хранится на Order и возвращается на GET /b2b/v1/orders/{id} (в payload’ах webhook не отзеркаливается — см. ниже)

Заказу не обязательны позиции: отправьте amount вместо items, чтобы выставить просто сумму (счёт, депозит, платёжная ссылка на произвольную сумму). Отправляйте что-то одно, не оба поля.

CheckoutSession умирает после того, как один из её PaymentIntent рассчитан, либо после истечения TTL. Order живёт всегда.

Когда создаётся Order

Когда вы вызываете POST /b2b/v1/checkout-sessions/quick, InfraIO Pay создаёт и новый Order, и новую CheckoutSession в одной транзакции. Если у вас уже есть Order и вы хотите повторить checkout (например, после того, как покупатель забросил), используйте POST /b2b/v1/checkout-sessions, чтобы привязать свежую сессию к существующему заказу — сохраняя аудиторскую цепочку.

Жизненный цикл

СостояниеЗначит
PENDINGCheckoutSession активна и не разрешена.
PAIDПолная сумма рассчитана. Webhook payment.settled срабатывает здесь. Безопасно начинать обработку заказа.
PARTIAL_PAIDДеньги пришли, но меньше общей суммы. См. «Недоплата» ниже.
CANCELEDСессия истекла или мерчант отменил. metadata.canceled_reason объясняет почему (payment_timeout, merchant_canceled, …).
REFUNDEDВся оплаченная сумма возвращена.
PARTIALLY_REFUNDEDЧасть возврата исполнена, остаток остаётся оплаченным.

Состояние, по которому переключается ваша логика обработки заказа, — PAID, а не COMPLETED у CheckoutSession. Webhook payment.settled — канонический сигнал.

Поле external_ref

При создании сессии вы можете включить external_ref (любая строка до 255 символов — обычно ваш собственный ID заказа). Он проходит через весь pipeline:

  • Хранится на Order
  • Виден в панели мерчанта для поиска при поддержке
  • Возвращается на GET /b2b/v1/orders/{id}, чтобы обработчик webhook мог получить его после получения payment.settled

Payload’ы webhook не содержат external_ref. Чтобы сопоставить webhook payment.* с вашей собственной записью, возьмите order_id из payload’а и запросите заказ.

Недоплата

Если on-chain перевод покупателя прошёл на меньшую сумму, чем общая сумма заказа, Order переходит в PARTIAL_PAID. У вас три варианта:

  1. Принять и разрешить. Переводит заказ в PAID и отправляет order.resolved. Это недоступно через REST API, поэтому для self-serve потока используйте вариант 2 (собрать остаток).
  2. Ждать остатка. Создайте новую CheckoutSession против того же Order с amount_due = остаток. Покупатель доплачивает разницу; когда она рассчитается, Order перейдёт в PAID.
  3. Отменить и вернуть. Верните частичную сумму и отмените Order. Покупатель отвечает за любые chain-комиссии.

Возвраты

Возвраты — это отдельный API-уровень и отдельная страница концепции. См. Концепции → Возвраты.

Endpoint’ы API

МетодПутьЗаметки
POST/b2b/v1/ordersСоздание Order без сессии (редко)
GET/b2b/v1/orders/:order_idЧтение полного заказа с позициями + историей платежей
PATCH/b2b/v1/orders/:order_id/cancelОтмена неоплаченного заказа
PATCH/b2b/v1/orders/:order_id/reopenПереоткрытие авто-отменённого заказа (payment_timeout)

Что дальше