1 Poster Wallet
2 Contractor Wallet
3 Add Payment
4 Transactions
5 Detail
6 Escrow
7 Instant Payout
8 Failed
9 Refund
10 Connect
1 / Poster Wallet
9:41
Wallet
Total Balance
$2,847.50
2 active escrow holds · 1 pending refund
Payment Methods
+ Add New
Visa ending 4242
Expires 08/27
DEFAULT
Apple Pay
iPhone 15 Pro
Chase ···· 8891
Checking account
Recent Transactions
View All
Kitchen Remodel Escrow
Feb 20, 2026
-$4,200.00
FUNDED
Deck Repair Escrow
Feb 18, 2026
-$1,850.00
HOLD
Gutter Cleaning Refund
Feb 15, 2026
+$350.00
REFUNDED

WalletScreen (poster variant)

useQuery(api.payments.wallet.getPosterSummary)

2 / Contractor Wallet
9:41
Earnings
Available Balance
$6,312.40
Pending
$3,918.60
This Week
$2,190.60
Stripe Connect
Payouts enabled
ACTIVE
Bank Account
Huntington ···· 3457
Business checking · Weekly payouts
Weekly Summary
Jobs completed 4
Gross earnings $7,200.00
Platform fee (6.7%) -$482.40
Net earnings $6,717.60

WalletScreen (contractor variant)

useQuery(api.payments.wallet.getContractorEarnings)


3 / Add Payment Method
9:41
Add Payment
Express Checkout
OR ADD CARD
Save as default
Use for future payments

AddPaymentMethodScreen

useMutation(api.stripe.stripe.createSetupIntent)

4 / Transaction History
9:41
Transactions
Feb 1 – Feb 24, 2026
All
Payments
Refunds
Payouts
February 2026
Kitchen Remodel
Feb 20 · Escrow funding
-$4,200.00
COMPLETE
Deck Repair
Feb 18 · Escrow funding
-$1,850.00
PENDING
Gutter Cleaning Refund
Feb 15 · Refund processed
+$350.00
REFUNDED
Bathroom Tile
Feb 10 · Escrow released
-$2,100.00
RELEASED
Roof Inspection
Feb 5 · Payment failed
-$450.00
FAILED

TransactionHistoryScreen

useQuery(api.payments.financialTransactions.list)

5 / Transaction Detail
9:41
Transaction
$4,200.00
COMPLETED
Escrow funding · Feb 20, 2026
Status Timeline
Initiated
Feb 20, 2:14 PM
Processing
Feb 20, 2:14 PM
Completed
Feb 20, 2:16 PM
Details
From Visa ···· 4242
To 3bids Escrow
Reference pi_3Qx...kLm
Linked Job
Kitchen Remodel
742 Evergreen Terrace, Akron OH

TransactionDetailScreen

useQuery(api.payments.financialTransactions.get)


6 / Escrow Detail
9:41
Escrow
Escrow Balance
$4,200.00
HOLD PERIOD
24-Hour Hold Period
Fraud prevention · work begins after
14:32:08
remaining
Payout Split
40%
60%
First payout (after hold)
$1,567.44
Final payout (completion)
$2,351.16
Platform fee (6.7%)
$281.40
Milestone Releases
Escrow Funded
Feb 20, 2:16 PM
$4,200
Hold Period Ends
Feb 21, 2:16 PM · 14h left
3
First Payout (40%)
Auto-releases after hold
$1,537
4
Final Payout (60%)
After job completion
$2,306

EscrowDetailScreen

useQuery(api.payments.escrow.getForJob)

7 / Instant Payout
9:41
Instant Payout
Available for Payout
$6,312.40
Huntington ···· 3457
Fee Breakdown
Payout amount $6,312.40
Instant fee (1.5%)
Standard payouts are free
-$94.69
You receive $6,217.71
Destination
Huntington ···· 3457
Arrives in minutes
Instant payouts arrive in minutes to your linked debit card or bank. Standard weekly payouts have no fee.

InstantPayoutScreen

useMutation(api.stripe.stripe.createInstantPayout)


8 / Payment Failed
9:41
Payment Failed
Payment Declined
Your card ending in 4242 was declined. Please try a different payment method.
Suggested Fixes
Update card details
Check expiration date and CVV
Contact your bank
They may have flagged the transaction
Check available funds
Ensure sufficient balance exists

PaymentFailedScreen

Error state from useMutation(api.payments.escrow.fund)

9 / Refund Request
9:41
Request Refund
Gutter Cleaning
515 Oak St, Cuyahoga Falls OH
$350.00
Refund Type
Full Refund
Partial
Reason for Refund
Work incomplete
Quality issues
Contractor no-show
Scope disagreement
Other
Refund Amount
Original payment $350.00
Refund amount $350.00
Refunds typically process in 5–10 business days back to your original payment method.

RefundRequestScreen

useMutation(api.payments.escrow.requestRefund)

10 / Connect Onboarding
9:41
Get Paid
Step 2 of 3
Bank Details
Where should we send your earnings?
Verify Identity
ID uploaded · verified
DONE
Bank Details
Add routing & account number
CURRENT
Tax Information
W-9 · required for payouts
PENDING
Checking
Savings
Powered by Stripe Connect. Your banking information is securely handled and never stored on our servers.

StripeConnectOnboardingScreen

useMutation(api.stripe.stripe.createConnectOnboardingLink)

Data Architecture

Schema

escrow

jobId: Id<jobs> posterId: Id<posterUsers> contractorId: Id<contractorUsers> totalBidAmount: number escrowBalance: number status: pending | hold_period | funded | first_payout_pending | first_payout_sent | second_payout_pending | released | refunded | disputed platformFee: number? contractorNetAmount: number? holdPeriodEndsAt: number? firstPayoutAmount/At: number? secondPayoutAmount/At: number? version: number? (optimistic lock)

financialTransactions

escrowId: Id<escrow> jobId: Id<jobs> posterId: Id<posterUsers> contractorId: Id<contractorUsers> transactionType: escrow_funding | contractor_payout | platform_fee | refund transactionDirection: credit | debit amount: number description: string stripePaymentIntentId: string? stripeTransferId: string?

stripeSync

clerkId: string userType: "poster" | "contractor" stripeCustomerId: string stripeConnectAccountId: string? subscriptionStatus: string? defaultPaymentMethodBrand: string? defaultPaymentMethodLast4: string? connectChargesEnabled: boolean? connectPayoutsEnabled: boolean? connectDetailsSubmitted: boolean?

Status Flows

Escrow Flow

pendinghold_period (24h) → fundedfirst_payout_pendingfirst_payout_sentsecond_payout_pendingreleased Any stage can → disputed or refunded

Financial Model ($4,200 example)

Platform Fee: 6.7% = $281.40 Contractor Net: = $3,918.60 1st Payout: 40% = $1,567.44 (after 24h hold) 2nd Payout: 60% = $2,351.16 (after completion) Constants: PLATFORM_FEE_RATE = 0.067 FIRST_PAYOUT_RATE = 0.4 HOLD_PERIOD_MS = 86,400,000 (24h)

Hooks & Queries

Frontend Hooks

useQuery(api.payments.wallet.getPosterSummary) useQuery(api.payments.wallet.getContractorEarnings) useQuery(api.payments.escrow.getForJob) useQuery(api.payments.financialTransactions.list) useQuery(api.payments.financialTransactions.get) useMutation(api.payments.escrow.fund) useMutation(api.payments.escrow.requestRefund) useMutation(api.stripe.stripe.createSetupIntent) useMutation(api.stripe.stripe.createInstantPayout) useMutation(api.stripe.stripe.createConnectOnboardingLink)

Stripe Integration Points

createCustomer — on user signup createPaymentIntent — escrow funding listPaymentMethods — wallet display createConnectAccount — contractor onboarding createConnectOnboardingLink — step-through createTransfer — payout to contractor constructEvent — webhook verification Webhooks: payment_intent.succeeded, account.updated, transfer.created, charge.refunded

Security Measures

Payment Security

Optimistic locking (version field) TOCTOU race condition prevention Stripe webhook signature verification Idempotency keys on all mutations Refund deduplication (processedRefundIds) Rate limiting on public endpoints PCI compliance via Stripe Elements

Indexes

escrow: by_job_id, by_poster_id, by_contractor_id, by_status, by_stripe_payment_intent financialTransactions: by_escrow_id, by_job_id, by_stripe_refund_id stripeSync: by_clerk_id, by_stripe_customer_id, by_user
Wallet Overview
9:41
Wallet Overview
Poster Wallet
$2,450
Balance
$1,200
In Escrow
Payment Methods
Visa ****4242
Expires 08/27
Default
Chase ****8910
Checking
Recent Transactions
Kitchen Renovation
Mar 8, 2026
-$3,500
Refund — Plumbing
Mar 5, 2026
+$450
Deck Installation
Mar 1, 2026
-$2,800
Escrow & Payouts
9:41
Escrow & Payouts
Escrow Details
Status
Hold Period
Amount
$3,500.00
Hold Expires
Mar 10, 2026
Payout Timeline
Payment Received
Mar 8, 2026
24h Hold Period
Ends Mar 9
40% First Payout
$1,400
60% Final Payout
$2,100
Wallet Dashboard
https://app.3bids.io/wallet
3Bids
Wallet ⌘1
Transactions ⌘2
Escrow ⌘3
Methods ⌘4
Instant Payout ⌘5
Stripe Connect ⌘6
JM
James Mitchell
Homeowner
Settings ⌘,

Wallet Dashboard

$2,450
Balance
$1,200
In Escrow
$12,400
Total Paid
2
Cards
Recent Transactions
Kitchen Renovation
Mar 8
-$3,500
Refund — Plumbing
Mar 5
+$450
Spending Trend
Transaction Center
https://app.3bids.io/wallet/transactions
3Bids
Wallet ⌘1
Transactions ⌘2
Escrow ⌘3
Methods ⌘4
Instant Payout ⌘5
Stripe Connect ⌘6
JM
James Mitchell
Homeowner
Settings ⌘,

Transaction Center

47
Total
12
Completed
3
Pending
1
Failed
Active Escrows
Kitchen Reno
Hold — 18h left
$3,500
Deck Build
Funded
$2,800
Payment Methods
Visa ****4242
Default
Chase ****8910
Checking