Review

Capture berth deposit after transient-slip confirm

Berthline transient-slip checkout was blocking the HTTP response on Stripe capture (~400–900ms). Move capture off the request path with BackgroundTasks so guests get a confirmed berth immediately after we persist the booking and leave the PaymentIntent authorization in place for async capture.

FastAPITier 4fastapipaymentsbackground-tasksdurability

Click a line to flag it, pick one or more labels, then submit. If the change looks correct, approve it.

app/api/slips/bookings.py+22-4
4848from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException
4949from sqlalchemy.orm import Session
5050
5151from app.db import get_db
5252from app.models import Booking
53-from app.payments import capture_payment_intent
53+from app.payments import capture_payment_intent, mark_capture_failed
5454from app.schemas import BookingCreate, BookingOut
5555
5656router = APIRouter(prefix="/bookings", tags=["bookings"])
5757
58+def _capture_after_confirm(payment_intent_id: str, booking_id: int) -> None:
59+ try:
60+ capture_payment_intent(payment_intent_id)
61+ except Exception:
62+ mark_capture_failed(booking_id, payment_intent_id)
63+
5864@router.post("", response_model=BookingOut)
59-def create_booking(body: BookingCreate, db: Session = Depends(get_db)):
65+def create_booking(
66+ body: BookingCreate,
67+ background_tasks: BackgroundTasks,
68+ db: Session = Depends(get_db),
69+):
6070 booking = Booking(
6171 slip_id=body.slip_id,
6272 guest_id=body.guest_id,
6373 payment_intent_id=body.payment_intent_id,
6474 status="confirmed",
6575 )
6676 db.add(booking)
6777 db.commit()
6878 db.refresh(booking)
69- capture_payment_intent(body.payment_intent_id)
79+ background_tasks.add_task(
80+ _capture_after_confirm,
81+ body.payment_intent_id,
82+ booking.id,
83+ )
70- return BookingOut.model_validate(booking)
84+ return BookingOut(
85+ id=booking.id,
86+ status=booking.status,
87+ payment_status="captured",
88+ )