Перейти к содержимому

Платежи

Платформа принимает оплату картой через ЮKassa или Т-Банк. Ключи банка продавец вводит сам в Настройки → Способы оплаты. Покупатель платит на странице банка, а подтверждение оплаты платформа получает от банка сама — уведомлением и регулярной сверкой.

Обработчик Параметры способа оплаты
yookassa — ЮKassa Shop ID, Secret key, Return URL (витрина), Фискализация 54-ФЗ (чек), код НДС: 1 — без НДС, 2 — 0%, 3 — 10%, 4 — 20%, 5 — 10/110, 6 — 20/120
tinkoff — Т-Банк (Т-Касса) Terminal Key, Password, Return URL (витрина), Фискализация 54-ФЗ (чек), система налогообложения (osn, usn_income, usn_income_outcome, esn, patent), НДС (none, vat0, vat10, vat20, vat110, vat120)

Ключи хранятся у каждого способа оплаты своего магазина. Витрина выбирает способ по его коду из eligiblePaymentMethods.

  1. Витрина переводит заказ в ArrangingPayment и вызывает addPaymentToOrder с кодом способа и адресом возврата:

    mutation AddPayment($input: PaymentInput!) {
    addPaymentToOrder(input: $input) {
    __typename
    ... on Order { code state payments { id state method metadata } }
    ... on ErrorResult { errorCode message }
    }
    }
    { "input": { "method": "yookassa", "metadata": { "returnUrl": "https://shop.example/payment-success?code=ABC123" } } }
  2. Сервер платформы создаёт платёж в банке. Платёж получает состояние Authorized, а ссылка на страницу банка приходит в payments[].metadata.public.paymentUrl. Витрина отправляет туда покупателя.

  3. Покупатель платит или уходит со страницы банка. В обоих случаях банк возвращает его на returnUrl.

  4. Банк присылает уведомление, сервер платформы сверяется с банком и переводит платёж в Settled (оплачен) или Cancelled (отменён).

Если returnUrl не передан, берётся Return URL из способа оплаты. Повторный запрос с тем же заказом, суммой и номером попытки не создаёт второй платёж в ЮKassa: ключ идемпотентности стабилен в пределах попытки.

checkOrderPayment просит сервер платформы сверить заказ с банком прямо сейчас, не дожидаясь уведомления:

mutation CheckOrderPayment($orderCode: String!) {
checkOrderPayment(orderCode: $orderCode) {
code
state
payments { id state method createdAt metadata }
}
}
  • Доступ — как у orderByCode: свой заказ или только что оформленный гостем в этой же сессии. Чужой или несуществующий — null.
  • Банк по одному заказу спрашивается не чаще раза в 3 секунды, чаще — заказ отдаётся как есть.
Что пришло Что показать
Заказ PaymentSettled и дальше Заказ оплачен
Платёж Authorized, заказ ждёт оплаты «Ждём оплату», ссылка обратно на страницу банка из metadata.public.paymentUrl
Заказ Cancelled Оплата не прошла, товары можно вернуть в корзину
Последний платёж Declined, Cancelled или Error, заказ не отменён Банк отказал при создании платежа, корзина снова активна

Адрес уведомлений продавец указывает в личном кабинете ЮKassa сам: Интеграция → HTTP-уведомления, события payment.succeeded и payment.canceled. Адрес вида https://<адрес платформы>/payments/yookassa показан в описании способа оплаты в админке.

Телу уведомления сервер не доверяет: статус перечитывает запросом к ЮKassa по номеру платежа и только по нему переводит платёж.

Если исход неясен (банк не ответил на сверку, подтверждение сорвалось), сервер отвечает банку 500, и банк повторяет уведомление. Уведомление по платежу, созданному другим способом оплаты, отклоняется.

Уведомление может не дойти: не настроено в кабинете банка, сбой сети. Поэтому воркер платформы каждые 5 минут сверяет с банками платежи в состоянии Authorized старше 5 минут и младше 30 дней — до 500 за проход, каждый в своём магазине.

Ответ банка Что делает платформа
Оплачен Платёж Settled, заказ PaymentSettled. Если у магазина включены письма о заказе, покупателю уходит письмо об оплате
Отменён, срок вышел, отказ Платёж Cancelled. Заказ, который держался только на нём, — Cancelled с причиной «ЮKassa: оплата отменена» или «Т-Банк: оплата не прошла», остатки освобождаются
Ещё ждёт оплату Ничего, следующая проверка через 5 минут

Без уведомлений оплаченный заказ подтвердится не позже чем через 10 минут после создания платежа, с уведомлениями — сразу.

С включённой фискализацией сервер передаёт банку чек: товары по ценам с учётом скидок и доставку отдельной позицией-услугой, с кодом НДС и признаком полной предоплаты. Сумма чека совпадает с суммой платежа. Для чека нужна почта или телефон покупателя — без них платёж не создаётся.

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