Accelerate CMO · Referral Partner System

How Your Referral Partner System Works

Prepared for Melanie Harr-Hughes · July 2026 · by MapMatix

Phase 1, Workflow Flows & Screen Data Map

Flow 1, Partner recruitment & onboarding (recruit → signed → active)

flowchart TD
  classDef ghl fill:#e8f2f8,stroke:#258CBF,color:#12303f;
  classDef custom fill:#fff1e2,stroke:#F5821F,color:#12303f;
  classDef ext fill:#eef7f0,stroke:#327D7B,color:#12303f;
  classDef decision fill:#fdf6e3,stroke:#d9a400,color:#4a3b00;
  classDef actor fill:#eceff1,stroke:#607d8b,color:#12303f;

  A["Melanie recruits partner in GHL<br/>Referral Partnership Pipeline"]:::ghl
  B{"Card reaches<br/>'Made a Move'?"}:::decision
  A --> B
  B -->|not yet| A
  B -->|"yes (trigger)"| C["GHL workflow fires webhook to custom app"]:::ghl
  C --> D["Custom app creates partner record,<br/>pre-filled from GHL standard fields:<br/>name / email / phone / company / address"]:::custom
  D --> E["Send branded invitation email + personal link"]:::custom
  E --> F["Partner opens branded intake page,<br/>confirms details + adds mailing address"]:::actor
  F --> G["Review 10% terms → click to sign"]:::actor
  G --> H["SignWell opens in a NEW TAB to sign"]:::ext
  H --> I{"Signed?"}:::decision
  I -->|"no / abandoned"| I1["Reminder emails: day 2, day 7;<br/>day 8 escalation to Melanie.<br/>Melanie notified on each send.<br/>Partner stays 'agreement_sent'"]:::custom
  I1 --> F
  I -->|"yes → returns to app"| J["Create agreement record, store signed PDF,<br/>capture signer fields"]:::custom
  J --> K["Partner sets portal password"]:::actor
  K --> L["Prompt: complete Stripe Connect payout setup<br/>(bank details; Stripe collects W-9)"]:::ext
  L --> M{"Stripe onboarding<br/>complete now?"}:::decision
  M -->|yes| N["Mark payout setup complete;<br/>tag GHL 'Payout Setup Complete'"]:::custom
  M -->|"not now"| O["Portal shows persistent 'complete payout setup'<br/>banner; tag GHL 'Payout Setup Incomplete';<br/>payouts held until complete"]:::custom
  J --> P["Write back to GHL: tag 'Active Referral Partner',<br/>move card → 'Signed Referral Agreement';<br/>at activation the card moves on → 'Nurturing'"]:::ghl
  N --> Q["Welcome splash → partner portal · ACTIVE"]:::custom
  O --> Q
  P --> Q

Notes: trigger is entering "Made a Move" (manual jumps included). SignWell opens in a new tab and returns the partner to the app to set their password. Stripe payout setup can be deferred; if not done, the portal keeps a persistent prompt and GHL is tagged "Payout Setup Incomplete" until it's finished. Reminder cadence for an unsigned agreement: day 2, day 7, then day 8 escalation to Melanie, with Melanie notified each time a reminder goes out. Card moves are two-step (as built): signing moves the card to "Signed Referral Agreement"; creating the portal password moves it on to "Nurturing" (enrolls nurture).


Flow 2, Referral lifecycle (starts in GHL → linked to partner → conversion)

flowchart TD
  classDef ghl fill:#e8f2f8,stroke:#258CBF,color:#12303f;
  classDef custom fill:#fff1e2,stroke:#F5821F,color:#12303f;
  classDef decision fill:#fdf6e3,stroke:#d9a400,color:#4a3b00;
  classDef actor fill:#eceff1,stroke:#607d8b,color:#12303f;

  A["Partner emails an introduction<br/>with the prospect CC'd to Melanie"]:::actor
  A --> B["Lead created in GHL Sales Pipeline<br/>(Melanie runs her own sales here)"]:::ghl
  B --> B2["Melanie marks the lead's 'Referring Partner'<br/>field in GHL (= acknowledgment)"]:::ghl
  B2 --> C["GHL workflow syncs it: custom app records<br/>the referral · status: open, NO manual entry"]:::custom
  C --> D["Start 180-day window from acknowledgment -<br/>tracked in BOTH GHL and the custom app"]:::custom
  D --> E{"Deal closes in GHL?"}:::decision
  E -->|"won"| F{"Closed inside the<br/>180-day window?"}:::decision
  E -->|"lost / no close"| G["Referral stays open, then expires ·<br/>no payout"]:::custom
  F -->|yes| H["Referral → converted (eligible);<br/>close synced to custom app"]:::custom
  F -->|"no (outside window)"| I{"Melanie override?<br/>extend / waive"}:::decision
  I -->|"no (strict default)"| J["Referral ineligible · no payout"]:::custom
  I -->|yes| H
  H --> K["Qualify as Business Opportunity (Section 5)<br/>→ money flow (Flow 3)"]:::custom

Notes: the lead lives in GHL for Melanie's sales management, and the referral link is CRM-DRIVEN: Melanie sets a "Referring Partner" dropdown on the lead in GHL and a workflow syncs it into the custom app, there is NO manual referral entry in the admin screen. The custom app tracks referral status (open/closed/converted). The 180-day window is recorded in both systems and reconciled when the GHL deal closes (inside vs outside the window). Because GHL has no custom fields today, tracking the window + partner link in GHL means creating a few GHL custom fields (referring partner, acknowledged date, window expiry), a build task, flagged in open questions.


Flow 3, Money flow (client pays in QBO → commission → Stripe payout, recurring)

flowchart TD
  classDef ghl fill:#e8f2f8,stroke:#258CBF,color:#12303f;
  classDef custom fill:#fff1e2,stroke:#F5821F,color:#12303f;
  classDef ext fill:#eef7f0,stroke:#327D7B,color:#12303f;
  classDef qbo fill:#efe9f6,stroke:#7A5AA6,color:#2e2140;
  classDef decision fill:#fdf6e3,stroke:#d9a400,color:#4a3b00;
  classDef actor fill:#eceff1,stroke:#607d8b,color:#12303f;

  A["Client is invoiced and pays -<br/>billing runs in QuickBooks Online"]:::qbo
  A --> B{"Invoice marked paid in QBO?"}:::decision
  B -->|"paid (QBO webhook)"| C["QBO 'invoice paid' event →<br/>updates custom app + GHL"]:::qbo
  B -->|"check not yet entered"| D["Melanie records the check payment<br/>IN QBO, the only place payments<br/>are marked received"]:::qbo
  D --> C
  C --> E["Custom app: client_payment (received)<br/>+ commission = 10% of gross → payable"]:::custom
  E --> F{"Client refunded or cancelled<br/>within 60 days of start?"}:::decision
  F -->|yes| G["Clawback (negative entry),<br/>nets against next payout"]:::custom
  F -->|no| H["Commission sits in the payout queue"]:::custom
  G --> H
  H --> I{"Release payout?<br/>Melanie's schedule, within 60 days<br/>(or set auto-release)"}:::decision
  I -->|release| J["Stripe pays 10% to the partner's bank"]:::ext
  J --> K["Generate fee statement<br/>+ update the partner portal"]:::custom
  K --> L{"Another client payment?<br/>(renewal / next month)"}:::decision
  L -->|yes| A
  L -->|"client relationship ended"| M["Commissions stop accruing"]:::custom

Notes: the "payment received" trigger originates in QuickBooks Online (her billing system), which updates both the custom app (commission becomes payable) and GHL. Checks that QBO can't auto-detect are recorded by Melanie in QBO itself, that entry fires the same QBO event, so everything flows through one door. The admin screen has no manual "mark paid" control; QBO is the single source of truth for money in. Stripe still pays the partner out.


Flow 4, System sync (QuickBooks · GoHighLevel · custom app · Stripe) ← reworked

flowchart LR
  classDef ghl fill:#e8f2f8,stroke:#258CBF,color:#12303f;
  classDef custom fill:#fff1e2,stroke:#F5821F,color:#12303f;
  classDef ext fill:#eef7f0,stroke:#327D7B,color:#12303f;
  classDef qbo fill:#efe9f6,stroke:#7A5AA6,color:#2e2140;

  subgraph QBO["QuickBooks Online, client billing (money IN)"]
    Q1["Client invoice paid /<br/>payment received"]:::qbo
  end
  subgraph GHL["GoHighLevel, sales + partner ops"]
    G1["Referral Pipeline:<br/>'Made a Move'"]:::ghl
    G2["Sales Pipeline: lead + deal,<br/>180-day window,<br/>deal close (won/lost + date)"]:::ghl
    G3["Contact tags:<br/>Active Partner ·<br/>Payout Setup Incomplete/Complete ·<br/>card stage + nurture"]:::ghl
  end
  subgraph CUSTOM["Custom app, partner source of truth"]
    C1["Start partner onboarding"]:::custom
    C2["Referral ledger:<br/>attribution, 180-day window,<br/>commissions, payouts"]:::custom
  end
  subgraph STR["Stripe, partner payouts (money OUT)"]
    S1["Payout to partner's bank"]:::ext
  end

  G1 -->|webhook| C1
  Q1 -->|"invoice paid → commission payable"| C2
  Q1 -->|"mark paid on deal"| G2
  G2 -->|"deal closed + date (in/out of window)"| C2
  C2 -->|"partner signed/active · status ·<br/>payout-setup status"| G3
  C2 -->|"release payout"| S1
  G2 -. "planned (separate scope): client onboarding creates QBO customer + invoice" .-> Q1

Notes: four systems, minimal wires. QBO drives client-payment detection into both the custom app and GHL; GHL drives the pipeline trigger and syncs deal-close-vs-window back to custom; custom writes partner status/tags to GHL and releases payouts via Stripe. The dashed link (GHL → QBO client onboarding) is not in the current Phase 1 scope, see the scope note in open questions. The referral/commission/payout ledger is not mirrored anywhere; it lives only in the custom app.


Screen data map, what's collected, shown, and interactive

"Pre-filled" = from GHL standard contact fields; "Entered" = the partner types it; "Via SignWell/ Stripe/QBO" = collected inside that external step.

A. Intake form (partner-facing, one time, during onboarding)

Item How it's obtained Required When
First & last name Pre-filled from GHL, confirm/edit Yes On opening the intake link
Email (also the portal login) Pre-filled, confirm/edit Yes "
Phone Pre-filled, confirm/edit Yes "
Company name Pre-filled if in GHL, else entered Yes "
Full mailing address Entered Yes (contract) Intake step
Acknowledge the 10% terms Presented to read (not a field) Yes Before signing
Signature + signer fields (full name, company, address, phone, email, date) Captured in SignWell (opens in a new tab) Yes Signing step
Portal password Entered (or magic-link) Yes On return from SignWell
Payout account (bank + W-9/tax) Via Stripe Connect hosted onboarding (Stripe collects the tax form) Before first payout (can defer) End of onboarding, or later from the portal

B. Partner portal, presented (read-only)

Shown Source
Their referrals and the outcome of each referrals
Each referral's conversion status + 180-day window status/flags referrals
Lifetime earnings (total paid to date) payouts / commissions
Payout history, amount, date, status, fee statement payouts
Pending commissions (payable, not yet released) commissions
A copy of their signed agreement (PDF) agreements
Payout-setup status + persistent "complete Stripe setup" prompt if incomplete partners.stripe_onboarding_status

C. Partner portal, interactive (the partner can do)

Action Effect
Edit contact details (name, phone, company, address) Updates their partner record
Complete / manage Stripe payout setup (persistent CTA until done) Via Stripe Connect; flips payout-setup status + GHL tag
Change password Account security
(Open, not planned) Submit a new referral via a form Pending Melanie's call, see open questions

D. Admin screen (Melanie-facing), views & actions

Views Actions
All partners + status (referrals sync in from GHL, no manual entry) Mark deal closed won/lost; set client start date
Each partner's referrals, earnings paid, pending Override a referral's 180-day window (extend / waive)
Payout queue: payable + 60-day due dates Release payouts (single/batch) or set auto-release
Flags: window passed, clawbacks, negative balances Pause / end a partner
Per-partner ledger detail

Deliberately NOT here (Matt, 2026-07-17): no "mark payment received" action, payments (including checks) are recorded only in QBO, and the app picks them up from QBO's event. And no in-app "needs attention" notification feed, notifications go to Slack (next section); the admin screen keeps read-only flags for reference, but Slack is where Melanie gets told something needs her.


Notifications to Melanie (reminder events + more)

Notifications arrive in Slack. Every event that needs Melanie's attention posts to a Slack channel in her workspace, the same pattern Matt runs for MapMatix's own onboarding, proven and cheap to build (one webhook per event). No in-app "needs attention" feed; the admin screen keeps read-only flags, but Slack is the alerting channel. Events that notify: signing reminder sent (day 2 / day 7), day-8 escalation, Stripe payout setup still incomplete, an open invoice that may need a check recorded in QBO, a referral approaching/passing its 180-day window, a clawback recorded, a payout due inside the 60-day contract window. Each notification includes a link to the matching admin screen so it's actionable in one click.