# Weekend Launch Financial Readiness Brief
**Prepared:** 2026-02-19 19:51 AEDT
**Author:** Harper (Finance/Legal)
**For:** Michael

---

## 1. Payment Processing — VERIFIED ✅

### Stripe Integration Status
- **Keys:** Live keys configured (not test mode) — `STRIPE_TEST_MODE=False`
- **Webhook endpoint:** Active at `/api/webhooks/stripe` (returns 405 on GET = correct)
- **Webhook cold start issue:** RESOLVED per fleet bulletin (was causing missed events)
- **All 4 env vars set:** Secret key, publishable key, public publishable key, webhook secret

### Payment Flow (End-to-End)
1. **Contractor clicks "Hire"** → `HirePaymentModal` opens
2. **Payment Intent created** → server-side via `/api/payments/create`
   - Amount **hardcoded at $50.00 AUD** server-side (can't be tampered by client) ✅
   - Validates: user auth, company ownership, match exists & not rejected, no duplicate payment
   - Rate limited: 10 requests per 15 min per user/IP ✅
   - CSRF protected ✅
3. **Stripe Elements form** → card details entered (never touch our servers) ✅
4. **Payment confirmed** → Stripe webhook fires `payment_intent.succeeded`
5. **Webhook handler:**
   - Updates `payments` table → status = `charged`
   - Updates `matches` table → status = `hired`, `fee_charged = true`, `hired_at` timestamp
   - Creates notification for worker → "You've been hired!"
6. **Success page** → contractor redirected, confirmed

### Security Controls
- Webhook signature verification (replay attack prevention) ✅
- Server-side amount enforcement ($50 hardcoded) ✅
- User authentication required ✅
- Company ownership verified ✅
- Rate limiting (IP + user-level) ✅
- CSRF protection ✅
- 3D Secure / SCA support (automatic via Stripe) ✅
- Failed payments keep `pending` status (retry allowed) ✅
- Cancelled payments deleted from DB ✅

### ⚠️ Items for Michael to Verify Before First Real Payment
1. **Stripe Dashboard:** Confirm webhook endpoint URL is `https://rivet.rateright.com.au/api/webhooks/stripe` (or the final domain)
2. **Stripe Dashboard:** Confirm listening for events: `payment_intent.succeeded`, `payment_intent.payment_failed`, `payment_intent.canceled`
3. **Domain switch impact:** If moving to `rateright.com.au`, the Stripe webhook URL and `return_url` in PaymentForm need updating
4. **Bank account:** Confirm Stripe is connected to the AirWallex account for payouts
5. **Test transaction:** Run one $50 test payment before going live with real contractors

---

## 2. Revenue Tracking — First Hires

### What Gets Recorded Per Hire
| Data Point | Where | How |
|-----------|-------|-----|
| Payment amount ($50) | `payments` table | `amount` field |
| Payment status | `payments` table | `pending` → `charged` |
| Stripe payment ID | `payments` table | `stripe_payment_id` |
| Match ID | `payments` table | Links to job + worker |
| Company ID | `payments` table | Who paid |
| Hire timestamp | `matches` table | `hired_at` |
| Fee charged flag | `matches` table | `fee_charged` |

### Revenue Tracking I'll Maintain
| Metric | Source | Frequency |
|--------|--------|-----------|
| Total revenue (cumulative) | Stripe Dashboard + DB | Weekly |
| Hires per week/month | `matches` WHERE `status = hired` | Weekly |
| Revenue per contractor | `payments` grouped by `company_id` | Monthly |
| Average time to hire | `matches` created_at → hired_at | Monthly |
| Payment success rate | Succeeded vs failed intents | Monthly |
| Stripe fees | Stripe Dashboard | Monthly |

### Stripe Fee Structure (What We Keep)
| Item | Amount |
|------|--------|
| Gross per hire | $50.00 AUD |
| Stripe fee (domestic card) | ~$1.22 (1.7% + $0.30) |
| Stripe fee (international card) | ~$1.70 (2.9% + $0.30) |
| **Net revenue (domestic)** | **~$48.78** |
| **Net revenue (international)** | **~$48.30** |

### Xero Integration (Future)
- Michael has Xero but doesn't use it yet
- When volume warrants: Stripe → Xero integration auto-records revenue
- For now: I'll track manually from Stripe Dashboard + DB

---

## 3. Key Financial Metrics to Watch Post-Launch

### 🔴 Critical (Check Daily in Week 1)
| Metric | Target | Why It Matters |
|--------|--------|----------------|
| **Hires completed** | ≥1 in week 1 | Proof of concept — first dollar of revenue |
| **Payment success rate** | >95% | Failed payments = lost revenue + bad UX |
| **Stripe webhook delivery** | 100% | Missed webhooks = hire confirmed but not recorded |

### 🟡 Important (Check Weekly)
| Metric | Target | Why It Matters |
|--------|--------|----------------|
| **Monthly hires** | 11/mo = breakeven | $715/mo covers $700/mo burn |
| **Unique paying contractors** | Growing | Diversified revenue base |
| **Burn rate vs revenue** | Revenue ↑, burn flat | Path to profitability |
| **Stripe balance & payouts** | Funds arriving | Cash actually hitting AirWallex |
| **Refund rate** | <5% | Quality of matches |

### 🟢 Monthly Review
| Metric | Target | Why It Matters |
|--------|--------|----------------|
| **Unit economics** | >$48 net per hire | After Stripe fees |
| **CAC (cost to acquire contractor)** | <$50 | Must be < lifetime value |
| **R&D spend tracking** | Document all | 43.5% comes back as tax offset |
| **Runway remaining** | >18 months | Safety threshold |
| **GST threshold proximity** | Watch at $60K+ | Register before hitting $75K |

### 📊 Breakeven Dashboard
```
Current burn:     $700/month
Revenue per hire: ~$48.78 net (after Stripe fees)
Breakeven:        15 hires/month (at net rate)
                  OR 11 hires/month (at $65 blended rate if some hires are premium)

At 5 hires/month:  $244/mo revenue → $456/mo cash burn → 53 months runway
At 11 hires/month: $537/mo revenue → $163/mo cash burn → 150+ months runway
At 20 hires/month: $976/mo revenue → $276/mo profit → runway extending
At 50 hires/month: $2,439/mo revenue → sustainable business
```

### ⚡ Alert Triggers (I'll Flag Immediately)
- First payment received (celebrate!)
- Payment failure rate >10%
- Stripe webhook failures
- Any refund or dispute
- Revenue approaching GST threshold ($75K/year)
- Monthly burn increasing unexpectedly
- Runway drops below 24 months

---

## 4. Pre-Launch Checklist for Michael

| # | Item | Status | Action |
|---|------|--------|--------|
| 1 | Stripe live keys configured | ✅ Done | — |
| 2 | Stripe webhook endpoint set | ✅ Code ready | Verify in Stripe Dashboard |
| 3 | Webhook cold start fix | ✅ Resolved | Per fleet bulletin |
| 4 | Stripe → AirWallex payout | ❓ Unknown | Michael to verify in Stripe |
| 5 | Test $50 payment | ❓ Not done | Run before first real customer |
| 6 | Domain switch webhook URL | ⚠️ If switching | Update webhook URL in Stripe |
| 7 | ABN on Stripe receipts | ❓ Check | ABN 62 841 523 907 should appear |
| 8 | Stripe receipt emails | ❓ Check | Auto-receipt to contractor on payment |

---

*"First revenue changes everything. Track every dollar from day one."*
