# Moore Sunny Daze — Reservation System with Stripe ## Architecture Overview ``` Guest Browser → Landing Page → Check Availability → Book → Stripe Checkout → Confirmation ↑ Admin Dashboard (Tim) ``` ## Components ### 1. Public Booking Flow ``` Landing Page (mooresunnydaze.com) → "Check Availability" button → Availability calendar (fetches from API) → Select dates → guest count → price quote → Guest details form (name, email, phone, # guests, pet?) → Stripe Checkout (embedded or redirect) → Confirmation page + email ``` ### 2. Backend API (FastAPI on Core/app1) | Endpoint | Method | Purpose | |----------|--------|---------| | `/api/availability` | GET | Get booked dates for a month | | `/api/quote` | POST | Calculate price for selected dates | | `/api/booking` | POST | Create booking (pending payment) | | `/api/booking/{id}/confirm` | POST | Confirm after Stripe payment | | `/api/booking/{id}` | GET | View booking details | | `/api/guest/{email}` | GET | Lookup returning guest | ### 3. Database Schema (SQLite) ```sql -- Guests CREATE TABLE guests ( id TEXT PRIMARY KEY, name TEXT NOT NULL, email TEXT UNIQUE NOT NULL, phone TEXT, notes TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Bookings CREATE TABLE bookings ( id TEXT PRIMARY KEY, guest_id TEXT REFERENCES guests(id), check_in DATE NOT NULL, check_out DATE NOT NULL, guests_count INTEGER NOT NULL, nightly_rate REAL NOT NULL, cleaning_fee REAL DEFAULT 150, total REAL NOT NULL, status TEXT DEFAULT 'pending', -- pending, confirmed, cancelled, completed stripe_session_id TEXT, stripe_payment_intent TEXT, notes TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- Blocked Dates CREATE TABLE blocked_dates ( date DATE PRIMARY KEY, reason TEXT -- 'booking_XYZ', 'maintenance', 'owner' ); -- Rate Rules CREATE TABLE rate_rules ( id TEXT PRIMARY KEY, name TEXT, start_date DATE, end_date DATE, nightly_rate REAL, min_nights INTEGER DEFAULT 3 ); ``` ## Stripe Integration ### Setup 1. Tim creates Stripe account (stripe.com) 2. Connects business bank account 3. We get API keys from Stripe Dashboard 4. Store in `.env` on server ### Payment Flow ```python # 1. Create Stripe Checkout Session session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price_data': { 'currency': 'usd', 'product_data': { 'name': f'Moore Sunny Daze — {nights} nights', 'description': f'{check_in} to {check_out}, {guests} guests' }, 'unit_amount': int(total * 100), # cents }, 'quantity': 1 }], mode='payment', success_url='https://mooresunnydaze.com/booking/confirmed?session_id={CHECKOUT_SESSION_ID}', cancel_url='https://mooresunnydaze.com/booking/cancelled', customer_email=guest_email, metadata={ 'booking_id': booking_id, 'property': 'moore-sunny-daze' } ) # 2. Redirect to session.url # 3. Stripe webhook → mark booking confirmed ``` ### Webhook Handling ```python @app.post("/stripe-webhook") async def stripe_webhook(request: Request): payload = await request.body() sig = request.headers.get('stripe-signature') event = stripe.Webhook.construct_event(payload, sig, WEBHOOK_SECRET) if event['type'] == 'checkout.session.completed': session = event['data']['object'] booking_id = session['metadata']['booking_id'] mark_booking_confirmed(booking_id) send_confirmation_email(booking_id) add_blocked_dates(booking_id) return {"status": "ok"} ``` ## Deployment ### Server - Deploy on Core (152.53.33.195) as systemd service - Port: 8910 (internal) - Caddy reverse proxy: `mooresunnydaze.com/api/* → localhost:8910` ### Filesystem ``` /opt/mooresunnydaze/ ├── server.py # FastAPI app ├── db.sqlite # SQLite database ├── .env # STRIPE_SECRET_KEY, etc ├── requirements.txt # fastapi, uvicorn, stripe, aiosqlite └── templates/ # Email templates ``` ### systemd Service ```ini # /etc/systemd/system/mooresunnydaze.service [Unit] Description=Moore Sunny Daze Booking API After=network.target [Service] Type=simple User=root WorkingDirectory=/opt/mooresunnydaze ExecStart=/opt/mooresunnydaze/venv/bin/uvicorn server:app --host 127.0.0.1 --port 8910 Restart=always [Install] WantedBy=multi-user.target ``` ## Admin Features 1. **Calendar view** — booked/available/blocked dates 2. **Booking management** — confirm, cancel, view details 3. **Guest directory** — past guests, contact info, stay history 4. **Rate management** — seasonal pricing, minimum stays 5. **Block dates** — maintenance, owner use 6. **Revenue reports** — monthly/annual totals 7. **Email templates** — confirmation, pre-arrival, post-stay ## Pricing Integration Tim's property is currently listed at ~$295/night (peak season, from Airbnb). We'd implement: - **Base rate:** $295/night peak, $225/night off-peak - **Cleaning fee:** $150 flat - **Pet fee:** $50 (if applicable) - **Minimum stay:** 3 nights - **Holiday premium:** +20% for major holidays ## Comparison: Direct vs VRBO | | VRBO (current) | Direct (our system) | |---|---|---| | 3-night stay @ $295 | $885 + VRBO fee (~$130) | $885 (no fee) | | Guest pays | ~$1,015 | $885 | | Owner receives | ~$885 - VRBO 5% host fee | $885 - Stripe 2.9% | | Owner net | ~$840 | ~$859 | | **Savings to guest** | — | **$130 (13%)** | | **Savings to owner** | — | **~$19/stay + guest relationship** | ## Next Steps 1. ✅ Design complete 2. Set up Stripe account for Tim 3. Build FastAPI backend 4. Deploy on Core 5. Wire up booking widget on landing page 6. Test end-to-end booking flow 7. Go live