Net after fuel, labor, equipment, and Stripe. On every job, automatically
Every quote returns net-after-Stripe-fees and equipment cost. Every job persists fuel, labor, and equipment cost columns at booking time. The bookkeeping panel rolls them up against actual Stripe payouts so the numbers reconcile.
Below: seven shipped pieces of the cost-tracking pipeline, with column and route citations for each.
Seven pieces of the cost-tracking pipeline
Each piece is shipped. Open the linked file or admin URL to audit.
- 01
Every quote returns net-after-fees explicitly
The `/api/quote` response includes `net_after_fees` on every quote — calculated as `quoted_price - (quoted_price × 0.029 + 0.30)` for Stripe-collected jobs. The customer sees the gross price; you see what actually lands in your bank account. The booking-page summary shows it as "You receive: $X" alongside the customer-facing "Total: $Y" so there’s no end-of-month surprise about Stripe’s cut.
stripeNetAfterFees() in packages/shared/src/pricing.ts; net_after_fees on POST /api/quote response
- 02
Card-fee passthrough flips who pays Stripe
If you turn on `pass_card_fee_to_customer` at the service level, the engine adds the 2.9% + 30¢ to the customer’s quoted price and `net_after_fees` becomes the full quoted amount — because the customer absorbed Stripe’s cut. `card_fee_included: true` rides on the quote response so the booking page can render "$X (card fee included)" cleanly. You choose: eat the fee and net less, or pass it through and net the full quoted price.
pass_card_fee_to_customer flag; card_fee_included on /api/quote response
- 03
Equipment cost is computed on every quote
Each service can have equipment assigned to it (riding mower, edger, blower). Each `equipment_type` has a `cost_per_hour` value. The quote engine multiplies hours (from `estimated_time_mins / 60`, or a per-equipment `hours_override`) by the cost-per-hour and returns the total as `equipment_cost` on the quote response. The number persists on the job row when the customer books.
equipment_types.cost_per_hour; calculateEquipmentCost() in pricing.ts; equipment_cost on /api/quote and jobs.equipment_cost column
- 04
Every job persists four cost columns
When a job is created the engine writes `fuel_cost`, `labor_cost_drive`, `labor_cost_job`, and `equipment_cost` into the row alongside `distance_miles`, `drive_time_mins`, `estimated_time_mins`, and `actual_time_mins`. These aren’t calculated on the fly in a report — they’re snapshotted at booking time so historical jobs reflect the costs as they were that day, not as your settings are today.
jobs.fuel_cost, jobs.labor_cost_drive, jobs.labor_cost_job, jobs.equipment_cost columns
- 05
Cost inputs live in /admin/settings
`/admin/settings` → Labor & Fuel has the two inputs that drive the cost columns: `default_labor_rate_per_hour` ($/hr — typically your loaded cost: wage + payroll tax + insurance) and `fuel_mpg` (vehicle fuel economy). Distance is geocoded; drive time is estimated; the resulting fuel and labor costs are written to the job row at booking. Edit the rates seasonally if your costs shift — historical jobs keep their snapshotted values.
tenants.settings.default_labor_rate_per_hour, tenants.settings.fuel_mpg
- 06
The admin jobs table shows Stripe-net per completed job
The completed-jobs view in `/admin/jobs` renders the Stripe-net amount (`final_price × (1 - 0.029) - 0.30`) in the rightmost column for every completed row. It’s the same calculation the quote engine returns on `net_after_fees`, applied to the actual `final_price` after any on-site adjustments. You see, line by line, what each job put into your bank account after Stripe.
JobsTable.tsx renders final_price × (1 - 0.029) - 0.30 for completed jobs
- 07
Period profit rollup lives in /admin/bookkeeping
The bookkeeping panel aggregates the persisted cost columns across all jobs whose payments hit the selected period (dedup by job_id). It surfaces total fuel, total labor, total equipment, total miles, and the resulting net profit (gross job income minus the rolled-up costs). The export ties to Stripe payouts so the numbers reconcile against what landed in your bank.
/admin/bookkeeping aggregates jobs.fuel_cost + labor_cost_job + equipment_cost per payment period
The math, in plain terms
Stripe net. quoted_price − (quoted_price × 0.029 + 0.30) — the deduction Stripe takes from every card charge. This is the number returned as net_after_fees on the quote and shown in the jobs table for every completed job.
Labor cost. estimated_time_mins / 60 × default_labor_rate_per_hour — snapshotted into jobs.labor_cost_job at booking. labor_cost_drive tracks the round-trip drive labor separately.
Equipment cost. Σ (hours × equipment_types.cost_per_hour) for every piece of equipment assigned to the service — written to the quote as equipment_cost and persisted on the job row.
Fuel cost. round-trip distance / fuel_mpg × per-gallon cost — persisted as jobs.fuel_cost.
Period profit. Σ payments − Σ (fuel_cost + labor_cost_job + equipment_cost) over the selected period, dedup’d by job_id — what /admin/bookkeeping displays alongside the Stripe payout reconciliation.
Where each number surfaces
/api/quote—net_after_fees,equipment_cost,card_fee_included,below_target_rateon every quote response./admin/jobs— Stripe-net column on every completed job; click into the job detail for the full line-item breakdown, the target-rate flag, and operator price adjustments./admin/bookkeeping— period profit rollup with fuel / labor / equipment / miles totals, reconciled against Stripe payouts; CSV export for accounting./admin/settings→ Labor & Fuel — the two cost inputs (`default_labor_rate_per_hour`, `fuel_mpg`) that drive the snapshotted cost columns at booking time.
Profit-per-job FAQs
Why is "profit" rolled up by period in bookkeeping instead of shown per row on the jobs table?+
How is the Stripe cut shown on the customer-facing quote?+
What about payment_collection = external — jobs you take by cash or check?+
How accurate is the labor cost — you’re using estimated_time_mins, not actual?+
What about fuel price — gas is not the same per gallon everywhere.+
Can my bookkeeper export this for QuickBooks?+
Does the operator queue show profit?+
See net-after-fees on your own pricing
14-day free trial. Set your labor rate, your fuel MPG, and equipment cost-per-hour; run a real booking; read the cost columns on the job row and the rollup in /admin/bookkeeping.
14-day free trial · No card required · Cancel any time