StackTrading Docs

SRS: Stage 3 KYC & Live Onboarding — UC_5.5: Flows 3D–3G Contracts & Market Data Initiation

FieldValue
BA in Chargelinh.nguyen34
Date Created2026-08-07
Versionv2.3
Last Updated2026-08-22 — CHR tag standardization: STAGE3-037 → STAGE3-037 [CHR-46] (3 occurrences), CR-20260813-001 → [CHR-46] (3 occurrences).
Document ReferencesZapier Integration V7.pdf (Flow 3D lines 1177–1208; Flow 3E lines 1210–1227; Flow 3F lines 1229–1249; Flow 3G lines 1251–1262) · RFQ_ Stack Trading Prop Tech V7.pdf (§Contract Routing, §Market Data) · CR-20260720-001 (TradeSea replaces NinjaTrader — affects Flow 3H/UC_5.8, not this UC) · CR-20260720-004 (Freshdesk replaces Zendesk — not applicable to this UC)

UC Index

UC_IDUse Case NameBusiness Description
UC_5.5Flows 3D–3G — Contracts & Market Data InitiationWhen all three KYC/payout statuses are Approved, the aggregation gate fires. Flow 3D sends the correct Independent Contractor Agreement via Rippling (country-routed) and initiates the Market Data setup path for Futures traders. Flow 3E handles the Rippling contract-signed webhook and evaluates whether live provisioning (Flow 3H) can proceed. Flows 3F and 3G handle the Futures-only Market Data Setup form and optional premium payment.

Changelog

DateVersionUpdated itemBeforeAfterNotes
2026-08-07v1Initial creationCreated SRS for UC_5.5 (Flows 3D–3G)First authoring pass
2026-08-11v1.2§5 Flow 3E/3F/3G + §11 AC-5.5-06/08/10 — inter-flow trigger terminology"fire internal webhook to trigger Flow 3H" / "triggered in same Zap execution""dispatch internal Webhook to trigger Flow 3H in a separate process; source Zap terminates" — Flow 3E/3F/3G and Flow 3H are independent ZapsSTAGE3-029 confirmed 2026-08-11
2026-08-11v1.2§7 Exceptional Flow — NULL Billing_Country (new, GAP-03)Not presentConfirmed design gap: source does NOT define fallback when Billing_Country = NULL at Flow 3D routing branch. Added as GAP-03.STAGE3-028 confirmed 2026-08-11
2026-08-11v1.2§11 Acceptance Criteria (new section)Not presentAC-5.5-01 to AC-5.5-11 added — all confirmed ĐẠT by client 2026-08-11STAGE3-028 confirmed 2026-08-11
2026-08-12v1.3§7 Flow 3E stagnation — trader never signs ICA; BR_5.5.10 added[MISSING] — no reminder or expiry behavior definedICA validity = indefinite (no expiry on contract itself). Signing link TTL = 7 days; Rippling native or internal DB invalidation. Reminders: Day 3 + Day 7 (Rippling native or webhook-triggered). Day 7: contract_status → 'Expired'; trader re-initiates via Dashboard button. BR_5.5.10 added.QnA STAGE3-034 confirmed 2026-08-12
2026-08-12v1.4§1 3rd Party — removed Typeform/Zapier form assumption; §2 Trigger Flow 3F — webhook source changed from third-party form to internal frontend endpoint; §5 Flow 3D — "Level 1 Setup Form email" changed to login link email; §5 Flow 3F — rewritten as native dashboard screen with new internal Option A endpoint; §9 Wireframe — Level 1 Setup Form owned by Stack Trading frontend (not third-party)As documented in v1.3Level 1 Setup Form is hosted on Stack Trading frontend dashboard. Flow 3D email = login link. Flow 3F trigger = frontend call to new internal endpoint (Option A) or existing checkout (Option B). BR_5.5.6 updated.QnA STAGE3-042 confirmed 2026-08-12
2026-08-12v1.5§7 Flow 3F stagnation — [MISSING] replaced with confirmed cron logic; BR_5.5.11 added[MISSING] — no stagnation handling for setup_statusDaily backend cron scans setup_status = 'Pending' + contract_status = 'Signed'; fires reminder at D+3 and D+7; no Ops Slack escalation; 90-day stagnation_deadline from Flow 3E handles termination. BR_5.5.11 added.QnA STAGE3-043 confirmed 2026-08-12
2026-08-14v1.9§9 Wireframe — added re-entry trigger (load/refresh while setup_status=Pending); §10 Screen Description — full spec from screenshot (step pill, asset label, headline, 4 toggle cards, cost bar, lifecycle info box, Next CTA, on-click logic)§9 one-liner; §10 "N/A"Market Data selection screen fully documented. Step indicator = "Step 1". CME Level 2 ON by default (cannot be toggled off). CBOT/NYMEX/COMEX OFF by default. Cost bar dynamic. Lifecycle copy confirmed.Screenshot confirmed 2026-08-14.
2026-08-14v1.8§5 Flow 3F Option B — removed "payment link emailed to trader"; §3 3rd Party — removed "Option B payment link" from SES scope; §9 Wireframe — Option B payment widget on dashboard; AC-5.5-09 — correctedFlow 3F Option B: middleware "sends payment link to trader via email"Option B payment is completed entirely on the Stack Trading dashboard. Frontend calls Calculate Cart + Execute Checkout inline — no email sent. SES-26 (Market Data Payment Link) does not exist.Correction: STAGE3-042 applies to both options — all payment UI is native to the dashboard.
2026-08-12v1.7§5 Flow 3G Step 2 — market_data_flags writeOnly setup_status = 'Complete' and market_data_billable = True documentedNode.js middleware at Process Payment Webhook also parses addon_ids from gateway metadata and writes per-feed Active/Inactive flags to market_data_flags JSON column in Users table, in the same atomic DB transaction. GET /market-data-status reads these flags. BR_5.5.12 added.QnA STAGE3-047 confirmed 2026-08-12
2026-08-12v1.7§1 Overview / §6 Alt-1 added (dashboard lockout context)UC_5.1 not previously referenced hereAdded scope note: during Flows 3A–3E (all pending), dashboard is hard-locked. Only when contract is signed (Flow 3E complete) does the trader enter Flow 3F forced Market Data screen. Lockout BRs live in UC_5.1.md (BR_5.1.8/BR_5.1.9); referenced here for completeness.QnA STAGE3-048 confirmed 2026-08-12
2026-08-18v2.2§7 Flow 3E stagnation + BR_5.5.10 — Rippling native confirmedDay 3 reminder: "Rippling native or internal webhook-triggered"; Day 7: "If Rippling supports TTL / if not, PostgreSQL invalidation"; "Dev investigation required (STAGE3-034)" block presentRippling handles TTL + reminders natively — confirmed by client 2026-08-18. All conditional if/else implementation language removed. "Dev investigation required" note removed. Implementation: pass ttl=7 days at signature request; configure Day 3 in Rippling scheduler; no internal fallback.Client confirmed 2026-08-18
2026-08-18v2.1§2 Trigger Flow 3F — Returnee Trader Branch B trigger addedFlow 3F trigger: "Frontend call from Market Data selection screen (Futures traders only)"Added second trigger source: internal webhook from Flow 3A Step 0B (Branch B Returnee Trader — identity_status='Approved' AND dots_payee_id IS NOT NULL AND contract_status='Signed'). Bypasses Flows 3B/3C/3D/3E; payout_status='Approved' + setup_status='Pending' already set. Flow 3F onward identical for both paths.BR_5.1.11 / STAGE3-055/H-07 extended — 2026-08-18
2026-08-15v1.9 → v2.0§7 Flow 3D Rippling fail, §7 new Flow 3E webhook auth, §7 Flow 3G payment fail, §8 BR_5.5.13, §8 BR_5.5.14Flow 3D Rippling fail [MISSING]; Flow 3E webhook auth not documented; Flow 3G payment fail [MISSING]; market_data_billable reset on reactivation not documentedH-08: Rippling halt/freeze confirmed (no skip). H-09: Rippling dual-layer auth (Signed Webhook + IP Allowlist). M-13: payment fail → keep Pending_Payment, no rollback. BR_5.5.13: market_data_billable must reset True on reactivation. BR_5.5.14: Rippling webhook dual-layer auth.STAGE3-056/057/058/072 confirmed 2026-08-15
2026-08-12v1.6§3 Pre-conditions Flow 3D — Billing_Country replaced with kyc_country; §5 Flow 3D Step 2 — routing source field changed; §7 GAP-03 — closed (NULL country structurally impossible); BR_5.5.2 updated; AC-5.5-01/02 updatedFlow 3D evaluated Billing_Country from payment gatewayFlow 3D now evaluates kyc_country extracted from Veriff government ID and written to Users table at APPROVED. kyc_country is never NULL at Flow 3D time — if Veriff fails to extract country, KYC fails and aggregation gate never fires. Billing_Country removed from ICA routing logic entirely. GAP-03 permanently closed.QnA STAGE3-045 confirmed 2026-08-12
2026-08-10v1.1Q4: Payment processor webhook authentication confirmed — three-layer global security mandate documented; BR_5.5.8 (security layers) and BR_5.5.9 (integration patterns) added[MISSING] — assumption was Zapier filter onlyConfirmed: HMAC/JWS signature + IP allowlist + rate limiting; two integration patterns (Baseline Zapier Code Step vs Hardened WAF+Middleware)QnA STAGE3-016 confirmed 2026-08-10
2026-08-22v2.2 → v2.3All sections — CHR tag standardizationBare STAGE3 codes without CHR tags; date-based CR refsA37: CR-20260813-001 → [CHR-46] (3 occurrences). B11: STAGE3-037 → STAGE3-037 [CHR-46] (3 occurrences).CHR_Tag_Change_Plan_20260822_v4.md

Glossary

For all shared project terminology, refer to: Project Glossary.


UC_5.5 — Flows 3D–3G: Contracts & Market Data Initiation

1. Overview

FieldContent
IDUC_5.5
Use CaseFlows 3D–3G — Contracts & Market Data Initiation
DescriptionThis UC covers four sequential Zapier flows that bridge the KYC/payout approval stage and the live account provisioning stage. Flow 3D fires when the three-way aggregation gate is met (all statuses Approved). It country-routes the Independent Contractor Agreement (ICA) via Rippling and simultaneously initiates the Market Data setup path by sending a login link email to Futures traders. Flow 3E receives the Rippling contract-signed webhook, updates contract_status = 'Signed', sets stagnation_deadline, and evaluates whether Market Data Setup is already complete before triggering Flow 3H. Flow 3F handles the Futures-only Market Data selection screen (native Stack Trading dashboard — confirmed STAGE3-042): Option A (firm-paid standard) calls a new internal endpoint to set setup_status = 'Complete'; Option B (trader-paid premium) initiates the existing checkout flow. Flow 3G handles the payment confirmation for Option B, setting setup_status = 'Complete' and re-evaluating the gate to Flow 3H.
Zapier FlowsFlow 3D · Flow 3E · Flow 3F (Futures only) · Flow 3G (Futures Option B only)
Zapier TableUsers table (contract_status'Pending' / 'Signed' / 'Expired', setup_status, stagnation_deadline, is_professional, market_data_billable, kyc_country — written at Veriff APPROVED, used by Flow 3D ICA routing)
3rd PartyRippling (ICA e-signature) · Payment processor (Option B market data payment — active processor per ACTIVE_PAYMENT_PROCESSOR config) · AWS SES (emails — login link for Market Data Setup only)

Scope note — Forex traders: Forex traders skip Flows 3F and 3G entirely. Their setup_status is set to 'N/A' by Flow 3D. Flow 3E therefore gates on setup_status == 'N/A' (already satisfied) and proceeds directly to Flow 3H after contract signing.

Scope note — contract type: The WBS description references "US W-2 or Dots International contractor." Per source (zapier_v7_full.txt line 1190): "Tax forms are excluded from this Rippling flow as Dots handles W-8BEN/W-9." Rippling is used strictly for ICA e-signature, not for tax forms. All four ICA variants are Independent Contractor Agreements, not W-2 employment forms. There is no W-2 (employee tax form) in this flow.


2. Trigger

Flow 3D: Internal webhook fired by the aggregation gate in Flow 3B (UC_5.2) or Flow 3C (UC_5.4) — whichever sets the last of the three required status fields to 'Approved'. Flow 3B.2 (UC_5.3) deprecated (STAGE3-037 [CHR-46]/039 — [CHR-46]) — Flow 3B now covers all traders (Futures and Forex).

Flow 3E: Inbound webhook from Rippling confirming the trader has e-signed the Independent Contractor Agreement.

Flow 3F: Frontend call from the Market Data selection screen in the Stack Trading dashboard (Futures traders only). Option A: frontend calls a new internal endpoint to update setup_status and trigger Flow 3H. Option B: frontend calls Calculate Cart and Execute Checkout endpoints; Flow 3G handles the subsequent payment confirmation webhook. (Confirmed STAGE3-042: not a third-party form webhook.)

Returnee Trader (Branch B) trigger (BR_5.1.11 / 2026-08-18): For Returnee Traders, Flow 3F is also triggered by an internal webhook from Flow 3A Step 0B — the Branch B execution block that bypasses Flows 3B/3C/3D/3E entirely and routes directly here. The payout_status = 'Approved' and setup_status = 'Pending' are already set by Flow 3A middleware before this trigger fires. From Flow 3F onward, the Returnee path is identical to the New Trader path: trader selects market data (Option A or B) and Flow 3H provisions the new account.

Flow 3G: Inbound webhook from payment processor confirming payment_success for the Option B premium market data upgrade (Futures Option B traders only).


3. Pre-conditions

Flow 3D:

  • identity_status = 'Approved' AND institution_approval_status = 'Approved' AND payout_status = 'Approved' for user_id.
  • Internal aggregation gate webhook received.

🔄 CR — STAGE3-045: ICA routing now uses kyc_country (from Veriff government ID) instead of Billing_Country. kyc_country is written to Users table at Veriff APPROVED and guaranteed non-NULL at Flow 3D trigger time.

  • kyc_country IS NOT NULL in Users table — guaranteed by the Veriff APPROVED gate: if Veriff cannot extract a country from the government ID, KYC fails and Flow 3D never triggers. (Confirmed STAGE3-045 — replaces Billing_Country as the ICA routing source field.)

Flow 3E:

  • Flow 3D has executed: Rippling ICA e-signature request sent; contract_status = 'Pending'.
  • Trader has received the Rippling contract email and completed the e-signature.
  • Rippling has fired the signed-confirmation webhook.

Flow 3F:

  • Asset_Class = 'Futures' for the trader.
  • Flow 3D has sent the Market Data Setup login link email; setup_status = 'Pending'.
  • Trader has logged in to dashboard and is presented with the Market Data selection screen.

Flow 3G:

  • Flow 3F Option B path was triggered: trader selected premium add-ons; checkout initiated on dashboard.
  • setup_status = 'Pending_Payment'.
  • Payment processor has confirmed payment_success and fired the webhook.

4. Post-conditions

Flow 3D:

  • Rippling ICA e-signature request sent to trader (one of four country-routed agreements).
  • contract_status = 'Pending' in Users table.
  • Futures traders: setup_status = 'Pending'; "Action Required: Complete Market Data Setup" login link email sent to trader.
  • Forex traders: setup_status = 'N/A'.
  • Zap terminates.

Flow 3E — contract signed:

  • contract_status = 'Signed' in Users table.
  • stagnation_deadline = Today + 90 days set.
  • is_professional = True set.
  • Gate evaluated: if setup_status == 'Complete' OR setup_status == 'N/A' → Flow 3H triggered.
  • Else: Zap terminates, waits for Market Data Setup.

Flow 3F — Option A (firm-paid):

  • setup_status = 'Complete' and market_data_billable = False.
  • Gate evaluated: if contract_status == 'Signed' → Flow 3H triggered. Else: Zap terminates.

Flow 3F — Option B (trader-paid):

  • Trader completes checkout on the dashboard (no payment link emailed).
  • setup_status = 'Pending_Payment'.
  • Zap terminates.

Flow 3G — payment confirmed:

  • setup_status = 'Complete' and market_data_billable = True.
  • Gate evaluated: if contract_status == 'Signed' → Flow 3H triggered. Else: Zap terminates.

5. Basic Flow

Flow 3D — Contract Execution & Market Data Initiation

  1. Internal webhook received: identity_status, institution_approval_status, payout_status all 'Approved' for user_id.
  2. Zapier evaluates kyc_country (verified country from Veriff government ID — confirmed STAGE3-045; replaces Billing_Country) to route the correct ICA via Rippling API:
    • kyc_country = 'US' → US Contract
    • kyc_country = 'GB' or EU member state → UK/EU Contract
    • kyc_country IN ('CA', 'AU', 'NZ') → Common Law Contract
    • All other countries → Rest of World Contract
  3. Rippling API call sends the selected ICA for e-signature to the trader.
  4. UPDATE Users table: contract_status = 'Pending'.
  5. Market Data branching by Asset_Class:
    • IF Asset_Class == 'Futures': send "Action Required: Complete Market Data Setup" email to trader (contains login link to dashboard — no form link); UPDATE setup_status = 'Pending'.
    • IF Asset_Class == 'Forex': UPDATE setup_status = 'N/A'.
  6. Zap terminates.

Flow 3E — Contract Execution Handler

  1. Rippling webhook received: contract signed, containing user_id.
  2. UPDATE Users table:
    • contract_status = 'Signed'
    • stagnation_deadline = Today + 90 days
    • is_professional = True
  3. Aggregation gate check: query setup_status for user_id:
    • IF setup_status == 'Complete' OR setup_status == 'N/A' → dispatch internal Webhook to trigger Flow 3H (UC_5.8); Flow 3E Zap terminates.
    • ELSE → Zap terminates; waits for Market Data Setup (Flows 3F or 3G).

Flow 3F — Market Data Setup Handler (Futures only)

Platform confirmed (STAGE3-042 2026-08-12): The Market Data selection screen is hosted natively on the Stack Trading frontend dashboard. This is NOT a standalone form hosted on Typeform or Zapier. When the trader logs in after receiving the Flow 3D email, the dashboard forces them to the Market Data selection screen.

  1. Trader logs into dashboard; dashboard forces navigation to Market Data selection screen.
  2. Trader selects market data option:
    • Option A — Standard (firm-paid, includes 1 Level 2 CME Feed):
      • Frontend calls new internal endpoint: POST /market-data/setup-complete (or equivalent) with user_id, option = 'A'.
      • Backend: UPDATE Users table: setup_status = 'Complete', market_data_billable = False.
      • Backend: dispatch internal webhook to trigger Flow 3H (UC_5.8); Flow 3F process terminates.
      • Gate check: if contract_status != 'Signed' → dispatch to Flow 3H is deferred; Zap terminates and waits for contract.
    • Option B — Premium add-ons (trader-paid, beyond firm-covered feed):
      • Frontend calls POST /calculate-cart then POST /execute-checkout with product_id = 'LIVE_DATA_UPGRADE', addon_ids = [selection] — all on the dashboard (no payment link emailed).
      • Middleware checks ACTIVE_PAYMENT_PROCESSOR; payment flow completes within the dashboard session.
      • UPDATE Users table: setup_status = 'Pending_Payment'.
      • Zap/process terminates; awaits payment confirmation via Flow 3G.

Flow 3G — Market Data Payment Handler (Futures Option B only)

  1. Webhook received from payment processor: payment_success, containing user_id, product_id, addon_ids.
  2. Node.js Middleware (Process Payment Webhook) performs an atomic DB transaction (STAGE3-047 2026-08-12):
    • Parse addon_ids from gateway payment metadata.
    • Write per-feed flags to market_data_flags JSON column in Users table (one flag per exchange/feed in addon_ids — e.g., NYMEX: Active, CBOT: Active).
    • SET setup_status = 'Complete'
    • SET market_data_billable = True
    • All three writes are atomic — partial write must not occur.

    Why: GET /market-data-status reads market_data_flags to render the Active/Inactive status per feed on the dashboard. If market_data_flags is not written here, the feed status display will show incorrect state regardless of payment confirmation. (Source: STAGE3-047 confirmed 2026-08-12)

  3. Gate check: if contract_status == 'Signed' → dispatch internal Webhook to trigger Flow 3H (UC_5.8); Flow 3G Zap terminates. ELSE: Zap terminates, waits for contract.

6. Alternative Flow

  • [Flow 3E — setup_status already Complete or N/A at time of contract signing]

    • Forex trader or Futures Option A trader already completed Market Data Setup before signing.
    • Aggregation gate immediately satisfied → Flow 3H triggered in the same Zap execution.
  • [Flow 3E — contract signed before Market Data Setup complete (Futures)]

    • setup_status = 'Pending' or 'Pending_Payment' when contract signed.
    • Flow 3E terminates; gate re-evaluated by Flow 3F or 3G when Market Data Setup completes.
  • [Flow 3F — trader selects Option B (premium add-ons)]

    • Follows the Option B path in §5 Flow 3F. Zap terminates; waits for payment confirmation via Flow 3G.
  • [Flow 3G — contract already signed when payment confirmed]

    • contract_status = 'Signed' at time of payment confirmation → Flow 3H triggered immediately in Flow 3G.

7. Exceptional Flow

  • [Flow 3D — Rippling API call fails (H-08/STAGE3-056)]

    Confirmed — HALT/FREEZE. If the Rippling API returns non-200 or times out at Flow 3D Step 3:

    • Do NOT skip. contract_status stays 'Pending' (or NULL if not yet written).
    • Fire Slack alert (urgent) to Ops channel for manual vendor issue resolution.
    • Trader cannot proceed to live trading without signing ICA. No bypass allowed. (Source: STAGE3-056 / H-08 confirmed 2026-08-15)
  • [Flow 3D — trader's country not matched by any routing rule]

    • Source defines four routing rules: US, GB/EU, CA/AU/NZ, Rest of World. "Rest of World" is a catch-all, so technically all countries are covered. However, the EU member state list is not explicitly enumerated in the source — it is assumed to be the standard ISO EU member list.
    • [MISSING] — is there an explicit allowlist of EU member states, or does the system rely on a country-code lookup table?
  • [Flow 3D — Billing_Country is NULL (GAP-03)] (Confirmed design gap — STAGE3-028 2026-08-11) ⛔ GAP-03 CLOSED — STAGE3-045 2026-08-12. Flow 3D no longer evaluates Billing_Country. ICA routing now uses kyc_country — the country extracted from the trader's government ID by the Veriff payload and written to the Users table at identity_status = 'Approved' (UC_5.2 Step 3 / BR_5.2.10). NULL is structurally impossible: If Veriff cannot extract a country from the government ID document, the trader fails KYC (identity_status stays 'Pending'), the aggregation gate never fires, and Flow 3D is never triggered. No fallback or default routing logic is needed. Legal liability note: Client explicitly rejected defaulting to "Rest of World" for unknown country (Billing_Country-based Options 1–3 were rejected). Using verified KYC country eliminates the legal risk entirely.

  • [Flow 3E — Rippling webhook received but user_id not found in Users table]

    • [MISSING] — no handling documented for orphaned Rippling webhooks.
  • [Flow 3E — contract_status already 'Signed' (duplicate webhook)]

    • If Rippling re-delivers the webhook, the DB UPDATE re-sets the same values (idempotent for contract_status and is_professional). stagnation_deadline = Today + 90 days would be re-calculated from the re-delivery date — potentially extending the deadline unintentionally.
    • [MISSING] — is there an idempotency guard to prevent stagnation_deadline from being reset on duplicate webhook delivery?
  • [Flow 3E — trader never signs the contract (stagnation)] (Confirmed — STAGE3-034 2026-08-12; Rippling native confirmed by client 2026-08-18)

    • ICA validity period: The ICA document itself is valid indefinitely — there is no annual renewal or expiration date on the contract.
    • Signing link TTL (7 days): The Rippling-generated signing link expires after 7 days. Rippling handles this natively — pass TTL at signature request generation; no internal PostgreSQL invalidation required.
    • Automated reminders:
      • Day 3: Rippling native automated reminder sent to trader.
      • Day 7: Rippling native expiry fires. UPDATE Users table: contract_status = 'Pending' → 'Expired'. Trader required to click a button on Dashboard to generate a fresh Rippling signature request and restart the signing process.
    • No dev investigation required. Rippling natively handles both TTL enforcement (Day 7 expiry) and automated reminder scheduling (Day 3). No internal fallback webhook or PostgreSQL-level invalidation needed. (Client confirmed 2026-08-18.)
  • [Flow 3F — Market Data selection never completed (stagnation)] (Confirmed — STAGE3-043 2026-08-12)

    • Automated reminders via backend cron: A daily cron job scans for users where setup_status = 'Pending' AND contract_status = 'Signed'. Reminder emails fire at:
      • Day 3: Standard reminder email sent to trader.
      • Day 7: Second reminder email sent to trader.
    • No Ops Slack escalation. Operations team does not chase traders who fail to complete Market Data setup.
    • No new automated closure process. Flow 3E already sets stagnation_deadline = Today + 90 days at contract signing. If the trader never sets up market data, they sit dormant until the Flow 19 Stagnation Monitor sweeps them up at the 90-day mark and terminates the account automatically.
    • See BR_5.5.11.
  • [Flow 3E — Rippling inbound webhook authentication (H-09/STAGE3-057)]

    Confirmed — dual-layer auth required. Middleware Hub MUST validate inbound Rippling signed webhooks using both:

    1. Signed Webhook Verification — verify Rippling's cryptographic signature in the webhook header.
    2. IP Allowlisting — only accept requests from Rippling's published IP range. Both layers are mandatory and simultaneous. Invalid signature or unlisted IP → reject + log security event. (Source: STAGE3-057 / H-09 confirmed 2026-08-15)
  • [Flow 3F/3G — payment fails or is declined (H-13/STAGE3-072)]

    setup_status stays 'Pending_Payment'. Trader receives error from payment gateway directly on dashboard UI. Trader clicks the payment button again — no new link generation needed. (Source: STAGE3-072 / M-13 confirmed 2026-08-15)

  • [Flow 3F/3G — Option B checkout initiated but Rippling contract already signed before payment]

    • Covered in Alternative Flow (§6) — Flow 3G triggers Flow 3H immediately when payment is confirmed.
    • No exception; standard path.

8. Business Rules

BR_5.5.1: Aggregation Gate Trigger — All Three Statuses Required

Flow 3D fires only when ALL three of the following are simultaneously 'Approved' for the same user_id:

FieldSet by
identity_statusFlow 3B (Veriff, Forex) or Flow 3B.2 (Ironbeam, Futures) Flow 3B (Veriff) — ALL traders (STAGE3-037 [CHR-46] / [CHR-46])
institution_approval_statusFlow 3B (Veriff, Forex) or Flow 3B.2 (Ironbeam, Futures) Flow 3B (Veriff) — ALL traders, set simultaneously with identity_status (STAGE3-037 [CHR-46] / [CHR-46])
payout_statusFlow 3C (Dots)

The gate is checked by whichever of the three upstream flows fires last. This UC is the downstream target — it does not re-check the gate itself.

(Source: Zapier Integration V7.pdf Flow 3D lines 1179–1181)

🔄 CR — STAGE3-045: ICA routing source changed from Billing_Country to kyc_country. Four ICA variants now routed on verified government ID country. Billing_Country removed from routing logic. GAP-03 permanently closed.

BR_5.5.2: ICA Country Routing — Four Variants via Rippling, routed on kyc_country (STAGE3-045)

Rippling sends one of four Independent Contractor Agreements based on kyc_country (the country extracted from the trader's Veriff government ID document — written to Users table at Veriff APPROVED per BR_5.2.10).

Billing_Country is NOT used for ICA routing. It cannot be relied on for legal jurisdiction determination (confirmed STAGE3-045 2026-08-12 — legal liability concern).

kyc_country valueContract Type
'US'US Contract
'GB' or EU member stateUK/EU Contract
'CA', 'AU', 'NZ'Common Law Contract
All other countriesRest of World Contract

kyc_country is guaranteed non-NULL at Flow 3D trigger time: if Veriff fails to extract a country from the government ID, the trader fails KYC and the aggregation gate never fires. No NULL fallback logic is required. (This permanently closes GAP-03.)

Tax forms (W-9, W-8BEN) are excluded from Rippling. Dots handles all tax form collection (UC_5.4).

(Source: Zapier Integration V7.pdf Flow 3D lines 1184–1190; QnA STAGE3-045 confirmed 2026-08-12)

BR_5.5.3: Stagnation Deadline Set at Contract Signing

stagnation_deadline = Today + 90 days is set when the trader signs the ICA (Flow 3E). This is the deadline by which the trader must complete live trading milestones before the account is flagged for stagnation review. The clock does not start until the ICA is signed — not when it is sent.

(Source: Zapier Integration V7.pdf Flow 3E lines 1217–1218)

BR_5.5.4: is_professional = True Set at Contract Signing

is_professional = True is set in the same DB write as contract_status = 'Signed'. This flag affects market data entitlement levels in Flow 3H (professional vs. non-professional data fees).

(Source: Zapier Integration V7.pdf Flow 3E line 1219)

BR_5.5.5: Forex Traders Skip Market Data Setup

For Forex traders, setup_status = 'N/A' is set by Flow 3D. Flow 3E's aggregation gate treats 'N/A' as equivalent to 'Complete' for triggering Flow 3H. Flows 3F and 3G are never executed for Forex traders.

(Source: Zapier Integration V7.pdf Flow 3D lines 1202–1205; Flow 3E lines 1223–1224)

BR_5.5.6: Market Data — Two-Tier Model for Futures Traders (Native Dashboard — STAGE3-042)

The Market Data selection is performed natively on the Stack Trading frontend dashboard (not via a Typeform or Zapier form). The dashboard forces the trader to the Market Data selection screen upon login while setup_status = 'Pending'.

Futures traders select their market data tier:

  • Option A (Standard — firm-paid): 1 Level 2 CME Feed included. Frontend calls a new internal endpoint to set setup_status = 'Complete' and market_data_billable = False. Backend then triggers the internal webhook to Flow 3H.
  • Option B (Premium — trader-paid): Additional data feeds beyond the firm-covered standard. Frontend calls Calculate Cart and Execute Checkout endpoints. Payment processor is determined dynamically from ACTIVE_PAYMENT_PROCESSOR configuration. market_data_billable = True upon payment confirmation (Flow 3G).

The Flow 3D email for Futures traders contains a standard dashboard login link (subject: "Action Required: Complete Market Data Setup") — not a direct form link.

(Source: Zapier Integration V7.pdf Flow 3F lines 1235–1249; QnA STAGE3-042 confirmed 2026-08-12)

BR_5.5.7: Dual Aggregation Gates — Contract and Market Data Must Both Complete

Flow 3H can only be triggered when BOTH of the following are true simultaneously:

  • contract_status = 'Signed' (set by Flow 3E)
  • setup_status IN ('Complete', 'N/A') (set by Flow 3D for Forex, Flow 3F for Futures Option A, Flow 3G for Futures Option B)

Both Flow 3E and Flow 3F/3G independently evaluate this two-field gate. Whichever completes last triggers Flow 3H.

(Source: Zapier Integration V7.pdf Flow 3E lines 1223–1227; Flow 3F lines 1238–1239; Flow 3G lines 1260–1262)


BR_5.5.8: Global Webhook Security Mandate — Three Layers Apply to All Payment Webhooks

All inbound webhooks from external payment providers (NMI, Triple-A, Nomupay, EBANX, Dusupay, Skrill) are subject to a mandatory three-layer security control before any processing occurs:

LayerControlDescription
1Signed Webhook Verification (HMAC/JWS)Webhook receiver MUST verify the cryptographic hash of the payload against the stored gateway secret. Delivered via provider_signature header/parameter on POST /provisioning/live-trader (Process Payment Webhook).
2IP AllowlistingSystem MUST explicitly whitelist inbound IP ranges for each payment gateway. Requests from non-whitelisted IPs are rejected before payload inspection.
3Layer-7 Rate LimitingEnforced on all webhook catcher endpoints to prevent bot or brute-force traffic from exhausting automated task quotas or compute resources.

The Process Payment Webhook endpoint (POST — ingests NMI/T365/etc. webhook) requires:

  • provider_signature — cryptographic hash to validate against gateway secret.
  • Payload with custom metadata: addon_ids, product_id, user_id — ensures transaction consistency and correct routing.

(Source: QnA STAGE3-016 confirmed 2026-08-10; RFQ_ Stack Trading Prop Tech V7.pdf §Process Payment Webhook lines 1335–1373)

BR_5.5.9: Two Integration Patterns — How Signature Verification Executes

The physical execution of the signature check depends on the deployed integration pattern:

Option A — Baseline (Direct to Zapier):

  • Payment provider webhook routes directly to a Zapier Catch Hook.
  • Signature verification is executed via a Zapier Code Step (Python or JavaScript) or a synchronous API call back to the Middleware Hub for validation.
  • Lower infrastructure overhead; requires Zapier Code step to be correctly maintained per gateway.

Option B — Hardened (Direct to Middleware, recommended):

  • Webhook is sent directly to an internet-facing endpoint on the Middleware Hub behind a Web Application Firewall (WAF).
  • Middleware Hub handles: cryptographic signature check → IP allowlist verification → payload normalisation → DB write-back → push of a clean, normalised event to Zapier.
  • Zapier receives only the validated, normalised event — never the raw payment webhook.
  • Higher security posture; WAF provides additional Layer-7 protection and shields Zapier from raw provider payload format changes.

Which pattern is deployed is an infrastructure/implementation decision. Both must satisfy all three controls in BR_5.5.8.

(Source: QnA STAGE3-016 confirmed 2026-08-10)


🔄 CR — STAGE3-034: ICA signing link TTL = 7 days. contract_status = 'Expired' state added. Day 3 reminder + Day 7 expiry with dashboard re-initiation button. Client confirmed 2026-08-18: Rippling handles both natively — no internal fallback needed.

The Rippling-generated ICA signing link has a 7-day Time-To-Live (TTL). Rippling handles TTL enforcement and reminder scheduling natively — no internal PostgreSQL invalidation or webhook fallback is needed. (Client confirmed 2026-08-18.)

PhaseBehavior
Contract itselfValid indefinitely — no renewal or expiry date on the ICA document
Day 3Rippling native automated reminder sent to trader
Day 7Rippling natively expires the signing link. contract_status transitions from 'Pending''Expired'. Trader must click a Dashboard button to generate a fresh Rippling signature request and restart the signing process.

Implementation: Pass TTL parameter (ttl = 7 days) at Rippling signature request generation. Configure Day 3 reminder in Rippling scheduler. No internal cron or webhook required for this flow.

(Source: QnA STAGE3-034 confirmed 2026-08-12; Rippling native confirmed by client 2026-08-18)


BR_5.5.11: Market Data Setup Stagnation — Cron Reminders at D+3 and D+7

If a Futures trader does not complete the Market Data selection screen after receiving the Flow 3D login link email, setup_status remains 'Pending' indefinitely. The following stagnation handling applies:

DayAction
Day 3Backend daily cron fires a webhook to dispatch a standard reminder email to the trader
Day 7Backend daily cron fires a second reminder email
Day 90stagnation_deadline (set by Flow 3E at contract signing) expires — Flow 19 Stagnation Monitor sweeps the account and terminates it

Cron query: Scan for users where setup_status = 'Pending' AND contract_status = 'Signed'.

No Ops Slack escalation. Operations does not manually intervene for traders who fail to complete Market Data setup.

No new automated closure process. The existing 90-day stagnation_deadline from Flow 3E handles termination — no separate closure path is required.

(Source: QnA STAGE3-043 confirmed 2026-08-12)


BR_5.5.12: market_data_flags must be written atomically by middleware at payment confirmation (STAGE3-047 2026-08-12)

When Flow 3G (Process Payment Webhook) processes a successful payment with product_id = 'LIVE_DATA_UPGRADE' (or 'MARKET_DATA'), the Node.js middleware MUST parse addon_ids from the gateway payload metadata and write the per-feed Active flags to the market_data_flags JSON column in the Users table in the same atomic DB transaction as setup_status = 'Complete' and market_data_billable = True.

Zapier does not write market_data_flags. This write is handled entirely by the Node.js middleware at the Process Payment Webhook endpoint.

Downstream dependency: GET /market-data-status reads market_data_flags to render the Active/Inactive status for each subscribed exchange feed (NYMEX, CBOT, COMEX, etc.) in the dashboard. If market_data_flags is not written, the dashboard feed status display will be incorrect regardless of payment status.

(Source: QnA STAGE3-047 confirmed 2026-08-12)


BR_5.5.13: market_data_billable MUST be reset to True on reactivation (H-10/STAGE3-058 2026-08-15)

When a trader is reactivated after a Zombie/Inactive Hold (Flow 19 stagnation sweep), the backend MUST:

  1. Re-enable market data feeds (re-activate the exchange data subscription).
  2. Set market_data_billable = True in the Users table.

Both steps are mandatory and must occur together. Setting feeds active without resetting market_data_billable = True would result in the trader receiving live market data without being billed in the next EOM billing cycle (Flow 22), causing revenue leakage.

(Source: STAGE3-058 / H-10 confirmed 2026-08-15)


BR_5.5.14: Rippling inbound webhook MUST use dual-layer authentication (H-09/STAGE3-057 2026-08-15)

Inbound webhooks from Rippling (Flow 3E — contract signed confirmation) require both authentication layers simultaneously:

  1. Signed Webhook Verification — validate Rippling's cryptographic signature embedded in the webhook request header.
  2. IP Allowlisting — only accept requests originating from Rippling's published IP address range.

Both layers are mandatory. A request that passes only one layer MUST be rejected. Invalid → HTTP 400, security event logged.

Rationale: a spoofed Rippling webhook could falsely set contract_status = 'Signed' and trigger live account provisioning (Flow 3H) without a genuine signed ICA — a critical compliance and legal risk.

(Source: STAGE3-057 / H-09 confirmed 2026-08-15)


The only Stack Trading-owned UI screen in this UC is the Market Data selection screen (Flow 3F):

  • Market Data selection screen (Stack Trading dashboard — confirmed STAGE3-042 2026-08-12): Displayed when the trader logs in after receiving the Flow 3D login link email, OR when trader loads/refreshes the dashboard while setup_status = 'Pending'. The dashboard forces navigation to this screen — trader cannot navigate away. Trader selects Option A (standard, firm-paid CME feed) or Option B (premium add-ons, trader-paid). Frontend-owned screen — owned by Agency B (Stack Trading frontend).

Other trader-facing touchpoints in this UC are:

  • Rippling-hosted ICA e-signature page (Rippling UI — not owned by Stack Trading)
  • "Action Required: Complete Market Data Setup" login link email sent in Flow 3D (AWS SES — no embedded form link)
  • Option B payment widget embedded in dashboard Market Data selection screen (no email payment link)

10. Screen Description and Business Rules

Market Data Selection Screen (Flow 3F — Futures only, confirmed from screenshot 2026-08-14):

Entry condition: setup_status = 'Pending' AND contract_status = 'Signed' AND asset_class = 'Futures'. Dashboard forces this screen on login or page refresh — no sidebar or settings access until setup_status transitions out of 'Pending'.

Step indicator: "Step 1" pill at top of screen. Progress bar shows 1 of 3 segments filled (this is the first step of the live account setup flow presented to the trader after contract signing).

Asset class label: "Futures" displayed below the step pill.

Headline: "Market Data" — display typography, "Data" in a distinct gold/italic style.

Exchange toggle cards (4 cards in a row):

CardDefault stateBadgeDescription
CME Level 2ON (gold toggle)"Most Popular" badge (top-right corner)Firm-paid — 1 Level 2 CME feed. Included for all Futures traders at no cost.
CBOTOFF (grey toggle)Trader-paid premium add-on
NYMEXOFF (grey toggle)Trader-paid premium add-on
COMEXOFF (grey toggle)Trader-paid premium add-on
  • CME Level 2 toggle is ON by default and cannot be turned off — it is the firm-covered mandatory feed.
  • CBOT, NYMEX, COMEX toggles are OFF by default. Trader can toggle any combination to add premium feeds (Option B).
  • Enabling any premium toggle transitions from Option A to Option B.

Cost summary bar:

StateDisplay
No premium add-ons selected (Option A)Cost: $0.00
One or more premium add-ons enabled (Option B)Cost: $[calculated amount] — updates dynamically as toggles change

Market Data Lifecycle info box:

Static informational section displayed below the cost bar. Confirmed copy from screenshot:

  • Associate Track Evaluation: The Firm pays 100% of data costs.
  • Level 1 and 2: The Trader pays (Standard Exchange Professional Data rates apply).
  • Level 3: The Trader is fully reimbursed for Level 1 and 2 market data costs incurred.
  • Level 3 to Level 24: The Firm pays 100% of data costs.

CTA: "Next" button — gold/amber pill button, bottom-right corner. Enabled once a selection is made (CME Level 2 ON by default, so "Next" is always enabled from initial load).

On "Next" click:

  • Option A (only CME Level 2 ON): Frontend calls internal endpoint → setup_status = 'Complete', market_data_billable = False. If contract_status = 'Signed' → internal webhook to Flow 3H.
  • Option B (any premium add-on ON): Frontend calls POST /calculate-cart + POST /execute-checkout with selected addon_ids → payment flow on dashboard → setup_status = 'Pending_Payment'.

(Source: screenshot confirmed 2026-08-14; STAGE3-042 confirmed 2026-08-12; STAGE3-030 confirmed 2026-08-11)


11. Acceptance Criteria

(All ACs confirmed ĐẠT / CHÍNH XÁC by client 2026-08-11 — Source: STAGE3-028)

AC IDFlowScenarioExpected Result
AC-5.5-01Flow 3DThree-way aggregation gate fires; kyc_country = 'US' (formerly Billing_Country = 'US' — STAGE3-045)Rippling API sends US ICA; contract_status = 'Pending'; Futures: setup_status = 'Pending' + Market Data Setup login link email sent; Forex: setup_status = 'N/A'
AC-5.5-02Flow 3DAll four ICA routing rules evaluated on kyc_country (STAGE3-045)kyc_country = 'US' → US Contract; kyc_country = 'GB' or EU member state → UK/EU Contract; kyc_country IN ('CA','AU','NZ') → Common Law Contract; all other countries → Rest of World Contract
AC-5.5-03Flow 3DAsset_Class = 'Forex'setup_status = 'N/A'; no Level 1 Setup Form email sent
AC-5.5-04Flow 3DAsset_Class = 'Futures'setup_status = 'Pending'; Level 1 Setup Form emailed to trader to collect CME data subscription before account provisioning
AC-5.5-05Flow 3ERippling signed webhook receivedSingle atomic DB write: contract_status = 'Signed', stagnation_deadline = Today + 90 days, is_professional = True
AC-5.5-06Flow 3EContract signed; setup_status already 'Complete' (Option A) or 'N/A' (Forex)Aggregation gate satisfied → internal Webhook dispatched to trigger Flow 3H in a separate process; Flow 3E Zap terminates
AC-5.5-07Flow 3EContract signed; setup_status = 'Pending' (Futures, form not yet submitted)Flow 3E Zap terminates; waits for trader to complete market data setup; Flow 3H webhook NOT dispatched
AC-5.5-08Flow 3Faddon_ids count = 1 (CME only — Option A)setup_status = 'Complete', market_data_billable = False; if contract_status = 'Signed' → internal Webhook dispatched to trigger Flow 3H in separate process; Flow 3F Zap terminates
AC-5.5-09Flow 3Faddon_ids count > 1 (premium add-ons — Option B)POST /calculate-cart + POST /execute-checkout called on dashboard; setup_status = 'Pending_Payment'; Zap terminates; Flow 3H webhook NOT dispatched
AC-5.5-10Flow 3Gpayment_success webhook receivedsetup_status = 'Complete', market_data_billable = True; if contract_status = 'Signed' → internal Webhook dispatched to trigger Flow 3H in separate process; Flow 3G Zap terminates
AC-5.5-11Flow 3DRippling ICA signed via Flow 3EICA contains NO W-9 or W-8BEN forms; tax forms collected separately by Dots in UC_5.4 (KYC/Payout flow)

END OF UC_5.5

On this page

UC IndexChangelogGlossaryUC_5.5 — Flows 3D–3G: Contracts & Market Data Initiation1. Overview2. Trigger3. Pre-conditions4. Post-conditions5. Basic FlowFlow 3D — Contract Execution & Market Data InitiationFlow 3E — Contract Execution HandlerFlow 3F — Market Data Setup Handler (Futures only)Flow 3G — Market Data Payment Handler (Futures Option B only)6. Alternative Flow7. Exceptional Flow8. Business RulesBR_5.5.1: Aggregation Gate Trigger — All Three Statuses RequiredBR_5.5.2: ICA Country Routing — Four Variants via Rippling, routed on kyc_country (STAGE3-045)BR_5.5.3: Stagnation Deadline Set at Contract SigningBR_5.5.4: is_professional = True Set at Contract SigningBR_5.5.5: Forex Traders Skip Market Data SetupBR_5.5.6: Market Data — Two-Tier Model for Futures Traders (Native Dashboard — STAGE3-042)BR_5.5.7: Dual Aggregation Gates — Contract and Market Data Must Both CompleteBR_5.5.8: Global Webhook Security Mandate — Three Layers Apply to All Payment WebhooksBR_5.5.9: Two Integration Patterns — How Signature Verification ExecutesBR_5.5.10: ICA Signing Link TTL — 7-Day Expiry and contract_status = 'Expired' TransitionBR_5.5.11: Market Data Setup Stagnation — Cron Reminders at D+3 and D+7BR_5.5.12: market_data_flags must be written atomically by middleware at payment confirmation (STAGE3-047 2026-08-12)BR_5.5.13: market_data_billable MUST be reset to True on reactivation (H-10/STAGE3-058 2026-08-15)BR_5.5.14: Rippling inbound webhook MUST use dual-layer authentication (H-09/STAGE3-057 2026-08-15)10. Screen Description and Business Rules11. Acceptance Criteria