StackTrading Docs

SRS: Stage 3 KYC & Live Onboarding — UC_5.4: Flow 3C Dots Payout Profile

FieldValue
BA in Chargelinh.nguyen34
Date Created2026-08-07
Versionv1.8
Last Updated2026-08-25 — CR-20260825-001: Sub-flow A Step 5 corrected to use Veriff legal_name (not SIM first_name/last_name); Step 6 corrected to PUT /v2/users/{id}/addresses (not "Submit Compliance"); Sub-flow B trigger corrected to user.updated + GET re-fetch + 5-field check; BR_5.4.5 updated.
Document ReferencesZapier Integration V7.pdf (Flow 3A lines 1062–1085; Flow 3C lines 1158–1175) · RFQ_ Stack Trading Prop Tech V7.pdf (§Process Veriff Handoff, lines 754–782) · CR-20260720-004 (Freshdesk replaces Zendesk — not applicable to this UC)

UC Index

UC_IDUse Case NameBusiness Description
UC_5.4Flow 3C — Dots Payout ProfileAfter Veriff APPROVED,Process Veriff Handoff (Flow 3B / UC_5.2) runs a 3-step Dots payee creation: (1) POST /v2/users with SIM data → stores dots_payee_id; (2) Submit Compliance Information with Veriff-extracted legal_name + address (pre-fills W-9/W-8BEN); (3) POST /v2/flowsflow_link → "Payout Profile Setup" email dispatched. Flow 3C then listens for the Dots Active and Payable webhook → sets payout_status = 'Approved' → evaluates three-way aggregation gate for Flow 3D.

Changelog

DateVersionUpdated itemBeforeAfterNotes
2026-08-07v1Initial creationCreated SRS for UC_5.4 (Flow 3C — Dots Payout Profile)First authoring pass
2026-08-08v1.1Futures Dots path — §1 Scope note, §1 Overview, §3 Pre-conditions, §4 Post-conditions, §6 Alternative Flow[MISSING] — Futures path undocumented; email behavior on existing Dots profile ambiguousFlow 3A generates Dots hosted onboarding link for Futures traders; trader manually completes form, no auto-fill from Ironbeam. Email NOT sent for existing Dots profile — derived from source step 3 exit logic.Source: Zapier Integration V7.pdf Flow 3A lines 1068–1075; RFQ_ Stack Trading Prop Tech V7.pdf §Process Veriff Handoff steps 3–6
2026-08-12v1.1 → v1.2§1 Scope note — Futures pathFutures traders use Ironbeam WLP portal + manual Dots entryAll traders now use Veriff (STAGE3-037 [CHR-46]). Futures traders auto-fill Dots from Veriff same as Forex. Ironbeam WLP branch removed.STAGE3-037 confirmed 2026-08-12
2026-08-12v1.2 → v1.3§7 Sub-flow B — Dots suspension exceptional flow + §8 BR_5.4.8 / BR_5.4.9[MISSING] for Dots Suspended/Paused/Failed during Stage 3Confirmed: add Dots suspension webhook listener; set payout_status = 'Suspended'; Flow 3D blocked automatically; add payout_status == 'Approved' check to Flow 3H; dispatch Dots_Profile_Action_Needed email.STAGE3-038 [CHR-44] confirmed 2026-08-12
2026-08-15v1.4 → v1.5§1 UC Index, §1 Description, §3 Pre-cond Sub-flow A, §4 Post-cond, §5 Steps 5-9, §6 Alt-flow, §7 Exceptional FlowSub-flow A called POST /payees with Veriff-extracted legal_name/address; institution_approval_status = 'Approved' -- Forex only; second-cycle path marked [MISSING]3-step Dots process: POST /v2/users SIM data → Submit Compliance Veriff data → POST /v2/flows → flow_link. Second-cycle (H-07): skip steps 5-7, set payout_status directly. Exc flows updated with STAGE3-082/083/084/085.STAGE3-052/055/082/083/084/085 confirmed 2026-08-15
2026-08-14v1.3 → v1.4§1 Description, §1 Scope notes, §3 Pre-conditions, §4 Post-conditions, §1 Zapier Flow row"Forex only" qualifier on Sub-flow A; Futures path via Flow 3A with manual Dots entry; Scope note labeled "Forex traders"Sub-flow A now applies to ALL traders (Futures + Forex) — STAGE3-037 [CHR-46].identity_status and institution_approval_status set by Flow 3B (Veriff) for ALL traders, not Forex only. Futures path via Flow 3A + Ironbeam KYC link deprecated.[CHR-46] / STAGE3-037 [CHR-46]

Glossary

For all shared project terminology, refer to the single source of truth: Project Glossary.


<a id="UC_5.4"></a>

UC_5.4 — Flow 3C: Dots Payout Profile

1. Overview

FieldContent
IDUC_5.4
Use CaseFlow 3C — Dots Payout Profile
DescriptionThis UC covers two coupled sub-flows.Sub-flow A (Dots Payee Creation — ALL traders, inside Process Veriff Handoff / UC_5.2): Triggered when Veriff returns APPROVED for any trader. The 3-step creation process runs: (1) POST /v2/users with Veriff-extracted legal_name (split into first/last) + SIM contact fields (email, country_code, phone_number, metadata.internal_id) — must use Veriff name, NOT SIM registration name, because Dots IRS TIN matching runs against stored profile name (Dots bug, fix in progress as of 2026-08-25); (2) PUT /v2/users/{dots_payee_id}/addresses with Veriff-extracted normalized address — pre-fills W-9/W-8BEN address field on Dots Form UI (NOT PUT /compliance which signs and finalizes immediately); (3) POST /v2/flows (manage-payouts step) → flow_link. The flow_link is dispatched in the "Payout Profile Setup" email. Second-cycle logic: if dots_payee_id IS NOT NULL at APPROVED, all three steps are skipped and payout_status is set to 'Approved' directly (STAGE3-055). Sub-flow B (Payout Verification Handler — Flow 3C): When Dots fires a user.updated webhook, middleware immediately re-fetches GET /v2/users/{dots_payee_id} and validates all 5 health-check fields (status=verified, default_payout_method non-null, compliance.must_collect_1099=false, compliance.w8_ben_collected=true/skipped, compliance.flagged=false). On all-pass: sets payout_status = 'Approved' and evaluates the aggregation gate for Flow 3D.
Zapier FlowFlow 3A (initial Dots link generation) (Deprecated for Dots — STAGE3-037 [CHR-46]; Sub-flow A now runs in backend, not Zapier) · Flow 3C (Payout Verification Handler)
Backend EndpointProcess Veriff Handoff (POST — fires Sub-flow A on Veriff APPROVED)
Zapier TableUsers table (dots_payee_id written by backend; payout_status = 'Approved' set by Flow 3C)
3rd PartyDots (payee creation API, hosted W-9/W-8BEN forms, payout routing) · Veriff (source of legal_name + address for all traders — STAGE3-037 [CHR-46]) · AWS SES (delivers Payout Profile Setup email)

Scope note — Futures traders (UPDATED STAGE3-037 [CHR-46] 2026-08-12): For Futures traders, dots_payee_id creation follows a different path from Forex. Flow 3A handles both asset classes: it sets kyc_link = Ironbeam White Label Portal URL for Futures, then calls the Dots API to generate a hosted onboarding link and emails both links to the trader. The trader manually completes the Dots-hosted form; there is no auto-fill from Ironbeam data. All traders now use Veriff. Ironbeam waived manual KYC applications for all traders. Futures traders now go through Veriff (Flow 3B/UC_5.2) same as Forex traders, and the Process Veriff Handoff endpoint automatically creates the Dots payee profile using KYC-extracted legal_name and address for all traders — no manual entry required. The Futures-specific scope note on manual Dots completion is obsolete. (Source: STAGE3-037 [CHR-46] confirmed 2026-08-12)

Scope note — All traders (UPDATED STAGE3-037 [CHR-46] 2026-08-12): All traders' payout_status is set to 'Approved' by Flow 3C (this UC) after they complete the Dots onboarding. Their identity_status and institution_approval_status are set by Flow 3B (Veriff) — this applies to both Futures and Forex traders since all traders now go through Veriff (STAGE3-037 [CHR-46]). All three fields must be 'Approved' before Flow 3D fires.

Scope note — Returnee Trader bypass (BR_5.1.11 / STAGE3-055/H-07 extended, 2026-08-18): For Returnee Traders (Branch B at Flow 3A — identity_status = 'Approved' AND dots_payee_id IS NOT NULL AND contract_status = 'Signed'), Sub-flow A and Sub-flow B are both skipped entirely. Flow 3A Branch B sets payout_status = 'Approved' directly in one atomic DB write without calling the Dots API. No new Dots session is created; therefore Dots does NOT fire a new "Active and Payable" webhook for Returnee Traders. Flow 3C (this UC) is not triggered for the Returnee path.


2. Trigger

Sub-flow A — Dots Payee Creation: Triggered as a synchronous step within the Process Veriff Handoff backend endpoint when Veriff returns verification_status = 'approved'. The backend processes the Veriff webhook, then immediately calls the Dots API if dots_payee_id IS NULL in the Users table.

Sub-flow B — Payout Verification Handler (Flow 3C): Triggered when Dots sends a user.updated webhook. Middleware must NOT parse compliance fields directly from the webhook payload — instead, immediately re-fetch GET /v2/users/{dots_payee_id} and validate the 5-field health check on the response. This is the pattern confirmed by Dots (CR-20260825-001 2026-08-25).


3. Pre-conditions

Sub-flow A (Dots Payee Creation — ALL traders):

  • Veriff webhook received with verification_status = 'approved' for the trader's KYC session.
  • Backend has successfully validated the Veriff cryptographic payload signature (HMAC check).
  • legal_name, address, and kyc_country have been extracted from the Veriff payload and saved to Users table (UC_5.2 §5 Step 3).
  • SIM registration data (first_name, last_name, email, country_code, phone_number) available in Users table from Stage 1/2 registration.
  • Applies to ALL traders (Futures and Forex) — STAGE3-037 [CHR-46].

Sub-flow B (Payout Verification Handler — Flow 3C):

  • Dots payee profile exists for the trader (created via Sub-flow A for ALL traders — Veriff path).
  • Trader has clicked the Dots white-labeled onboarding link and completed it.
  • Trader has completed the Dots-hosted tax form (W-9 for US; W-8BEN for international) and linked a payout routing method.
  • Dots has confirmed the profile is Active and Payable and fired the webhook.

4. Post-conditions

Sub-flow A — On Dots payee creation (success — ALL traders, first cycle):

  • dots_payee_id stored in the Users table for this user_id.
  • identity_status = 'Approved', institution_approval_status = 'Approved' written.
  • payout_flow_link (from POST /v2/flows) stored for email dispatch.
  • "Payout Profile Setup" email sent to trader via AWS SES containing the personalized flow_link.

Sub-flow A — Second cycle (dots_payee_id IS NOT NULL — H-07/STAGE3-055):

  • Dots steps 4A-1 through 4A-3 skipped entirely.
  • identity_status = 'Approved', institution_approval_status = 'Approved', payout_status = 'Approved' all written directly.
  • No payout email dispatched.
  • Aggregation check fires immediately.

Sub-flow B — On webhook received from Dots:

  • Users table updated: payout_status = 'Approved' for user_id.
  • Aggregation gate evaluated: if identity_status == 'Approved' AND institution_approval_status == 'Approved' → Flow 3D triggered via internal webhook.
  • If any status is still 'Pending', Zap terminates and waits.

5. Basic Flow

Sub-flow A — Dots Payee Creation (inside Process Veriff Handoff)

  1. Veriff webhook arrives at the backend Process Veriff Handoff endpoint.
  2. Backend validates Veriff cryptographic signature (HMAC).
  3. Backend extracts from the Veriff payload: user_id, verification_status, legal_name, address.
    • 3a. If verification_status != 'approved' → update Users table status and halt (handled in UC_5.2).
    • 3b. If verification_status == 'approved' → continue.
  4. Backend queries Users table: SELECT dots_payee_id FROM Users WHERE user_id = extracted_user_id.
    • 4a. If dots_payee_id IS NOT NULL (second cycle) → skip to Step 8 (second-cycle path). See Alternative Flow.
    • 4b. If dots_payee_id IS NULL → proceed to Step 5.
  5. POST /v2/users — create Dots user with Veriff-extracted legal_name + SIM contact fields.
    • Payload: first_name + last_name from Veriff legal_name (split into parts), email, country_code, phone_number, metadata.internal_id = user_id. Must use Veriff legal name — NOT SIM registration name — because Dots IRS TIN matching runs against stored profile name, not W-9 payload. Known Dots bug (fix in progress as of 2026-08-25).
    • On success: store returned Dots user ID as dots_payee_id in Users table.
    • On failure (non-200 / timeout): Exponential Backoff 8× retry via BullMQ (STAGE3-085). On exhaustion → Dead Letter Queue + SEV1 Slack alert. identity_status NOT updated. (Source: STAGE3-052 / H-04, STAGE3-085 confirmed 2026-08-15; legal_name correction: CR-20260825-001)
  6. PUT /v2/users/{dots_payee_id}/addresses — pre-fill Veriff-extracted address on Dots profile.
    • Sends normalized address JSON (line_1/line_2/city/state/postcode/country) from Veriff payload. No TIN, DOB, or signature required.
    • This populates the address field on W-8BEN/W-9 form in Dots Flow UI — trader sees it pre-filled.
    • PUT /v2/users/{id}/compliance is NOT called from middleware in this flow: that endpoint signs and finalizes the form immediately. Only invoke if middleware has all required fields (TIN for W-9; DOB + signature for W-8BEN). With current design, trader self-enters TIN/signs.
    • If 400 addressinvalid → skip address pre-fill, continue. Trader self-enters address on Dots Flow UI. Non-blocking. (Source: CR-20260825-001 2026-08-25)
  7. POST /v2/flows (manage-payouts step) — generate personalized flow_link.
    • Call Dots API POST /v2/flows.
    • Receive flow_link — personalized, session-scoped URL with pre-filled tax form.
    • Store flow_link in Users table.
  8. Update KYC status.
    -- First-cycle (dots_payee_id was NULL — arrived here via 4b):
    UPDATE Users
    SET identity_status               = 'Approved',
        institution_approval_status   = 'Approved'
    WHERE user_id = extracted_user_id
    
    -- Second-cycle (dots_payee_id was NOT NULL — arrived here via 4a, H-07/STAGE3-055):
    UPDATE Users
    SET identity_status               = 'Approved',
        institution_approval_status   = 'Approved',
        payout_status                 = 'Approved'
    WHERE user_id = extracted_user_id
  9. Dispatch "Payout Profile Setup" email (first cycle only).
    • Backend fires internal webhook to Zapier.
    • Zapier sends email via AWS SES containing flow_link.
    • Second cycle: Step 9 is skipped (payout_status already set at Step 8).

Sub-flow B — Payout Verification Handler (Flow 3C)

  1. Dots sends user.updated webhook to Zapier/middleware, containing user_id.

  2. Middleware immediately calls GET /v2/users/{dots_payee_id} to re-fetch current state. Do NOT parse compliance fields directly from webhook payload — Dots does not guarantee all 5 fields are present in the payload. (Source: CR-20260825-001 2026-08-25)

  3. Validate 5-field health check on GET response:

    FieldRequired value
    status"verified"
    default_payout_methodnon-null
    compliance.must_collect_1099false
    compliance.w8_ben_collectedtrue or w8_ben_skipped
    compliance.flaggedfalse
    • All 5 pass → proceed to Step 4.
    • compliance.flagged = true → block payout_status update; SEV-1 alert → Ops; Ops manual override (reason + evidence + audit log). If form data deeply mismatched → Dots support must reset form by hand. See §7 Exceptional Flow.
    • Any other field fails → Zap terminates; waits for next user.updated event.
  4. Zapier UPDATE Users table: payout_status = 'Approved' WHERE user_id = webhook.user_id.

  5. Aggregation gate check: Zapier queries Users table for user_id:

    • IF identity_status == 'Approved' AND institution_approval_status == 'Approved' → fire internal webhook to trigger Flow 3D (UC_5.5).
    • ELSE → Zap terminates; waits for remaining approvals (identity or institution still 'Pending').

6. Alternative Flow

  • [Sub-flow A — Second cycle: dots_payee_id IS NOT NULL at Step 4a (H-07/STAGE3-055)]

    • Backend detects dots_payee_id IS NOT NULL. Skips steps 5–7 (Dots API calls).
    • Step 8 second-cycle path: sets identity_status = 'Approved', institution_approval_status = 'Approved', payout_status = 'Approved' all in one DB write.
    • Step 9 (email) is skipped. No "Payout Profile Setup" email dispatched.
    • Aggregation gate fires immediately after Step 8 if all conditions met.
    • Rationale (confirmed): Dots does NOT re-issue an Active/Payable webhook for existing payee accounts. payout_status must be set directly by Middleware. (Source: STAGE3-055 / H-07 confirmed 2026-08-15)
  • [Sub-flow B — Aggregation gate not yet met when payout is approved]

    • payout_status is set to 'Approved' but one or both of identity_status or institution_approval_status are still 'Pending'.
    • Flow 3C Zap terminates. No Flow 3D trigger yet.
    • When Flow 3B (Veriff — now covers ALL traders per STAGE3-037 [CHR-46]) later sets the remaining approval fields, the gate is re-evaluated at that time. Flow 3B.2 (Ironbeam) deprecated (STAGE3-039).

7. Exceptional Flow

  • [Sub-flow A — Dots API failure (Step 5 POST /v2/users, Step 6 Submit Compliance, or Step 7 POST /v2/flows)]

    • Non-200 or connection timeout at any of the 3 Dots steps.
    • Retry: Exponential Backoff 8× via BullMQ/Redis (+5s, +15s, +1m, +5m, +15m, +1h, +3h, +12h). (Source: STAGE3-085 / Kịch bản 4 confirmed 2026-08-15)
    • On exhaustion: Dead Letter Queue + SEV1 Slack alert #ops-compliance → Ops intervenes via Ops Console.
    • dots_payee_id remains NULL (if failed at Step 5). identity_status NOT updated. Trader locked at aggregation gate.
    • Special case — HTTP 200 but no payee_id returned: Validation Gate blocks NULL write to dots_payee_id, enqueues retry. (Source: STAGE3-069 / M-10 confirmed 2026-08-15)
  • [Sub-flow A — Dots profile: W-9/W-8BEN Rejected or TIN/SSN mismatch (Kịch bản 1 / STAGE3-082)]

    • Trader completes flow link but Dots Compliance rejects the submission.
    • Middleware receives Dots webhook → sets/keeps payout_status = 'Pending' → calls POST /v2/flows to generate New Session Flow Link (old link invalidated after first submit).
    • AWS SES dispatches email Dots_Profile_Action_Needed (or Level_6_International_Contractor_Dots_Profile_Action_Needed) with new link.
  • [Sub-flow A — Bank linking failure via Plaid (Kịch bản 2 / STAGE3-083)]

    • Trader completes tax form but fails bank link. Dots marks flow as Completed but account is Not Payable. No new flow link needed.
    • Dashboard renders "Manage Payouts" button linking to static payout_portal_url from GET /current-level-detail. Trader self-heals by re-linking bank via phone + OTP.
  • [Sub-flow B — Dots webhook missing metadata.internal_id (Kịch bản 3 / STAGE3-084)]

    • Middleware cannot correlate webhook to a user_id. Performs fallback query by email/phone. If still no match → SEV1 Slack alert #ops-compliance + Zendesk Compliance_Review ticket for manual assignment.
  • [Sub-flow B — Dots webhook not received (trader never completes Dots setup — STAGE3-068 / M-09)]

    • payout_status stays 'Pending' indefinitely. No automated reminder email. flow_link has TTL set by Dots.
    • Aggregation gate holds. Trader blocked from Flow 3D.
  • [Sub-flow B — Dots profile becomes Suspended, Paused, or Failed after initial approval]

    Confirmed — STAGE3-038 [CHR-44] 2026-08-12: This does NOT happen automatically without building a dedicated listener. Current architecture only listens for the Active and Payable success webhook. To handle suspension events:

    1. New webhook listener required: Create a webhook listener for any Dots status change to 'Suspended', 'Paused', or 'Failed'.
    2. DB update: When the suspension webhook fires → immediately execute:
      UPDATE Users SET payout_status = 'Suspended' WHERE user_id = webhook.user_id
    3. Flow 3D blocked automatically: Because Flow 3D requires payout_status = 'Approved', setting it to 'Suspended' is sufficient to break the Flow 3D chain. No additional gate check change needed in Flow 3D.
    4. Flow 3H pre-condition gap (critical): If a trader's Dots account is suspended AFTER contract signing but BEFORE market data setup, Flow 3H would incorrectly fund them because it currently only checks contract_status and setup_status. payout_status == 'Approved' must be added as a mandatory pre-condition check to Flow 3H (UC_5.8). See BR_5.4.8.
    5. Trader notification: Automatically dispatch Dots_Profile_Action_Needed email to the trader so they know they need to fix their tax or routing information before they can proceed. See BR_5.4.9.

    (Source: Client confirmed STAGE3-038 [CHR-44] 2026-08-12; zapier_v7_full.txt line 728 — Dots_Profile_Action_Needed email referenced in Stage 5/6)


8. Business Rules

<a id="BR_5.4.1"></a>

BR_5.4.1: Auto-Create from Veriff — No Trader Re-entry

The Dots payee profile is created automatically by the backend using legal_name and address extracted directly from the Veriff KYC payload. The trader is NOT required to manually re-enter their legal name or address in the Dots form. This eliminates a data-entry step and reduces name mismatch risk.

(Source: RFQ_ Stack Trading Prop Tech V7.pdf §Process Veriff Handoff, lines 766–769)

<a id="BR_5.4.2"></a>

BR_5.4.2: Idempotent Payee Creation — Skip if Profile Exists

If the Users table already has a non-NULL dots_payee_id for the user_id at the time the Veriff handoff runs, the backend does NOT call POST /payees again. It updates local KYC status to 'Approved' and exits the creation path. This prevents duplicate Dots profiles for traders who have been through a prior account cycle.

(Source: RFQ_ Stack Trading Prop Tech V7.pdf §Process Veriff Handoff, lines 762–765)

<a id="BR_5.4.3"></a>

BR_5.4.3: Tax Form Type Determined by Billing Country

The Dots white-labeled onboarding link natively presents the appropriate tax form based on the trader's Billing_Country:

  • US traders (Billing_Country = 'US'): W-9 form.
  • International traders (all other countries): W-8BEN form.

The form type selection is handled natively by the Dots platform — Stack Trading does not render the tax form itself.

(Source: Zapier Integration V7.pdf Flow 3A lines 1070–1073; RFQ_ Stack Trading Prop Tech V7.pdf lines 780–782)

<a id="BR_5.4.4"></a>

After dots_payee_id is stored, the backend fires a webhook to Zapier, which triggers the "Payout Profile Setup" email to the trader via AWS SES. This email contains the Dots white-labeled link that:

  1. Collects the W-9 or W-8BEN tax form (per BR_5.4.3).
  2. Collects the trader's payout routing information (bank account, debit card, etc.).

The Dots platform handles all tax form collection and payout routing setup — Stack Trading does not collect this data directly.

(Source: RFQ_ Stack Trading Prop Tech V7.pdf §Process Veriff Handoff, lines 778–782)

<a id="BR_5.4.5"></a>

BR_5.4.5: Flow 3C Trigger — user.updated Webhook + 5-Field Health Check (Updated CR-20260825-001)

payout_status is only set to 'Approved' when ALL 5 conditions pass after re-fetching GET /v2/users/{dots_payee_id} on receipt of a user.updated webhook from Dots:

  1. status = "verified"
  2. default_payout_method is non-null
  3. compliance.must_collect_1099 = false
  4. compliance.w8_ben_collected = true or w8_ben_skipped
  5. compliance.flagged = false

The webhook payload must NOT be parsed directly for compliance fields — Dots does not guarantee all fields are present in the payload. The re-fetch pattern (user.updatedGET /v2/users/{id} → validate) is the confirmed Dots-recommended approach.

Partial completion (e.g., tax form signed but no payout account linked) does NOT pass all 5 conditions and does NOT set payout_status = 'Approved'.

(Source: CR-20260825-001 — Dots vendor confirmed 2026-08-25; supersedes "Active and Payable" webhook description from Zapier Integration V7.pdf Flow 3C lines 1158–1161)

<a id="BR_5.4.6"></a>

BR_5.4.6: Aggregation Gate — Two-Field Check in Flow 3C

Flow 3C's aggregation gate checks identity_status == 'Approved' AND institution_approval_status == 'Approved' before triggering Flow 3D. This is intentionally a two-field check (not three) because payout_status is the field being set by this flow — it is already guaranteed to be 'Approved' at this point.

Cross-reference: Flow 3B (UC_5.2) and Flow 3B.2 (UC_5.3) each check all three fields (including payout_status). Whichever flow last sets its field to 'Approved' will be the one that successfully triggers Flow 3D. UPDATED (STAGE3-037 [CHR-46]/039 [CHR-46] — [CHR-46] — 2026-08-12): Flow 3B.2 / UC_5.3 deprecated. Flow 3B (UC_5.2) now handles ALL traders (Futures and Forex). Whichever of Flow 3B (UC_5.2) or Flow 3C (UC_5.4) fires last will trigger Flow 3D.

(Source: Zapier Integration V7.pdf Flow 3C lines 1169–1175)

<a id="BR_5.4.7"></a>

BR_5.4.7: Veriff HMAC Signature Validation — Mandatory Security Gate

The Process Veriff Handoff backend endpoint MUST validate the Veriff cryptographic signature (HMAC) before processing any payload content. If validation fails, the request is rejected and no KYC status update or Dots API call occurs.

(Source: RFQ_ Stack Trading Prop Tech V7.pdf §Process Veriff Handoff, line 754)


🔄 CR — STAGE3-038 [CHR-44]: Dots suspension webhook listener added. Sets payout_status = 'Suspended' on Dots Suspended/Paused/Failed events. payout_status == 'Approved' added as mandatory pre-condition to Flow 3H.

<a id="BR_5.4.8"></a>

BR_5.4.8: Dots Suspension Webhook Listener — payout_status = 'Suspended' (STAGE3-038 [CHR-44] 2026-08-12)

The system MUST implement a webhook listener for Dots status change events. When Dots sends a webhook indicating the payee profile status has changed to 'Suspended', 'Paused', or 'Failed':

  1. Backend updates payout_status = 'Suspended' in the PostgreSQL Users table.
  2. This DB update is sufficient to break the Flow 3D chain (Flow 3D requires payout_status = 'Approved').
  3. No separate gate change is required in Flow 3D — the existing check on payout_status == 'Approved' will block the trigger.

Critical gap in Flow 3H: Flow 3H currently only checks contract_status and setup_status. If a trader's Dots account is suspended after contract signing but before market data setup, Flow 3H would fund them incorrectly. payout_status == 'Approved' MUST be added as a pre-condition check to Flow 3H (UC_5.8). See UC_5.8 §3 Pre-conditions.

(Source: Client confirmed STAGE3-038 [CHR-44] 2026-08-12)


🔄 CR — STAGE3-038 [CHR-44]: Dots_Profile_Action_Needed email dispatch added on suspension. Non-blocking relative to DB update.

<a id="BR_5.4.9"></a>

BR_5.4.9: Dots_Profile_Action_Needed Email on Suspension (STAGE3-038 [CHR-44] 2026-08-12)

When the Dots suspension webhook fires (triggering payout_status = 'Suspended'), the system MUST automatically dispatch the Dots_Profile_Action_Needed email to the trader. This email informs the trader that their tax or routing information needs to be corrected before they can proceed with live trading onboarding.

The email dispatch is non-blocking relative to the DB update — both must execute, but email failure must not roll back the payout_status = 'Suspended' write.

(Source: Client confirmed STAGE3-038 [CHR-44] 2026-08-12; zapier_v7_full.txt line 728 — Dots_Profile_Action_Needed referenced)


9. Wireframe / UI

No screen is required for this UC. Both sub-flows are fully automated backend and Zapier processes. The only trader-facing touchpoint is the Dots white-labeled hosted link (owned and rendered by Dots, not by Stack Trading) and the "Payout Profile Setup" email (sent by Zapier/AWS SES).


10. Screen Description and Business Rules

N/A — this use case contains no Stack Trading-owned UI screens. All processing is automated via the backend Process Veriff Handoff endpoint, Dots API, Zapier, and AWS SES.


END OF UC_5.4


Update History

DateVersionSectionChange FromChange ToSource
2026-08-11v1 → v1.1§5 Sub-flow A Steps 4–8 — execution orderidentity_status = 'Approved' written at Step 4a exit / after Step 4a-b split; Dots call at Step 5; no explicit gate noteDots call at Step 5 (with failure halt note);dots_payee_id saved at Step 6; identity_status = 'Approved' written at Step 7 AFTER save; explicit note: identity_status gated on dots_payee_id successSTAGE3-025 confirmed 2026-08-11
2026-08-11v1 → v1.1§7 Exceptional Flow — POST /payees error[MISSING] — behavior undefinedConfirmed: halt on failure; identity_status stays 'Pending' (never written); no auto-retry; Break-Glass Runbook (POST /api/bps/kyc/reset or Ops Console manual override)STAGE3-025 confirmed 2026-08-11
2026-08-11v1 → v1.1§7 Exceptional Flow — empty payee_id[MISSING]Same halt + Break-Glass path as POST /payees non-200STAGE3-025 confirmed 2026-08-11
2026-08-11v1 → v1.1§6 Alternative Flow — existing profile (Step 4a)"exits at step 3" (stale step number reference)Updated to "exits at Step 4a" matching renumbered flowStep renumbering in this update
2026-08-22v1.6 → v1.7All sections — CHR tag standardizationBare STAGE3 codes without CHR tags; date-based CR refsB8: STAGE3-037 → STAGE3-037 [CHR-46] (8 occurrences). B9: STAGE3-038 → STAGE3-038 [CHR-44] (8 occurrences). A36: CR-20260813-001 → [CHR-46] (2 occurrences). B10: STAGE3-039 → STAGE3-039 [CHR-46] (1 occurrence).CHR_Tag_Change_Plan_20260822_v4.md
2026-08-25v1.7 → v1.8§1 Description; §2 Sub-flow B trigger; §5 Sub-flow A Step 5/6; §5 Sub-flow B Steps 1–5; §8 BR_5.4.5POST /v2/users used SIM first_name/last_name; Step 6 = "Submit Compliance Information"; Sub-flow B trigger = "Active and Payable" webhook; BR_5.4.5 based on Active/PayablePOST /v2/users must use Veriff legal_name (IRS TIN matching runs on stored profile name — Dots bug in progress); Step 6 = PUT /v2/users/{id}/addresses (pre-fill only, not compliance submission); Sub-flow B trigger = user.updated → GET /v2/users/{id} re-fetch → 5-field health check; BR_5.4.5 updated to 5-field check patternCR-20260825-001 (Dots vendor 2026-08-25)

On this page