Заказы
Если 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, чтобы привязать свежую сессию к
существующему заказу — сохраняя аудиторскую цепочку.
Жизненный цикл
| Состояние | Значит |
|---|---|
PENDING | CheckoutSession активна и не разрешена. |
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. У вас три варианта:
- Принять и разрешить. Переводит заказ в
PAIDи отправляетorder.resolved. Это недоступно через REST API, поэтому для self-serve потока используйте вариант 2 (собрать остаток). - Ждать остатка. Создайте новую CheckoutSession против того же
Order с
amount_due= остаток. Покупатель доплачивает разницу; когда она рассчитается, Order перейдёт вPAID. - Отменить и вернуть. Верните частичную сумму и отмените 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) |
Что дальше
- Концепции → Сессии — обращённая к покупателю оболочка, охватывающая Order.
- Концепции → Возвраты — состояния возврата и ручной шаг on-chain отправки.
- Webhooks → Обзор — каждое событие, которое отправляется в течение жизненного цикла Order.