fix: unify YooKassa webhook to single URL + add webhook instruction in UI

- Consolidate online booking payment handling into existing /api/webhooks/yookassa
  (was previously split — deposit.ts had partial handling, new route had full)
- deposit.ts webhook now fully handles online_bookings: reserved→confirmed,
  payment_status=paid, paid_amount, WS broadcast, and confirmation email
- Remove POST /api/yookassa/webhook (keep only GET /api/online-bookings/:id)
- PaymentSettingsPage: add webhook URL instruction panel with copy button
  showing https://api.hotelsync.ru/api/webhooks/yookassa and required events

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-08 03:08:02 +03:00
parent c8d2d87db4
commit 60c49d97d1
3 changed files with 85 additions and 111 deletions

View File

@@ -411,6 +411,29 @@ export function PaymentSettingsPage() {
</button>
</div>
</div>
{/* Webhook URL instruction */}
<div className="rounded-lg bg-indigo-50 dark:bg-indigo-950/30 border border-indigo-200 dark:border-indigo-800 p-3">
<p className="text-xs font-semibold text-indigo-700 dark:text-indigo-300 mb-1">Настройка вебхука в ЮКассе</p>
<p className="text-xs text-indigo-600 dark:text-indigo-400 mb-2">
В личном кабинете ЮКассы перейдите: <strong>Настройки HTTP-уведомления</strong> и укажите этот URL для всех событий:
</p>
<div className="flex items-center gap-2 bg-white dark:bg-slate-800 rounded-md px-2.5 py-1.5 border border-indigo-200 dark:border-indigo-700">
<code className="text-xs font-mono text-slate-700 dark:text-slate-200 flex-1 break-all">
https://api.hotelsync.ru/api/webhooks/yookassa
</code>
<button
type="button"
onClick={() => navigator.clipboard.writeText('https://api.hotelsync.ru/api/webhooks/yookassa')}
className="text-indigo-400 hover:text-indigo-600 shrink-0"
title="Скопировать"
>
<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
</button>
</div>
<p className="text-[11px] text-indigo-500 dark:text-indigo-400 mt-1.5">
Включите события: <strong>payment.succeeded</strong>, <strong>payment.canceled</strong>, <strong>payment.waiting_for_capture</strong>
</p>
</div>
</div>
<div>
<p className="text-xs text-slate-500 mb-1.5">Использовать в модулях:</p>