feat: centralized payment gateways + booking widget API
Backend:
- Migration 065: hotel_payment_gateways table (migrates YooKassa from deposit_settings)
- online_bookings table for widget submissions
- Routes: CRUD /api/hotels/:slug/payment-gateways
- Public widget API: /api/widget/:slug/{config,availability,bookings}
- yookassa.ts: add createCharge() for immediate capture
Frontend:
- PaymentSettingsPage: add 'Онлайн-оплата' section with gateway CRUD and module toggles
- DepositSettingsPage: replace YooKassa fields with link to centralized settings
- BookingWidgetPage: connect to real API, show gateway status, real booking submit
- api.ts: add PaymentGateway types, paymentGateways and widget API methods
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -36,6 +36,37 @@ export async function createHold(params: {
|
||||
return res.json() as Promise<YooKassaPayment>
|
||||
}
|
||||
|
||||
// Immediate charge (capture=true) — for online bookings
|
||||
export async function createCharge(params: {
|
||||
shopId: string
|
||||
secretKey: string
|
||||
amount: number
|
||||
description: string
|
||||
returnUrl: string
|
||||
idempotenceKey?: string
|
||||
}): Promise<YooKassaPayment> {
|
||||
const auth = Buffer.from(`${params.shopId}:${params.secretKey}`).toString('base64')
|
||||
const res = await fetch('https://api.yookassa.ru/v3/payments', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Basic ${auth}`,
|
||||
'Content-Type': 'application/json',
|
||||
'Idempotence-Key': params.idempotenceKey ?? randomUUID(),
|
||||
},
|
||||
body: JSON.stringify({
|
||||
amount: { value: params.amount.toFixed(2), currency: 'RUB' },
|
||||
capture: true,
|
||||
confirmation: { type: 'redirect', return_url: params.returnUrl },
|
||||
description: params.description,
|
||||
}),
|
||||
})
|
||||
if (!res.ok) {
|
||||
const err = await res.text()
|
||||
throw new Error(`YooKassa error ${res.status}: ${err}`)
|
||||
}
|
||||
return res.json() as Promise<YooKassaPayment>
|
||||
}
|
||||
|
||||
export async function capturePayment(params: {
|
||||
shopId: string
|
||||
secretKey: string
|
||||
|
||||
Reference in New Issue
Block a user