Marketplace & Orders
Routes
Section titled “Routes”| Route | Purpose |
|---|---|
/marketplace | Browse and purchase services |
/marketplace/order-success/[sessionId] | Post-payment confirmation |
/orders | Manage purchases and sales |
Marketplace Browsing
Section titled “Marketplace Browsing”Service Card Display
Section titled “Service Card Display”- Image carousel (main + media array)
- Hub logo, name, and handle
- Service name and description (2-line clamp)
- Category/subcategory badges
- Up to 3 tags (with “+X more” tooltip)
- Starting price (from cents, divided by 100)
- Minimum delivery days
- Package count
- Compare checkbox, favorite heart, message button
Filtering
Section titled “Filtering”| Filter | Description |
|---|---|
| Category | Graphics & Design, Programming, Writing, Video, Music, Business, Personal, Other |
| Subcategory | Context-dependent on category |
| Search | Text search across services |
| Favorites | Toggle to show only favorited services |
Quick View Modal
Section titled “Quick View Modal”Full service details: image carousel, hub info, description, tags, requirements, FAQs, package tiers (Basic/Standard/Premium) with pricing, delivery, and revisions.
Service Comparison
Section titled “Service Comparison”- Select up to 10 services via compare checkboxes
- Side-by-side comparison: price, delivery, packages, requirements
- “View Details” opens quick view per service
Favorites
Section titled “Favorites”Stored at: users/{userId}/favorites/{serviceId}
{ serviceId, hubId, serviceName, serviceImage, hubHandle, hubName, addedAt: serverTimestamp()}Toggle via heart icon on service cards.
Purchase Flow (Step by Step)
Section titled “Purchase Flow (Step by Step)”Step 1: Select Package
Section titled “Step 1: Select Package”User clicks “Select Package” in quick view modal. Package data includes: tier, name, price, deliveryDays, revisions, features, stripePriceId.
Step 2: Order Summary
Section titled “Step 2: Order Summary”Left panel: Package details (tier, name, price, delivery, revisions, features)
Center: Project requirements form
| Field | Required | Validation |
|---|---|---|
| Project Requirements | Yes | Min 10 characters |
| Additional Notes | No | No limit |
Right panel (sticky): Price breakdown (package price + platform fee + total), “Continue to Payment” button.
Platform fee: Currently 0% (previously 3-12% based on seller plan).
Step 3: Payment
Section titled “Step 3: Payment”On “Continue to Payment”:
- Validates requirements >= 10 chars
- Fetches seller’s Stripe Connect account from
stripeAccounts/{sellerId} - Calls
createConnectCheckoutCallableCloud Function with:
{ priceId, sellerStripeAccountId, amountInCents, successUrl: "{origin}/marketplace/order-success", cancelUrl: "{origin}/marketplace", platformFeePercentage: 0, currency: 'USD', buyerId: currentUser.uid, metadata: { serviceId, serviceName, serviceImageUrl, hubId, packageId, packageName, packageTier, sellerId, sellerName, requirements, additionalNotes, deliveryDays, revisions, isSinglePrice }}- Returns
{ sessionId, url, orderId, applicationFeeAmount } - Redirects to Stripe Checkout URL
Step 4: Order Success
Section titled “Step 4: Order Success”Route: /marketplace/order-success/[sessionId]
| Status | Display |
|---|---|
completed | Green checkmark, “Order Confirmed!”, service/package/seller details, buttons: Continue Shopping + View Orders |
failed | Red alert, “Payment Failed”, error message, Back to Marketplace button |
| pending | Loading spinner, “Processing Payment…” |
Orders Page (/orders)
Section titled “Orders Page (/orders)”- Purchases: Orders where current user is buyer
- Sales: Orders where current user is seller
Order Stats
Section titled “Order Stats”- Pending count, Completed count, Disputed count
- Total Spent (purchases) / Total Earned (sales)
Filtering
Section titled “Filtering”- By status: pending, in_progress, completed, cancelled, refunded, disputed
- By search query (service name, seller/buyer name)
Order Card Actions
Section titled “Order Card Actions”| Action | Purchases | Sales |
|---|---|---|
| View Details | Yes | Yes |
| Message | Message Seller | Message Buyer |
| Report Issue | Yes (if not cancelled) | No |
| View Dispute | Yes (if exists) | Yes (if exists) |
Dispute System
Section titled “Dispute System”Filing a Dispute
Section titled “Filing a Dispute”| Field | Required | Validation |
|---|---|---|
| Description | Yes | Min 20 characters |
| Evidence files | No | Max 5 files, max 10MB each |
Accepted file types: JPEG, PNG, GIF, WebP, PDF
Evidence upload path: disputes/{orderId}/{fileId}_{fileName}
Dispute Lifecycle
Section titled “Dispute Lifecycle”open → in_review → resolvedResolution Options
Section titled “Resolution Options”fee_refunded- Platform fee refundedhandle_directly- Parties resolve directly
On Dispute Creation
Section titled “On Dispute Creation”- Dispute document created at
marketplace_disputes/{disputeId} - Order updated with
disputeIdfield - System message sent to other party via chat
- Email notifications generated for admin, buyer, and seller
Dispute Document
Section titled “Dispute Document”{ id, orderId, reporterId, reporterRole: 'buyer'|'seller', description, evidence: [{id, url, name, type, size, uploadedAt}], status: 'open'|'in_review'|'resolved', resolution: 'fee_refunded'|'handle_directly'|null, resolvedAt?, resolvedBy?, adminNotes?, createdAt, updatedAt}Order Document
Section titled “Order Document”Collection: marketplace_orders
{ id, amountInCents, applicationFeeAmount, buyerId, sellerId, serviceId, packageId, checkoutSessionId, stripeAccountId, status: 'pending'|'in_progress'|'completed'|'cancelled'|'refunded', disputeId?: string|null, createdAt, updatedAt}Blockers
Section titled “Blockers”| Blocker | Description |
|---|---|
| Seller no Stripe account | ”Seller has not set up payments yet” |
| Requirements < 10 chars | Payment button disabled |
| Max 5 evidence files | Additional uploads rejected |
| Evidence file > 10MB | Upload rejected |
| Open dispute exists | Cannot file another dispute for same order |