Skip to content

Orders & Disputes

The orders module manages marketplace transactions from both buyer and seller perspectives, including a dispute resolution system.

Module path: src/lib/modules/orders/ Route: /orders

interface Order {
id: string;
amountInCents: number;
applicationFeeAmount: number; // 5% platform fee
buyerId: string;
sellerId: string;
serviceId: string;
packageId: string;
checkoutSessionId: string;
stripeAccountId: string;
status: OrderStatus;
disputeId?: string | null;
createdAt: Timestamp;
updatedAt: Timestamp;
}
type OrderStatus = 'pending' | 'in_progress' | 'completed' | 'cancelled' | 'refunded';

Firestore collection: marketplace_orders

Two tabs on the orders page:

  • Purchases - Orders where current user is the buyer
  • Sales - Orders where current user is the seller
  • By status: pending, in_progress, completed, cancelled, refunded, disputed
  • By search query
  • Pending count
  • Completed count
  • Disputed count
  • Total spent (purchases) / Total earned (sales)
ordersManager.purchases; // Buyer orders
ordersManager.sales; // Seller orders
ordersManager.currentOrders; // Based on active tab
ordersManager.filteredOrders; // After status/search filters
ordersManager.stats; // OrderStats aggregation
ordersManager.setView('purchases' | 'sales');
ordersManager.setStatus(status);
ordersManager.setSearchQuery(query);
interface Dispute {
id: string;
orderId: string;
reporterId: string;
reporterRole: 'buyer' | 'seller';
description: string;
evidence: DisputeEvidence[];
status: DisputeStatus;
resolution: DisputeResolution;
resolvedAt?: Timestamp;
resolvedBy?: string;
adminNotes?: string;
createdAt: Timestamp;
updatedAt: Timestamp;
}
type DisputeStatus = 'open' | 'in_review' | 'resolved';
type DisputeResolution = 'fee_refunded' | 'handle_directly' | null;
interface DisputeEvidence {
id: string;
url: string;
name: string;
type: string;
size: number;
uploadedAt: Timestamp;
}

Firestore collection: marketplace_disputes

  1. User clicks “Report Issue” on an order card
  2. Enters description (min 20 characters)
  3. Uploads evidence files (max 5 files, 10MB each, images/PDFs)
  4. Files uploaded to Firebase Storage: disputes/{orderId}/{fileId}_{filename}
  5. Dispute created and linked to order via disputeId
  6. Email templates generated for admin, buyer, and seller

Admin resolves with either:

  • fee_refunded - Platform fee refunded
  • handle_directly - Parties handle directly
disputesManager.allDisputes; // Admin view
disputesManager.userDisputes; // Current user's disputes
disputesManager.filteredDisputes; // After filters
disputesManager.createDispute(orderId, description, evidence, role);
disputesManager.resolveDispute(disputeId, resolution, adminNotes);
disputesManager.hasOpenDispute(orderId);
ComponentPurpose
orders-list.svelteMain view with tabs and filters
orders-stats.svelteStats cards
order-card.svelteIndividual order with actions
order-details-modal.svelteFull order information
report-issue-modal.svelteDispute creation with file upload
dispute-details-modal.svelteDispute information and evidence

Per order card:

  • View Details - Full order information
  • Message - Open chat with other party
  • Report Issue - Create dispute (if no open dispute)
  • View Dispute - See existing dispute details