link,[object Object]
Skip to content

Deals & Transactions

Overview

The deals system manages the complete transaction lifecycle from offer acceptance to business transfer completion. This includes escrow management, due diligence, asset handover, and payment processing.

Deal Steps Guide (Buyer & Seller)

The deal process follows a structured 6-phase approach with clear responsibilities for each party:

Phase 1: Kickoff Tab 🎯

Status: offer_pending → offer_accepted

  • Buyer: Send offer, sign NDA (REQUIRED), sign LOI (optional)
  • Platform: Send notifications, create NDA/LOI automatically, verify signatures
  • Seller: Analyze/accept offer, sign NDA (REQUIRED), sign LOI (optional)
  • Next Step: When NDA is signed by BOTH parties → proceed to Phase 2: Financing
  • ⚠️ IMPORTANT: Deal cannot proceed to financing without signed NDA from both buyer and seller

Phase 2: Financing Tab 💰

Status: payment_required → funded

  • Prerequisites: NDA must be signed by both buyer and seller
  • Buyer:
    • Receive notification
    • Access Financing tab
    • Choose payment provider (Stripe or External Escrow)
    • Option A: Make payment through Stripe PaymentIntent
    • Option B: Submit external escrow details (provider, reference, URL)
  • Platform:
    • Send funding notification
    • Create Stripe PaymentIntent (held funds) OR receive external escrow details
    • Confirm payment and update status OR verify external escrow documents (admin)
    • Hold funds securely (pseudo-escrow) OR confirm external funds deposited (admin)
  • Seller:
    • Wait for funding confirmation
    • Option A: Confirm funds are in platform
    • Option B: Wait for external escrow confirmation
  • Next Step: When payment is confirmed (Stripe) or external escrow details submitted → proceed to Phase 3: Due Diligence (Data Room)

Phase 3: Due Diligence (Data Room) Tab 📁

Status: funded → dd_in_progress

  • Seller: Receive Data Room access, upload all required documents, confirm documents complete
  • Platform: Automatically unlock Data Room, send seller notification, offer buyer access, wait for due diligence
  • Buyer: Access Data Room, analyze documents, can add additional requirements and send message to seller for clarifications (direct shortcut to chat). When everything is OK, buyer clicks "DD OK — continue to APA".
    • On click, system requests double confirmation, logs dd_reviewed_by_buyer and automatically switches tab to APA.
  • Next Step: When due diligence is complete → proceed to Phase 4: APA

Phase 4: APA Tab 📋

Status: dd_in_progress (continues)

  • Buyer: Access APA tab, receive pre-populated draft, edit and complete APA, finalize for signing, sign APA
  • Platform: Create APA draft automatically, generate final PDF, verify signatures, auto-transition to handover
  • Seller: Receive APA notification, review APA, confirm content, sign finalized APA
  • Next Step: When APA is signed by both parties → proceed to Phase 5: Handover

Phase 5: Handover Tab 🔄

Status: dd_in_progress → handover_in_progress → assets_delivered

  • Seller: Receive notification, access Handover tab, transfer all assets, mark transferred elements, confirm complete delivery, mark assets delivered
  • Platform: Auto-transition to handover_in_progress, offer Handover tab access, receive confirmation
  • Buyer: Receive access to all assets, confirm asset receipt (button always visible, disabled after confirmation)
  • UI Features:
    • Handover Documents section displayed as accordion (similar to Steps guide)
    • Confirmation button styled consistently with Due Diligence tab
    • Visual feedback for completed confirmation
  • Next Step: When all assets are delivered → proceed to Phase 6: Payout

Phase 6: Payout Tab 💸

Status: assets_delivered → buyer_accepts → payout_released → completed

  • Buyer: Receive notification, access Payout tab, check guards, confirm asset receipt, mark buyer_accepts
  • Platform: Send confirmation notification, offer Payout tab access, check all guards, verify guards are green, ready for admin approval, release payout, mark payout_released, finalize deal
  • Seller: Receive payout notification, check payout status, confirm ready for payout, receive final payout
  • UI Features:
    • Dynamic Status Display: Seller KYC and Payout Status show correct verification status with dates
    • Stripe Transfer Details: Real-time transfer information when payout is released
      • Transfer ID, amount (net after commission), status, initiation time, expected arrival
      • Status determination: "reversed" if transfer.reversed, "paid" if destination_payment exists, "pending" otherwise
    • Commission Calculation: Correct net amount displayed (total amount - platform commission)
    • Date Tracking: Timestamps for Seller KYC, Buyer Accepts, and Ready status
  • Next Step: 🎉 Deal completed successfully!

Notes (DD shortcuts)

  • Buyer has a quick button "Send DD message to seller" that opens the deal's conversation in chat for specific clarifications.
  • Buyer confirms completion of their DD analysis through "DD OK — continue to APA" (double confirmation + event log + automatic switch to APA tab).

Payment Provider Options

mermaid
graph LR
    A[Offer Accepted] --> B[Payment Required]
    B --> C[Funded/Escrow]
    C --> D[Due Diligence]
    D --> E[Handover Process]
    E --> F[Buyer Confirmation]
    F --> G[Payout Released]
    G --> H[Completed]
    
    B --> I[Payment Failed]
    C --> J[Disputed]
    D --> K[DD Failed]

Status Definitions

StatusDescriptionTimelineKey Actions
offer_acceptedSeller accepted buyer's offerDay 0Payment setup required
payment_requiredAwaiting buyer fundingDays 1-3Fund escrow account
fundedEscrow funded successfullyDay 3Begin due diligence
dd_in_progressDue diligence periodDays 3-17Document review, Q&A
handover_in_progressAsset transfer phaseDays 17-27Transfer accounts, domains
buyer_acceptsBuyer confirms receiptDay 27Authorize payout
payout_releasedSeller payment processedDay 28Transaction complete
completedDeal fully closedDay 30Archive and review

External Escrow (Verified by AcqMarketplace)

AcqMarketplace offers two escrow options for deal funding:

1. Stripe Escrow (Default)

  • Provider: Stripe Connect
  • Process: Funds held in Stripe escrow account
  • Features: Automated payment processing, instant payouts
  • Use Case: Standard deals requiring fast, automated processing

2. External Escrow (Verified by AcqMarketplace)

  • Provider: External services (Escrow.com, Wise, Bank Wire, Crypto)
  • Process: Platform verifies external escrow arrangements
  • Features: Document verification, milestone tracking, manual confirmation
  • Use Case: High-value deals, international transactions, custom requirements

External Escrow Flow

mermaid
graph LR
    A[Choose External Escrow] --> B[Submit Escrow Details]
    B --> C[Admin Verifies Documents]
    C --> D[Admin Confirms Funds]
    D --> E[Due Diligence Process]
    E --> F[Asset Handover]
    F --> G[Buyer Confirms Receipt]
    G --> H[Admin Finalizes Release]
    H --> I[Deal Completed]
    
    C --> J[Documents Rejected]
    J --> B

Stripe vs External Escrow — key differences

AspectStripe (default)External Escrow (Verified by AcqMarketplace)
InitiationBuyer pays through Stripe Checkout/PaymentIntentBuyer/Seller complete external provider details; no money movement in application
Provider immutabilityBecomes immutable after payment initiationBecomes immutable after submitting external details
Fund holdingStripe holds funds until releaseExternal provider holds funds; application only verifies
VerificationsAutomated (Stripe webhooks)Manual (doc verify, funds confirmed, release confirmed)
PayoutAutomatic via release-deal-payoutManual: admin finalizes external release, then finalize-deal
Platform commissionAutomatically deducted at releaseSeparate invoice (Payment Link) after Completed
ObservabilityStripe webhooks + payment_status statusInternal events + external_* fields on transactions

Note: provider selection is done in the financing tab and cannot be changed after initiation, for consistency and audit.

Harmonized status machine (summary)

  • Stripe: offer_accepted → payment_required → funded → dd_in_progress → handover_in_progress → buyer_accepts → payout_released → completed
  • External: offer_accepted → financing (provider selection) → external_funds_confirmed ↔ docs_verified → apa/signatures → handover → buyer_accepts → external_release_confirmed → completed

Involved Edge Functions (quick reference)

  • Stripe: create-deal-payment, release-deal-payout, refund-deal-payment, payment-status, webhook: stripe-webhook
  • External: set-deal-provider, submit-external-escrow-details, admin-verify-docs, mark-external-funded, buyer-confirm-receipt, admin-finalize-external-release

See details in docs/architecture/edge-functions.md and contracts in docs/architecture/apis.md.

External Escrow Components

Provider Selection

File: src/components/deal/tabs/FinancingTab.tsxFeatures:

  • Provider selector (Stripe vs External)
  • Immutable choice after selection
  • Clear UI distinction between options

External Details Form

File: src/components/deal/tabs/FinancingTab.tsxFeatures:

  • External escrow provider selection
  • Transaction reference/ID input
  • Dashboard URL (optional)
  • Proof of funds upload

Admin Verification Tools

File: src/pages/admin/AdminTransactions.tsxFeatures:

  • Document verification (approve/reject)
  • External funds confirmation
  • Release finalization
  • Timeline tracking
  • Status badges and indicators

External Escrow Status Flow

StatusDescriptionAdmin Action Required
external_details_submittedUser submitted escrow detailsReview and verify documents
docs_verifiedDocuments approved by adminNone
external_funds_confirmedAdmin confirmed external fundsNone
buyer_confirmedBuyer confirmed asset receiptFinalize release
external_release_confirmedAdmin confirmed external releaseNone
completedDeal fully closedNone

Core Components

Deal Dashboard

File: src/pages/DealDetail.tsxFeatures:

  • Deal timeline with progress visualization
  • Document management tabs
  • Checklist tracking system
  • Signature collection interface
  • Communication thread

Transaction Management

File: src/pages/admin/AdminTransactions.tsxFeatures:

  • Admin oversight of all deals
  • Payment status monitoring
  • Dispute resolution tools
  • Force progression controls
  • Export capabilities
  • Enhanced Admin Actions:
    • Tooltips for all action buttons with clear descriptions
    • Informative alerts based on transaction status (completed, payout_released, ready for approval)
    • Stripe Transfer Details: Real-time transfer information display
      • Transfer ID, amount, status, processing time
      • Automatic status updates every 30 seconds
      • Processing time estimates and arrival dates
  • Visual Transaction Marking:
    • Completed transactions marked with green background and left border
    • Consistent styling across admin and user transaction views

Data Model

Core Table: transactions

sql
id uuid PRIMARY KEY
listing_id uuid REFERENCES listings(id)
buyer_id uuid REFERENCES profiles(id) 
seller_id uuid REFERENCES profiles(id)
amount numeric NOT NULL
amount_gross numeric -- Including fees
commission_amount numeric
commission_rate numeric
status transaction_status DEFAULT 'offer_accepted'
created_at timestamptz DEFAULT now()

Supporting Tables

  • deal_events_log: Timeline tracking for all deal activities
  • deal_signatures: Contract and document signature management
  • deal_checklist_items: Task tracking for handover process
  • deal_documents: Secure document storage and sharing

Deal Timeline Visualization

Stepper Component

File: src/components/deals/DealStepper.tsx

typescript
const DEAL_STEPS = [
  { id: 1, name: "Offer Accepted", status: "offer_accepted" },
  { id: 2, name: "Payment Required", status: "payment_required" },  
  { id: 3, name: "Funded", status: "funded" },
  { id: 4, name: "Due Diligence", status: "dd_in_progress" },
  { id: 5, name: "Handover", status: "handover_in_progress" },
  { id: 6, name: "Buyer Confirms", status: "buyer_accepts" },
  { id: 7, name: "Payout Released", status: "payout_released" },
  { id: 8, name: "Completed", status: "completed" }
]

Event Logging System

Function: populate_deal_timeline_events(deal_id)

Automatically creates timeline entries when deal status changes:

sql
-- Example event log entries
INSERT INTO deal_events_log (deal_id, actor_id, event_type, details)
VALUES 
  (deal_id, buyer_id, 'offer_accepted', '{"amount": 50000}'),
  (deal_id, buyer_id, 'deal_funded', '{"escrow_amount": 52500}'),
  (deal_id, NULL, 'due_diligence_started', '{"deadline": "2025-01-30"}')

Document Management

Document Categories

  1. Purchase Agreement: Legal contract between parties
  2. Financial Records: Business financial documentation
  3. Asset Lists: Inventory of included business assets
  4. Transfer Documents: Account access and handover materials

Document Upload System

typescript
// Document upload with categorization
const uploadDealDocument = async (file: File, dealId: string, category: string) => {
  const filePath = `deals/${dealId}/${category}/${file.name}`
  
  const { data, error } = await supabase.storage
    .from('deal-documents')
    .upload(filePath, file, {
      metadata: {
        dealId,
        category,
        uploadedBy: userId,
        uploadedAt: new Date().toISOString()
      }
    })
}

Access Control

  • Buyers/Sellers: Full access to their deal documents
  • Admins: Access to all deal documents for support
  • Third Parties: No access (strict privacy protection)

Signature Collection System

Digital Signatures

Table: deal_signaturesFeatures:

  • Multi-party signature collection
  • Document versioning and tracking
  • Signature validation and timestamping
  • Automatic PDF generation with signatures
typescript
// Signature collection workflow
const requestSignature = async (dealId: string, signerRole: 'buyer' | 'seller', docType: string) => {
  await supabase.from('deal_signatures').insert({
    deal_id: dealId,
    signer_role: signerRole,
    doc_kind: docType,
    status: 'requested'
  })
  
  // Send notification to signer
  // Generate signature link
}

Checklist Management

Handover Checklist

Table: deal_checklist_itemsCategories:

  • Legal: Contracts, agreements, compliance documents
  • Technical: Domain transfers, hosting accounts, codebase
  • Financial: Bank accounts, payment processors, tax records
  • Operational: Customer lists, vendor relationships, processes

Checklist Templates

typescript
const DEFAULT_CHECKLIST_ITEMS = [
  // Legal Items
  { label: "Purchase agreement signed", category: "legal", required: true },
  { label: "Asset transfer agreement", category: "legal", required: true },
  
  // Technical Items  
  { label: "Domain name transferred", category: "technical", required: true },
  { label: "Hosting account access", category: "technical", required: true },
  { label: "Source code repository", category: "technical", required: false },
  
  // Financial Items
  { label: "Revenue verification", category: "financial", required: true },
  { label: "Expense documentation", category: "financial", required: true },
  
  // Operational Items
  { label: "Customer database", category: "operational", required: true },
  { label: "Operational procedures", category: "operational", required: false }
]

Progress Tracking

typescript
// Calculate completion percentage
const calculateProgress = (items: ChecklistItem[]) => {
  const requiredItems = items.filter(item => item.required)
  const completedRequired = requiredItems.filter(item => item.completed_at)
  
  return (completedRequired.length / requiredItems.length) * 100
}