--- name: fake-stripe-testing description: Build a fake Stripe-like payment system for testing booking/purchase flows that create real DB records without actual payment processing category: devops --- ## When to Use - Testing booking/purchase flows in development or staging - Need to verify data flows from mobile/frontend → backend → database → admin dashboard - Want realistic-looking transaction data without Stripe API costs or complexity ## Architecture ### Backend Endpoints (Express + PostgreSQL) **1. POST /api/checkout/class** - Accepts: `{ class_id, customer_id }` - Creates: `reservations` record with `payment_status: 'Paid'` - Decrements available_spots on the class - Returns: reservation object with fake Stripe ID **2. POST /api/checkout/product** - Accepts: `{ product_id, customer_id }` - Creates: `orders`, `line_items`, `transactions` records - If credit package: auto-creates `credits` record and updates customer totals - Calculates sales tax (e.g., 8.25% TX rate) - Generates fake but realistic transaction data ### Fake Data Generator Generate realistic-looking Stripe-style data: ```js function generateFakeTransaction(amount, feePercent = 0.029, flatFee = 0.30) { const fee = amount * feePercent + flatFee; const net = amount - fee; const orderId = [random(4), random(4), random(4)].map(s => s.toUpperCase().replace(/\d/g, c => 'ABCDEFGH'[parseInt(c)]) ).join('-'); const stripeId = 'ch_fake_' + random(8); return { order_number: orderId, stripe_charge_id: stripeId, payment_method: 'Card (Visa •••• 4242)', gateway: 'Stripe (Fake)', device_type: 'Mobile App', fee_amount: fee.toFixed(2), net_amount: net.toFixed(2), created_at: new Date().toISOString() }; } ``` ### Frontend Checkout Modal Key UI components: - Pre-filled test card number: **4242 4242 4242 4242** - Expiry: any future date (e.g., 12/28) - CVC: any 3 digits - Shows breakdown: subtotal, tax, total - Green confirmation on success: "You're booked!" or "Purchase complete!" - Updates UI state immediately (e.g., spots remaining decreases) ## Implementation Steps 1. **Add backend endpoints** in `server/index.js`: - Route order matters: `/customers/search` BEFORE `/customers/:id` - Use transactions for multi-table writes (orders + line_items + transactions) 2. **Create CheckoutModal component**: - Accepts `type` ('class' or 'product') and `item` props - Shows item details, price breakdown, fake card form - Calls appropriate API endpoint on confirm 3. **Wire up existing screens**: - ClassDetail: "Book This Class" → opens CheckoutModal - ProductDetail: "Purchase" → opens CheckoutModal - Add success state handling (show confirmation, refetch data) 4. **Test the full flow**: - Profile → Sign In (Demo) → search customer - Schedule/Shop → select item → Book/Purchase → Confirm - Verify DB records created - Check admin dashboard shows new reservation/order ## Pitfalls - **Route ordering**: Search endpoints must come BEFORE `:id` param routes - **Timezone handling**: DB stores UTC, frontend displays local - be consistent - **Customer lookup**: Need working search before checkout (or hardcode test user ID) - **Credit packages**: Ensure purchase triggers credit creation + customer total updates ## Verification After booking/purchase: ```sql -- Check reservation SELECT * FROM reservations WHERE customer_id = 9999 ORDER BY created_at DESC LIMIT 1; -- Check order + transaction SELECT * FROM orders WHERE customer_id = 9999 ORDER BY created_at DESC LIMIT 1; SELECT * FROM transactions WHERE order_id = [last_order_id]; -- Check customer credits updated (if applicable) SELECT total_remaining_credits, total_spent_all FROM customers WHERE id = 9999; ``` All records should appear in the admin dashboard under their respective sections. ## Session-specific implementation notes absorbed from `fake-stripe-payments` - Existing-table pattern that worked well: - class bookings write `reservations` with confirmed/paid semantics and decrement class spots - product purchases write `orders`, `order_line_items`, `transactions`, and optionally `customer_credits` - Useful fake production markers: - charge IDs like `ch_fake_` - payment intent IDs like `pi_fake_` - order numbers shaped like `VAGD-DG2B-5KV7` - gateway label `Stripe (Fake)` and display payment method `Visa ending in 4242` - Mobile/testing UX that matched expectations: - prefill test card `4242 4242 4242 4242` - calculate tax and Stripe-style fees visibly in the modal - return success payloads that look realistic enough for downstream admin dashboards and receipts - Credit-package purchases must update both the credits table and aggregate customer totals, not just create an order row.