Lines and rails

The running jobjob_7Hq2 · accepted · document.fr-CA.pdf · $49.00 final

The lines a charge carries beside the price, and who sells each one. Pass-through fees at cost, flat lines, referral shares and placement; then the three sellers a fee can have, the brand, the member at the same checkout, or an entity you own, which the rules decide.

A charge can carry more than your price, and not every dollar of it is yours to sell. Lines say what else the buyer pays. Rails say who sells each fee, on whose account.

price.lines adds lines to the charge. Each is itemized on the receipt and leaves the take's base with its proof:

LineWrittenCharged toLeaves the base with
Pass-through{ at: 'cost', from: 'fee' }the buyer, at what the outside system charged, never marked upits receipt
Pass-through you caused{ at: 'cost', from: 'fee', fault: 'brand' }you, when the repeat fee follows your own errorits receipt
Flat{ usd: 25, to: 'courier' }the buyer, per job, such as a courier's deliveryits act
Referral share{ share: '1%', of: 'closed_value', to: 'referrer', on: 'won' }the buyer, at that end, never a member's paythe outcome
Placementset by the Pool you importyou, per Task the Pool fillsthe filled Task: placement

A pass-through on api.lawyer, when the office asks for a second class's fee:

Run
git diff services/trademark-response.ts
magic values: none
-  price: { usd: 349, release: 'file' },
+  price: { usd: 349, release: 'file', lines: { office: { at: 'cost', from: 'fee' } } },
Call
→ GET /owner/matters/job_7Hr2   # the office asked for a second class's fee
200 · job_7Hr2 · trademark-response · delivered · $699.00 released · magic values: none
  record  file · receipt.rejected · fee_deficiency → fee · rcp_7Hr2 $350.00 paid to USPTO → file · rcp_7Hr3 accepted
  ledger  +$699.00 · office $350.00 at cost, rcp_7Hr2 (pass-through) · attorney's fee $175.00, sold by the attorney (rail member) · brand $174.00 · AI $2.10 · coverage $4.00 · you $167.90
  take    on $170.00 · the office fee leaves the base with its receipt

A referral share on api.forsale, charged to the seller beside the 5%, so the closer keeps every dollar of theirs:

Run
grep -n -B1 "referral" services/deal.ts   # the referrer's line, beside the price
magic values: none
51-  price: { usd: 0, share: '5%', of: 'closed_value', on: 'won', ai: 40,
52:    lines: { referral: { share: '1%', of: 'closed_value', to: 'referrer', on: 'won' } } },
Call
→ GET /owner/deals/job_7Hr4   # won, with a referrer
200 · job_7Hr4 · deal · won · $9,920.00 charged, held to 2027-01-12 · magic values: none
  ledger  +$9,920.00 · closer $6,200.00 (share, from the seller) · referrer $620.00 (line, from the seller) · placement $25.00 · AI $10.80 · you $3,064.20 before the take
  take    on $3,075.00 · never on the referral or the closer's share

Each role's fee has a seller:

railWho sells the feeWhere the money landsOn the receipt
'brand'you, the defaultyour account; you pay the member outone seller
'member'the member, at the same checkout as your chargethe member's own payout account, whole, never your balancetwo sellers, one payment
'entity'an entity you own, which contracts with the member and keeps a spreadthe entity's accountthe entity beside you

A role's rail is its rules row's rail, so the row that reserves an act also says who may sell it. check fails rail_conflict when a role says otherwise. The rail is fixed when the Task posts, never per act, so one job can carry two: your product fee on the brand rail and a professional fee on the member's.

Run
grep -A3 "'trademark-response': {" rules.ts
magic values: none
    'trademark-response': {
      respond: { reserved: 'bar admission', where: '*', rail: 'member', position: 'A response for the applicant is signed by an attorney admitted in any state.' },
      file: { reserved: 'bar admission', where: '*', rail: 'member', position: 'Filing the response for the applicant is practice before the office.' },
      fee: { open: true, position: 'Paying the office its fee is a delivery act.' },

check reads both rails back, with what each seller sells:

Run
npx services.dev check services/trademark-response.ts
magic values: none
services/trademark-response.ts · 21 lines · $349 per job, within 48 hours, charged on file's receipt.
  rails   attorney · member, from the respond and file rows · the attorney sells $175.00 on their own account
          brand · api.lawyer sells $174.00 · one checkout, two sellers, one receipt
  reads   API.LAWYER* TM RESPONSE (Brand.descriptor) · <attorney> VIA API.LAWYER (Pool.descriptor)
  ledger  +$349.00 · attorney's fee $175.00, sold by the attorney (rail member) · brand $174.00 · AI $2.10 (example) · coverage $4.00 · you $167.90
  take    on $170.00 · never on the attorney's fee

The buyer enters one card at one checkout. It writes two charges, one on behalf of you and one on behalf of the member, each released by the same fact. At Stripe the card is authenticated once, by a SetupIntent, then two manual-capture PaymentIntents authorize, the member's first. A decline of the second cancels the first before the 402 answers, so a buyer never holds half a checkout. Both capture at the fact, and on a bank account both are debited then:

captured/money-rails.txt · 200 · magic values: none
→ GET /owner/matters/job_7Hq3/charges
{
  "object": "list",
  "checkout": "chk_7Hq3",
  "data": [
    { "id": "chg_7Hq3", "object": "charge", "seller": "brand", "amount": 17400, "currency": "usd", "status": "earned", "take": { "base": 17000 }, "stripe": { "type": "separate", "on_behalf_of": "acct_…L4w1", "payment_intent": "pi_…Hq3", "transfer_group": "job_7Hq3" } },
    { "id": "chg_7Hq4", "object": "charge", "seller": "member", "member": "mbr_7Hq3", "amount": 17500, "currency": "usd", "status": "earned", "take": null, "stripe": { "type": "destination", "on_behalf_of": "acct_…7Hq3", "payment_intent": "pi_…Hq4", "transfer_group": "job_7Hq3" } }
Call
→ POST /matters {"service":"trademark-response",…,"max_usd":349,"payment_method":"pm_…0341"}   # the card covers one charge, not both
402 · magic values: none
{
  "type": "OFFER",
  "code": "payment_declined",
  "reason": "The card authorized the attorney's $175.00, then declined api.lawyer's $174.00, so the attorney's authorization was canceled: payment_intent.canceled, charge.voided. Nothing is held.",
  "next": { "do": "pay", "url": "https://api.lawyer/pay/chk_7Hr0", "note": "another card or a bank account, for both charges together" },
  "doc_url": "https://services.dev/docs/money/lines-and-rails#the-two-seller-checkout"
}

The receipt names both sellers and how each reads on the buyer's statement, from Brand.descriptor and Pool.descriptor. The member reads the fee as their own sale:

Call
→ GET /matters/job_7Hq3/receipt   # the client, in the customer portal
200 · job_7Hq3 · paid · $349.00 · one checkout, two sellers · chk_7Hq3 · magic values: none
  api.lawyer           $174.00   the response, drafted, reviewed and filed · USPTO receipt rcp_7Hq3
                                 on your statement as API.LAWYER* TM RESPONSE
  mbr_7Hq3, attorney   $175.00   the attorney's fee, sold by the attorney · bar admission, US-NY
                                 on your statement as J DOE ESQ VIA API.LAWYER
  card                 …4242 · both authorized 2 Nov, together · charged 9 Nov 2026, when the receipt arrived
  final                16 Nov 2026 · each seller refunds only its own line
Call
→ GET /me/earnings/tsk_7Hq3   # as mbr_7Hq3, in the delivery portal
200 · tsk_7Hq3 · api.lawyer · attorney · respond · $175.00 · your own sale · magic values: none
  sold      Mon 9 Nov 15:12   on your payout account, at the client's checkout   $175.00
  costs     none: api.lawyer pays the processing and the Pool's cover, and services.dev takes nothing from your fee
  final     yours

A member-rail role needs a member whose payout account can accept payments. Until it can, the claim answers rail_unavailable with the cure:

Call
→ POST /tasks/tsk_7Hr5/claim   # as mbr_7Hs3, whose payout account can't take payments yet
409 · magic values: none
{
  "type": "BLOCKED",
  "code": "rail_unavailable",
  "reason": "This Task sells your fee on your own account, and your account can't accept payments yet: Stripe asks for your tax ID.",
  "next": { "do": "open", "url": "/me/payouts", "note": "finish your payout account, then claim again" },
  "doc_url": "https://services.dev/docs/money/lines-and-rails#the-two-seller-checkout"
}

The member's charge carries no take, and its refund or dispute is its own: refunds and disputes. Where each charge lands at Stripe, and who carries a lost dispute on it, is flow of funds.

AppWhat it shows
Customer portalOne receipt with a line per seller, each with its name, credential and statement descriptor, and every pass-through with its receipt
Delivery portalOn the member rail, the fee as the member's own sale, on their payout account
Owner consoleThe ledger by rail: what you sold, what members sold, and each pass-through with its receipt
KeyWrittenLeft outDoes
price.lines.<name>{ at: 'cost'; from: <step>; fault?: 'brand' } | { usd; to } | { share; of; to; on }noneA pass-through, flat or share line on the charge
roles.<r>.pay.rail'brand' | 'member' | 'entity'the row's railWho sells the role's fee
Rules row rail'brand' | 'member' | 'entity''brand'The rail for the act's role
Brand.descriptorstring, up to 22 charactersthe domain, uppercasedHow your charge reads on the buyer's statement, with each Service's short name after it
Pool.descriptorstring, with the member's name as {member}the member's name, then VIA and your domainHow a member-rail charge reads on the buyer's statement
CodeWhen
rail_conflictcheck: a role's rail contradicts its rules row
rail_unavailablea claim of a member-rail Task by a member whose account can't accept payments, or whose country can't settle a charge made on their behalf in the buyer's currency; the answer names the cure
payment_declineda checkout where either charge was declined: both are voided, and the 402 asks for another card or a bank account

Pass-through and flat lines run live on Free, placement on Launch, and referral shares on Team. On every plan, a fee a rules row puts on the member rail sells through the two-seller checkout, and services.dev's take never touches it (never for sale).