Commission and payouts
This page explains how Expedition Insure tracks and pays the commission you earn on attributed sales: how your rate is set, how each sale moves through the commission ledger, and how you actually get paid. It’s for operator finance and engineering teams reconciling payouts.
Expedition Insure is the Merchant of Record (MoR): we collect the insurance premium on our own Stripe account, then pay you commission out of band. For the post-sale signal that drives this, see the policy.issued webhook. For where attribution comes from in the first place, see attribution and tracking.
1. commissionRateBps — your commission rate
Section titled “1. commissionRateBps — your commission rate”Your commission rate is stored as commissionRateBps, an integer in basis points:
1000= 10%2000= 20%
Basis points are whole integers, so there is no floating-point drift in the math.
Who sets it: Expedition Insure sets your rate. It is configured on your operator record by Expedition Insure during onboarding; there is no operator-facing setting to change it. You can read your current rate from the operator portal (it appears as commissionRateBps in your operator summary), but you cannot edit it. If your rate needs to change, contact us at help@expedition.insure.
No self-service rate edits yet. A per-operator rate is admin-configured today; an operator-facing or admin UI to adjust it is [needs-product-work].
How commission is computed
Section titled “How commission is computed”Commission is calculated on the gross attributed premium — the full premium for the policy that was attributed to you — in whole US dollars:
commissionUsd = round(attributedPremiumUsd * commissionRateBps / 10000)The base (attributedPremiumUsd) is the policy’s premium, not a net-of-discount figure: if a customer applied a promo credit, that reduces what Expedition Insure collects, not what you are owed. Your rate is snapshotted onto the ledger row at the moment the sale is recorded, so a later rate change never retroactively rewrites past commission.
2. The commission ledger
Section titled “2. The commission ledger”Every attributed sale produces exactly one row in the commission ledger. Each row is keyed to a single quote, so the ledger is idempotent — a sale can never be double-counted. Each row carries:
| Field | Type | Description |
|---|---|---|
operatorId | string | The operator the sale is attributed to. |
quoteId | string | The quote that produced the sale. |
policyNumber | string (optional) | Carrier policy number, once known. |
attributedPremiumUsd | number | Commission base — the policy premium, whole USD. |
commissionRateBps | number | Your rate, snapshotted at record time (immutable per row). |
commissionUsd | number | Computed commission, whole USD. |
payoutModel | string | separate_pi or connect (see section 4). |
status | string | provisional, confirmed, paid_out, or voided. |
source | string | How the row originated (e.g. estimate_at_paid, carrier_confirmation). |
All money on the ledger is in whole US dollars. Cents appear only at the Stripe boundary and in the *Cents fields of the policy.issued webhook.
3. Ledger states and what triggers each
Section titled “3. Ledger states and what triggers each”A ledger row moves through up to four states. The first two are automated; the last two are manual today.
(sale recorded) (carrier confirms premium) ┌──────────────────┐ ┌──────────────────┐ │ provisional │ → │ confirmed │ └──────────────────┘ └──────────────────┘ │ │ └───────────┬───────────┘ ↓ (manual, out of band) ┌──────────────┐ ┌──────────┐ │ paid_out │ │ voided │ └──────────────┘ └──────────┘provisional
Section titled “provisional”The row is created in provisional the moment an attributed payment succeeds. At this stage the commission is computed from the premium estimate captured at the time of payment (source: estimate_at_paid). Recording the sale also fires the policy.issued webhook to your endpoint.
A row is only created when all of these hold: the quote is attributed to your operator, your commissionRateBps is greater than 0, your payoutModel is separate_pi, and the policy has a positive premium. If any of those is missing, no ledger row is written.
confirmed
Section titled “confirmed”When the carrier confirms the firm premium (which can differ from the estimate at payment time), the row is recomputed against the confirmed premium — using the rate snapshot already on the row, never a re-read rate — and moved to confirmed (source: carrier_confirmation). This refreshes attributedPremiumUsd, commissionUsd, and policyNumber.
Confirmation does not re-fire a webhook. The
policy.issuedwebhook fires once, when the sale is first recorded. Reconfirmation updates the ledger silently — reconcile firm figures from the ledger totals in the operator portal, not from a second webhook.
paid_out
Section titled “paid_out”paid_out marks commission you have actually been paid. Under the current model this is set manually as part of the monthly out-of-band invoice settlement; there is no automated transition into paid_out yet — [needs-product-work].
voided
Section titled “voided”voided is reserved for clawbacks — commission reversed because a policy was cancelled or refunded. Automated voiding is not implemented today: there is no cancellation or refund trigger that writes voided, and no webhook notifies you when a commission is reversed — [needs-product-work]. Until that lands, any clawback is handled manually and reconciled against the monthly invoice.
4. Payout models
Section titled “4. Payout models”Your operator record carries a payoutModel. Two models are defined; one is live.
separate_pi — implemented
Section titled “separate_pi — implemented”This is the live model and the default for every new operator. Expedition Insure is the Merchant of Record: the customer’s insurance premium is charged on a separate PaymentIntent on our Stripe account, independent of any trip charge you collect on your own rail. Your commission accrues in the ledger and is paid out of band via a monthly invoice. This is the only model the ledger records — sales for any other model are skipped.
connect — deferred
Section titled “connect — deferred”A Stripe Connect model — where commission is netted automatically through a connected Stripe account — is defined but not implemented. The connectAccountId field is reserved on the operator record but unused, and sales for connect operators are skipped by the commission recorder. Connect-based netting is [needs-product-work].
5. Clawbacks, voids, currency, and netting
Section titled “5. Clawbacks, voids, currency, and netting”- Clawbacks / voids. Not automated yet (see
voided). Refund- or cancellation-driven reversals are handled manually and reflected on the monthly invoice; you are not webhook-notified. - Currency. All ledger and commission math is in whole US dollars. There is no multi-currency handling in the ledger; cents appear only at the Stripe boundary and in the webhook
*Centsfields. - Netting. Under
separate_pi, commission is not netted against any charge in real time — it accrues in the ledger and settles on the monthly invoice. Automatic netting is the goal of the deferredconnectmodel.
6. Where to see what you’re owed and paid
Section titled “6. Where to see what you’re owed and paid”The operator portal surfaces your live commission totals, scoped to your operator only. From your attribution stats you can read:
| Total | Meaning |
|---|---|
commissionOwedUsd | Sum of commissionUsd for rows in provisional + confirmed — owed but not yet paid. |
commissionPaidOutUsd | Sum of commissionUsd for rows in paid_out. |
attributedSales | Count of ledger rows excluding voided. |
salesPremiumUsd | Total attributed premium across non-voided rows. |
premiumGmvUsd | Premium GMV proxy across all attributed quotes. |
Reconcile against
policy.issued, not the UX signal.payment.succeeded(the in-iframe Tier-3 checkout event) is a UX-only signal and can be missed; never settle commission against it. The authoritative post-sale signal is the policy.issued webhook, and the ledger totals above are the source of truth for what you’re owed.
If your totals don’t match your records, contact help@expedition.insure before the monthly invoice settles.