Skip to content

Happy path: the Tienda Frescura sale

A story with 6 characters that shows the commissions module in action — from the first click on the landing page to the bonus payment at month 3.


Cast

CharacterRoleFunction
Tienda FrescuraCustomer (tenant)Supermarket that pays the monthly subscription
Pablo RamírezSDR — Sales Development RepProspects and brings in the lead. Co-participant in the sale
María GonzálezAE — Account ExecutiveCloses the deal. Primary participant
Carlos ManagerSales managerMaría's direct manager. Earns override
Diana DirectorRegional directorCarlos's manager. Earns second-level override
Sopinf Tech LLCThe MSPOwner of the SipSop product. Retains the rest of the revenue

Hierarchy

Diana Director (override 5%)
  └── Carlos Manager (override 10%)
        └── María González (AE, 70% of split)

Pablo Ramírez (SDR, 30% of split) — no manager in this example

Diana and Carlos earn override on the commission that corresponds to María (not on Pablo's, because Pablo isn't in their reporting chain).


The sale — real numbers

Tienda Frescura subscribes to the Business plan:

ComponentPriceStripe source
Base plan$79.00stripe_base_price_id
5 phones × $4.80$24.00stripe_phone_price_id
1 SIP line$12.00stripe_line_price_id
International overage$3.20stripe_overage_price_id
Monthly total$118.20

Terms agreed with the reps when creating the assignment:

  • Participants: María 70% (role: AE) + Pablo 30% (role: SDR)
  • % per component: base 5% · phones 3% · lines 2% · overage 10%
  • One-time bonus: $200, vesting 3 months
  • Basis: gross (without deducting Stripe fees)

System configuration

commission_reps

María González — email: maria@sopinf.com — managerId: carlos.id
Carlos Manager — email: carlos@sopinf.com — managerId: diana.id — overridePercent: 10
Diana Director — email: diana@sopinf.com — managerId: null — overridePercent: 5
Pablo Ramírez  — email: pablo@sopinf.com — managerId: null — overridePercent: 0

commission_assignment for Tienda Frescura

tenantId: tienda-frescura.id
recurringPercent: 5 (global fallback — not used in breakdown mode)
basis: gross
startsAt: 2026-02-01
oneTimeAmountCents: 20000 ($200)
recurringPercentBase: 5
recurringPercentPhones: 3
recurringPercentLines: 2
recurringPercentOverage: 10
participants:
  - María González: sharePercent=70, role='AE'
  - Pablo Ramírez: sharePercent=30, role='SDR'

Monthly flow (months 1, 2, and 3)

Billing day: Stripe charges Tienda Frescura

Stripe issues the invoice. The invoice.paid webhook reaches the API. The handler breaks down the invoice into 4 lines and creates 4 revenue_events:

revenue_events for Tienda Frescura, period 2026-02:
  source: stripe_invoice | component: base     | amountUsdCents: 7900
  source: stripe_invoice | component: phones   | amountUsdCents: 2400
  source: stripe_invoice | component: lines    | amountUsdCents: 1200
  source: stripe_invoice | component: overage  | amountUsdCents: 320
  Total gross: $118.20

Day 1 of the following month: cron generates statements

The commissions-monthly job runs at 3am UTC and calls materializeStatementsForPeriod('2026-02').

Calculator calculation by component:

The engine buckets revenue events by component and applies the corresponding %:

ComponentRevenue% María (70%)% Pablo (30%)
base$79.005% × $79 × 0.70 = $2.775% × $79 × 0.30 = $1.19
phones$24.003% × $24 × 0.70 = $0.503% × $24 × 0.30 = $0.22
lines$12.002% × $12 × 0.70 = $0.172% × $12 × 0.30 = $0.07
overage$3.2010% × $3.20 × 0.70 = $0.2210% × $3.20 × 0.30 = $0.10
Total$118.20$3.66$1.57

Note: cents use Math.round(). There may be a ±1¢ difference due to rounding.

Override walk for María's line items:

Carlos Manager (10% override, María's manager):

  • $3.66 × 10% = $0.37 (override on María's base line items)

Diana Director (5% override, Carlos's manager):

  • $3.66 × 5% = $0.18 (override on María's original commission — no compounding)

Pablo has no manager, so he generates no upward overrides.

Statements generated (months 1–3, recurring only):

RepTypeAmount
María Gonzálezrecurring split$3.66
Pablo Ramírezrecurring split$1.57
Carlos Manageroverride on María$0.37
Diana Directoroverride on María$0.18

Sopinf retains: $118.20 - $3.66 - $1.57 - $0.37 - $0.18 = $112.42


Month 4 — one-time bonus vesting

startsAt = 2026-02-01. oneTimeQualificationMonths = 3. The cron on May 1, 2026 generates the April 2026 statement. qualifiedAt = 2026-05-01, which falls within [2026-04-01, 2026-04-30].

The calculator detects that the assignment qualified for the one-time bonus this period. It includes a kind='one_time' line item for $200 total, prorated by share:

RepRecurringOne-timeOverride one-timeMonth 4 total
María González$3.66$140.00 (70%)$143.66
Pablo Ramírez$1.57$60.00 (30%)$61.57
Carlos Manager$0.37$14.00 (10% of $140)$14.37
Diana Director$0.18$7.00 (5% of $140)$7.18

When finalizing the month 4 statement, the service marks commission_assignments.oneTimePaidAt = '2026-04-01'. The bonus won't appear again in future months.


Complete timeline

Day 0:   Pablo spots an opportunity. Shares landing.sipsop.net?ref=pablo-ramirez
         with Tienda Frescura. (In this example, Pablo has no ref code — María closes.)

Day 5:   María contacts Tienda Frescura. Convinces the owner to do the demo.

Day 12:  Tienda Frescura fills out the landing form with ?ref=maria-gonzalez.
         First-touch cookie is set (90 days).
         POST /api/v1/leads → lead.commissionRepId = maría.id

Day 15:  Admin approves the lead and creates the tenant.
         Signup service detects lead.commissionRepId → creates commission_assignment automatically.
         Log: action='lead_converted'

Day 15:  Admin edits the assignment: adds Pablo as 30% SDR, adjusts María to 70% AE.
         replaceParticipants → log: action='admin_reassigned'

Day 15:  Tienda Frescura activates their Stripe subscription (Business plan).

Day 31:  First charge. webhook invoice.paid → 4 revenue_events (base, phones, lines, overage)

Day 60:  Second charge. 4 more revenue_events.

Day 90:  Third charge. 4 more revenue_events.

Day 1/3: March cron materializes February statements.
Day 1/4: April cron materializes March statements.
Day 1/5: May cron materializes April statements — includes one-time bonus.

Day 102: María and Pablo open /seller/dashboard, see statements for all 4 months.
         Download PDF statements.

Day 110: Admin reviews statements in /admin/commissions/statements.
         Finalizes each one (oneTimePaidAt is marked when finalizing month 4).
         Marks as paid: paymentMethod='ach', paymentReference='ACH-20260510'.

Money flow

mermaid
flowchart TD
    A[Tienda Frescura\n$118.20/mo] -->|Stripe invoice.paid| B[revenue_events\n4 events per component]
    B --> C[commission-calculator\ncalculateForPeriod]
    C --> D[María's Statement\n$3.66 recurring\n+ $140 one-time month 4]
    C --> E[Pablo's Statement\n$1.57 recurring\n+ $60 one-time month 4]
    C --> F[Carlos's Statement\noverride 10% on María\n$0.37 recurring]
    C --> G[Diana's Statement\noverride 5% on María\n$0.18 recurring]
    A -->|retains| H[Sopinf Tech LLC\n$112.42]

María's PDF statement (month 4)

The PDF generated by renderStatementPdf looks something like this:

STATEMENT — María González
Period: 2026-04-01 / 2026-04-30
Status: FINALIZED

TENANT              KIND               COMPONENT   REVENUE     RATE   AMOUNT
Tienda Frescura     recurring_percent  base        $79.00      5%     $2.77
Tienda Frescura     recurring_percent  phones      $24.00      3%     $0.50
Tienda Frescura     recurring_percent  lines       $12.00      2%     $0.17
Tienda Frescura     recurring_percent  overage     $3.20       10%    $0.22
Tienda Frescura     one_time           —           —           —      $140.00

SUBTOTAL RECURRING:                                                    $3.66
SUBTOTAL ONE-TIME:                                                   $140.00
SUBTOTAL OVERRIDE:                                                     $0.00
TOTAL:                                                               $143.66

Carlos's PDF statement (month 4)

Carlos sees his override line items with the source rep:

STATEMENT — Carlos Manager
Period: 2026-04-01 / 2026-04-30
Status: FINALIZED

TENANT              KIND      ON               COMPONENT   RATE   AMOUNT
Tienda Frescura     override  ↗ María González base        10%    $0.28
Tienda Frescura     override  ↗ María González phones      10%    $0.05
Tienda Frescura     override  ↗ María González lines       10%    $0.02
Tienda Frescura     override  ↗ María González overage     10%    $0.02
Tienda Frescura     override  ↗ María González one_time    10%    $14.00

SUBTOTAL RECURRING:                                                    $0.37
SUBTOTAL ONE-TIME:                                                     $0.00
SUBTOTAL OVERRIDE:                                                    $14.37
TOTAL:                                                                $14.37

Why first-touch? It incentivizes reps to bring in leads early in the sales cycle. The SDR who starts the conversation gets credit even if the AE closes the deal weeks later. The 70/30 split between María and Pablo explicitly recognizes both contributions, without disputes.

Watch out for double invitations. If Pablo also had a ref code and Tienda Frescura visited the landing first using Pablo's link, the cookie would have been set with pablo-ramirez. The form would send that ref code. María would have been left out of automatic attribution. That's why the admin can do a manual override via commissions.leads.setRep before the conversion.

Override doesn't duplicate the IC's commission. Carlos receives an additional $14.37 — Sopinf pays that extra amount, it's not deducted from María's earnings. Override is additional compensation from the MSP to the manager, not a split of the IC's commission.


SipSop documentation. Product operated by Sopinf Tech LLC.