ЮKassa
OPORA поддерживает полный lifecycle ЮKassa-платежа: создание,
захват после авторизации (two-stage), отмена, refund’ы. Separate
policy: payment.{read,write} + refund.{read,write} — refund’ы
можно гейтить отдельно от обычных оплат (fraud-prevention).
За ~10 минут вы:
- Получите
shop_id+secret_keyв кабинете ЮKassa - Сохраните их в OPORA
- Настроите webhook для событий жизненного цикла платежа
- Запустите workflow «incoming order → create payment → email’ом ссылку покупателю → webhook succeeded → записать в 1С»
1. Credentials
Section titled “1. Credentials”- Откройте кабинет ЮKassa:
https://yookassa.ru/my - «Настройки» → «Магазин»
- Раздел «Идентификатор магазина» → скопируйте
shop_id(цифровой, например123456) - «Секретный ключ» → «Выпустить ключ» → скопируйте (он показывается один раз, больше не появится; если потеряете — выпустите новый)
2. Сохраните в OPORA
Section titled “2. Сохраните в OPORA”Settings → Secrets:
yookassa-shop-id: вашshop_idyookassa-secret-key: вашsecret_key
3. Webhook setup
Section titled “3. Webhook setup”После создания workflow’а с yookassa.webhook.trigger нодой, OPORA
покажет URL вида https://app.opora.example/webhook/<uuid>.
Зарегистрируйте его в ЮKassa:
- «Настройки» → «HTTP-уведомления» или «Webhooks»
- «Добавить URL» → вставьте URL OPORA
- События: выберите нужные для вашего workflow’а:
payment.waiting_for_capture— двустадийная оплата, ждёт.capturepayment.succeeded— платёж прошёл (one-stage или.captureзавершён)payment.canceled— отменён вами или истёкrefund.succeeded— возврат прошёл
- Создайте токен валидации (ЮKassa даёт query-param
?<token>в URL; задайте тот же в настройках trigger-ноды OPORA).
4. Workflow пример: order → payment → succeeded
Section titled “4. Workflow пример: order → payment → succeeded”webhook.trigger (generic, from вашего frontend'а) {order_id, amount, customer_email} ↓yookassa.payment.create amount = {{trigger.amount}} description = "Заказ #{{trigger.order_id}}" metadata = {order_id: "{{trigger.order_id}}"} return_url = "https://your-shop.ru/payment-return?order={{trigger.order_id}}" ↓email.send to = {{trigger.customer_email}} subject = "Ссылка на оплату заказа #{{trigger.order_id}}" textBody = "Перейдите: {{payment.create.confirmation.confirmation_url}}"Параллельно — второй агент на события:
yookassa.webhook.trigger (event: payment.succeeded) ↓data_table.rows.update table = "orders" filter = {order_id: {{trigger.object.metadata.order_id}}} patch = {payment_status: "paid", payment_id: {{trigger.object.id}}} ↓onec.odata.create entity = "Document_Реализация" data = {Номер: {{trigger.object.metadata.order_id}}, ...}Ноды ЮKassa
Section titled “Ноды ЮKassa”| Нода | Что делает | Policy |
|---|---|---|
yookassa.webhook.trigger | Incoming events (payment / refund lifecycle) | — |
yookassa.payment.create | Создание платежа (one-stage или two-stage) | payment.write |
yookassa.payment.get | Статус платежа по id | payment.read |
yookassa.payment.capture | Захват после авторизации (two-stage) | payment.write |
yookassa.payment.cancel | Отмена | payment.write |
yookassa.refund.create | Возврат | refund.write |
yookassa.refund.get | Статус возврата | refund.read |
Policy-split: refund’ы отдельно
Section titled “Policy-split: refund’ы отдельно”Policy-разделение позволяет дать одному агенту право создавать
платежи (payment.write) но не возвращать (refund.write) —
типовая fraud-ловушка, когда скомпрометированный workflow массово
refund’ит всё подряд.
В editor’е: открыть ноду yookassa.refund.create → секция
«Policies» → выбрать existing refund-policy или создать новую с
нужным approval-gate’ом (например, refund > 10000₽ требует
approval’а space-owner’а).
Two-stage payments (auth + capture)
Section titled “Two-stage payments (auth + capture)”Для двустадийной оплаты (товар списывается со счёта клиента после фактической отгрузки, а не в момент клика):
yookassa.payment.createсcapture: false→ возвращает payment’а в статусеwaiting_for_capture- Webhook event
payment.waiting_for_capture→ ваш workflow решает, захватывать ли yookassa.payment.captureсamountравным или меньше исходного (частичный захват возможен; remainder возвращается клиенту)
Срок хранения резерва — 7 дней; не захватил — ЮKassa автоматически отменит.
СБП-QR
Section titled “СБП-QR”Для платежей через СБП-QR (Система Быстрых Платежей) ЮKassa принимает
payment_method_data: {type: "sbp"} при создании платежа.
confirmation.confirmation_data вернёт base64-encoded SVG QR’а и
deeplink для мобильного банка покупателя.
OPORA не декодирует QR сам — просто прокидывает в output для frontend’а, который его рендерит.
Troubleshooting
Section titled “Troubleshooting”Invalid Credentials при создании платежа
Section titled “Invalid Credentials при создании платежа”- shop_id / secret_key спутаны (легко — оба цифро-буквенные). Сверьте с кабинетом ЮKassa.
- Магазин в test-mode’е, а key боевой (или наоборот). ЮKassa различает prod / test через префикс key’а.
Webhook не приходит
Section titled “Webhook не приходит”- IP-whitelist ЮKassa блокирует исходящие запросы с IP’ов, отличных от их списка. Убедитесь что ваш webhook-URL открыт наружу и Caddy/nginx пропускает запросы без auth’а (webhook-path должен быть public).
- В кабинете ЮKassa: Настройки → HTTP-уведомления → Логи — там видно, что отправлено и с каким статусом.
INVALID_REQUEST при refund’е
Section titled “INVALID_REQUEST при refund’е”Refund нельзя сделать больше исходного amount’а. Проверьте
refund.create нода получает правильный payment_id + amount
не превышает доступный остаток.
Платёж «висит» в pending
Section titled “Платёж «висит» в pending”Клиент ушёл с платёжной страницы, не завершив 3DS. Через 15 минут
статус сменится на canceled автоматически (webhook придёт).
152-ФЗ
Section titled “152-ФЗ”ЮKassa — российский оператор, соответствует 152-ФЗ и ЦБ’шным требованиям. OPORA хранит только metadata (payment id, amount, status, ваши custom metadata) — реквизиты карты клиента никогда не проходят через control plane, всё идёт напрямую между клиентом и ЮKassa.
Связанное
Section titled “Связанное”- T-Банк / T-Kassa — альтернатива с SBP-QR из коробки и single-source acquirer (карта + СБП + split)
- Bitrix24 — часто в связке: оплата прошла → обновить сделку в CRM