feat: card rail via LNbits fiat providers (Stripe), per operator
A guest may pay a fiat-priced room by card when its owner has opted in and
LNbits core has a fiat provider for that user — resolved through
settings.get_fiat_providers_for_user(owner), the seam lnbits#67's per-user
Stripe Connect credentials will plug into; chatelet stores no credentials.
Both rails now go through create_payment_request: Lightning unchanged
(sats, deposit_sat), card charges the same deposit share of the fiat price
in the room's currency with extra.checkout parameterising the hosted
Stripe page — success/cancel return to {frontend}/chatelet/{room}?checkout=…
&booking=<id>, customer_email, line item, metadata. frontend_url is
allow-listed against the instance's trusted origins (ported from events)
and resolved before the hold so a refused rail never leaves a dead hold.
Core settles the Stripe webhook onto the same invoice queue, so
tasks.on_invoice_paid confirms card bookings unchanged.
BookingRequestData gains payment_method / fiat_provider / frontend_url;
BookingQuote gains fiat_payment_request / fiat_provider / is_fiat and a
nullable payment_request. RPC chatelet_booking_request passes the fields
through. min_lnbits_version → 1.4.1 (events' floor for these APIs).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
8557ce617e
commit
0dad30b648
11 changed files with 417 additions and 36 deletions
10
views_api.py
10
views_api.py
|
|
@ -7,7 +7,7 @@ endpoints (room/block CRUD, settings) are HTTP-only and back the admin UI;
|
|||
the guest-facing surface (availability, booking) is what also rides the RPC.
|
||||
"""
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query, Request
|
||||
from lnbits.core.models import User, WalletTypeInfo
|
||||
from lnbits.decorators import check_user_exists, require_admin_key, require_invoice_key
|
||||
|
||||
|
|
@ -277,9 +277,13 @@ async def api_check_availability(q: AvailabilityQuery) -> AvailabilityResult:
|
|||
|
||||
|
||||
@chatelet_api_router.post("/api/v1/bookings", status_code=201)
|
||||
async def api_request_booking(data: BookingRequestData) -> BookingQuote:
|
||||
async def api_request_booking(
|
||||
data: BookingRequestData, request: Request
|
||||
) -> BookingQuote:
|
||||
try:
|
||||
return await services.request_booking(data)
|
||||
return await services.request_booking(
|
||||
data, base_url=str(request.base_url)
|
||||
)
|
||||
except services.BookingError as exc:
|
||||
raise HTTPException(502, str(exc)) from exc
|
||||
except ValueError as exc:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue