feat: YooKassa webhook, payment timeout, reserved status, BookingConfirmPage
- Add YooKassa webhook handler (POST /api/yookassa/webhook) that updates booking to confirmed+paid on payment.succeeded, cancelled on payment.canceled - Add public status endpoint GET /api/online-bookings/:id for return URL polling - Add 'reserved' booking status (violet) shown in calendar while awaiting payment - Add 'website' to BookingSource type - Payment timeout job (every 2 min) auto-cancels expired unpaid bookings - Widget setting: "Время ожидания оплаты" (5–60 min, default 15) - BookingConfirmPage at /booking-confirm/:id — polls status, countdown timer, shows success/pending/cancelled state - Widget bookings now use status='reserved' instead of 'inquiry' when YooKassa is configured; set to 'confirmed' by webhook on payment.succeeded - Migration 070: add 'reserved' to bookings status constraint + payment_expires_at Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,7 @@ export function formatDate(date: string, opts?: Intl.DateTimeFormatOptions) {
|
||||
|
||||
export const BOOKING_STATUS_LABELS: Record<BookingStatus, string> = {
|
||||
inquiry: 'Запрос',
|
||||
reserved: 'Зарезервирована',
|
||||
confirmed: 'Подтверждён',
|
||||
checked_in: 'Заселён',
|
||||
checked_out: 'Выехал',
|
||||
@@ -31,6 +32,7 @@ export const BOOKING_STATUS_LABELS: Record<BookingStatus, string> = {
|
||||
|
||||
export const BOOKING_STATUS_COLORS: Record<BookingStatus, string> = {
|
||||
inquiry: 'bg-amber-400 border-amber-600',
|
||||
reserved: 'bg-violet-400 border-violet-600',
|
||||
confirmed: 'bg-brand-500 border-brand-700',
|
||||
checked_in: 'bg-emerald-500 border-emerald-700',
|
||||
checked_out: 'bg-slate-400 border-slate-600',
|
||||
@@ -40,6 +42,7 @@ export const BOOKING_STATUS_COLORS: Record<BookingStatus, string> = {
|
||||
|
||||
export const BOOKING_STATUS_BADGE: Record<BookingStatus, string> = {
|
||||
inquiry: 'bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-300',
|
||||
reserved: 'bg-violet-100 text-violet-800 dark:bg-violet-900/30 dark:text-violet-300',
|
||||
confirmed: 'bg-brand-100 text-brand-800 dark:bg-brand-900/30 dark:text-brand-300',
|
||||
checked_in: 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900/30 dark:text-emerald-300',
|
||||
checked_out: 'bg-slate-100 text-slate-600 dark:bg-slate-700 dark:text-slate-300',
|
||||
@@ -54,6 +57,8 @@ export const SOURCE_LABELS: Record<BookingSource, string> = {
|
||||
booking_com: 'Booking.com',
|
||||
airbnb: 'Airbnb',
|
||||
expedia: 'Expedia',
|
||||
vrbo: 'VRBO',
|
||||
website: 'Сайт',
|
||||
other: 'Другое',
|
||||
}
|
||||
|
||||
@@ -62,6 +67,8 @@ export const SOURCE_COLORS: Record<BookingSource, string> = {
|
||||
booking_com: 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300',
|
||||
airbnb: 'bg-rose-100 text-rose-800 dark:bg-rose-900/30 dark:text-rose-300',
|
||||
expedia: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-300',
|
||||
vrbo: 'bg-cyan-100 text-cyan-800 dark:bg-cyan-900/30 dark:text-cyan-300',
|
||||
website: 'bg-violet-100 text-violet-800 dark:bg-violet-900/30 dark:text-violet-300',
|
||||
other: 'bg-slate-100 text-slate-700 dark:bg-slate-700 dark:text-slate-200',
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user