StackTrading Docs

SRS: UC_7.2 — Compliance Check & Amount Determination

BA in ChargeDate CreatedVersionDocument References
Trang Nguyen2026-10-05v1Zapier Integration V7.pdf §Flow 4 ("Ledger Update", "Data Fee Refund Calculation (Level 3 Bonus)"), §Flow 5 ("Compliance Check", "Matrix Lookup", "Minimum Check" — descoped), Appendix A/B (Table A/B); RFQ_ Stack Trading Prop Tech V7.pdf §Financial & Transaction Endpoints (GET /financial/calculate-data-refund); QnA_STAGE5_PAYOUT_WITHDRAWAL.md A-09→A-19, A-76→A-78 (A-09/A-10/A-11/A-12 answered by client 2026-09-10; A-13/A-18/A-19/A-76/A-77/A-78 settled by BA Trang Nguyen 2026-10-04/05)

Document References

#Original DocumentKey Sections Used
1Zapier Integration V7.pdf§Flow 4 ("Ledger Update" → "Data Fee Refund Calculation (Level 3 Bonus)"); §Flow 5 ("Compliance Check", "Matrix Lookup", "Minimum Check" — descoped); Appendix A ("Forex Configuration Matrix — Table A"); Appendix B ("Futures Configuration Matrix — Table B")
2RFQ_ Stack Trading Prop Tech V7.pdf§Financial & Transaction Endpoints (GET /financial/calculate-data-refund)
3QnA_STAGE5_PAYOUT_WITHDRAWAL.md (References/QnA from clients/06_STAGE5_PAYOUT_WITHDRAWAL/)UC_7.2 — Compliance + Amount: A-09→A-19, A-76→A-78

UC_7.2 — Compliance Check & Amount Determination

1. Overview

FieldContent
IDUC_7.2
Use CaseCompliance Check & Amount Determination (Flow 5 Steps 2–3: "Compliance Check" + "Matrix Lookup")
DescriptionThe second and third steps Flow 5 executes for a trader, immediately afterUC_7.1 (Anti-Fraud Reconciliation) completes, regardless of UC_7.1's outcome. First, it verifies the trader's Payout_Status is 'Approved' in the internal database — a KYC/compliance gate maintained asynchronously by Dots webhooks, never called live. Second, it determines the dollar amount to pay — by reading the Total_Payout amount that Flow 4 (Promotion) already computed and locked into the SQL payouts table record at the moment of promotion. If Payout_Status is anything other than 'Approved', the amount is held/accrued rather than cancelled, and multiple held promotions bundle into a single aggregated payout once compliance clears.
Zapier FlowFlow 5 — Payouts (Bonus), Steps "Compliance Check" + "Matrix Lookup" (precedes UC_7.3 — Routing & Execution; followsUC_7.1 — Reconciliation). The amount this UC reads is actually produced earlier, inside Flow 4's "Ledger Update" → "Data Fee Refund Calculation (Level 3 Bonus)" step.
Zapier TableTable A (Forex Configuration Matrix) / Table B (Futures Configuration Matrix) —Bonus_Paid_To_Trader column, looked up by Flow 4 at promotion time. Table C (Global Variables) — Base_CME_Data_Cost, feeds the Level 3 Futures Market Data refund calculation.
3rd PartyDots — source of Payout_Status via webhook (no live API call made by this UC); also emails the trader directly when a payout is held. Freshdesk — Ops ticket created via middleware webhook when a payout is held for compliance.

No wireframe — backend compliance/calculation step with no UI screen of its own in this version. A "Day 2 Payouts" dashboard screen that would surface a "Pending DOTS Review" flag has been raised by the client but is not yet confirmed as in scope (open item, tracked as A-74 — not part of this version).


2. Trigger

Event-driven — fires immediately after UC_7.1 (Anti-Fraud Reconciliation) completes, within the same Flow 5 execution, regardless of UC_7.1's outcome (within tolerance, beyond tolerance, or endpoint failure — none of those outcomes block this UC).

This UC — and Flow 5 as a whole — only ever fires once Flow 4 (Promotion) has fully completed, including its "Data Fee Refund Calculation" step, which locks the promotion's payout amount into the SQL payouts table (see BR_7.2.3). There is no intermediate state in which a trader has "hit" a Profit Target without Flow 4 having already finished and handed off payout data — see BR_7.2.5 for why this rules out a hard-breach race condition between target-hit and payout.

Reaching a Profit Target while in Defense mode (Flow 4B) does not constitute a genuine promotion for payout purposes and does not trigger Flow 4's payout-locking step — see BR_7.2.6.


3. Pre-conditions

IDCondition
P-1UC_7.1 (Anti-Fraud Reconciliation) has completed for this promotion event, regardless of its outcome.
P-2Flow 4 (Promotion) has fully completed for this promotion event, including locking the promotion's payout amount (Level_Performance_Bonus, plus the Market Data fee refund if Level 3 + Futures) into the SQL payouts table record — see BR_7.2.3.
P-3user_id resolves to exactly one account and one Asset_Class — a trader never holds parallel Futures and Forex accounts, so Payout_Status and the locked payout amount are both unambiguous when keyed by user_id.

4. Post-conditions

Payout_Status = 'Approved'

  • The locked Payout_Amount from Flow 4 (plus any amount still accrued from earlier held promotions, bundled — see BR_7.2.2) proceeds immediately to UC_7.3 (Routing & Execution — SRS not yet written). No minimum-amount or rollover check is applied — not even when the locked amount is $0 — see BR_7.2.3.

Payout_Status is anything other than 'Approved'

  • The amount is held in an accrued state, not cancelled. The promotion/level-up itself is unaffected — only the money transfer is paused. The middleware fires a webhook that opens a Freshdesk ticket for Ops. See BR_7.2.2.

5. Basic Flow

  1. Flow 5 continues. Immediately after UC_7.1's reconciliation call, Flow 5 proceeds to its "Compliance Check" step for the same trader/promotion event.

  2. Query Payout_Status. The middleware queries the trader's Payout_Status field from the internal PostgreSQL database — this value is not fetched live from Dots/Ripplings; it is maintained asynchronously by Dots/Ripplings webhooks and simply read here. See BR_7.2.1.

  3. Evaluate Payout_Status:

    • 'Approved' → continue to step 4 (see §6 Alt-1).
    • Anything else → go to Exc-1; do not continue to step 4 for this promotion's amount yet. See BR_7.2.2.
  4. Read the locked payout amount. The system does not recompute the bonus from Table A/B at this point. It reads the Total_Payout value that Flow 4 already calculated and wrote to the SQL payouts table record for this specific promotion, at the moment the trader was promoted — see BR_7.2.3 for how Flow 4 produced that value (Table A/B lookup by Current_Level, plus the Level 3 + Futures Market Data refund where applicable). This proceeds even if Total_Payout resolves to $0 — see BR_7.2.3.

  5. Hand off to Routing & Execution. The determined Payout_Amount proceeds to UC_7.3 (Routing & Execution — SRS not yet written) for Dots/Rippling dispatch.


6. Alternative Flows

  • Alt-1 — Payout_Status is already 'Approved' at promotion time (expected common case).

    • Context: the trader's compliance/KYC profile with Dots is already fully approved when this promotion event reaches the Compliance Check step.
    • The flow proceeds through steps 4–6 of §5 with no hold and no delay.
  • Alt-2 — Level 3, Futures: the locked amount includes the Market Data fee refund.

    • Context: the trader is being promoted to Level 3 on a Futures account. At the Flow 4 stage that preceded this UC, the middleware called GET /financial/calculate-data-refund (input user_id) to total the "Base" Market Data fees paid during Level 1 and Level 2 (SELECT SUM(amount) FROM invoices WHERE user_id = [Input] AND fee_type = 'MARKET_DATA_BASE' AND status = 'paid'), explicitly excluding non-refundable "Add-On" (e.g., NYMEX/COMEX) and "Platform" fees, and added the result (refundable_amount) to Level_Performance_Bonus to form the locked Total_Payout. (Source: RFQ_ Stack Trading Prop Tech V7.pdf §Financial & Transaction Endpoints; Zapier Integration V7.pdf §Flow 4 "Data Fee Refund Calculation (Level 3 Bonus)")
    • This UC's own step 4 behaves identically to Alt-1 from this point on — it simply reads whatever Total_Payout was locked, whether or not it includes the refund component.

7. Exceptional Flows

  • Exc-1 — Payout_Status is not 'Approved' (any other value, including values not yet enumerated).
    • The automated payout API trigger halts for this promotion's amount. The amount remains in an accrued holding state — it is not cancelled and the trader's level-up is not reversed. See BR_7.2.2.
    • The middleware separately fires a webhook that opens a Freshdesk ticket for Ops. The freshdesk ticket for Operations, the payload must include the user_id, the user's registered email, the new payout_status, and any specific error or reason code provided by the Dots webhook (If have).
    • If the trader is promoted again (reaches another level) while still held, that promotion's own locked amount accrues as well — when Payout_Status eventually returns to 'Approved', all accrued amounts across every held promotion are bundled into a single aggregated payout, executed instantly by resuming Flow 5 (UC_7.3 — Routing & Execution, SRS not yet written).

8. Business Rules

BR_7.2.1: Compliance Check — Payout_Status gate, checked at every promotion, sourced from internal PostgreSQL

The system checks the Payout_Status variable at every single level promotion, not just once. This check queries the internal PostgreSQL database — it is not a direct, live Dots/Ripplings API call. The value is maintained asynchronously by DotsRipplings webhooks, which write it into the database whenever Dots' own status changes.


BR_7.2.2: Non-'Approved' status holds and accrues the payout; it never cancels it, and held amounts bundle

If Payout_Status is anything other than 'Approved' at the Compliance Check — the client explicitly ruled out building custom routing for intermediate statuses such as pending, action_required, or rejected; any non-'Approved' value is treated identically — the automated payout halts and the funds enter an accrued holding state. This is a hold, not a cancellation: the trader's promotion/level-up already happened via Flow 4 and is not reversed.

If the trader advances through additional levels while still held, each subsequent promotion's locked amount (see BR_7.2.3) accrues on top of the earlier one. When Payout_Status is confirmed 'Approved' again, the system must bundle all earned bonuses into a single aggregated payout and execute it instantly.


BR_7.2.3: The payout amount is computed and locked by Flow 4 at promotion time — Flow 5 only disburses it

Flow 4 (Promotion), not Flow 5, is responsible for determining the dollar amount of a payout. During the promotion event, Flow 4 looks up Level_Performance_Bonus (= Bonus_Paid_To_Trader from Table A/B, keyed by the level just reached) and, for Level 3 + Futures only, adds the Market Data fee refund (refundable_amount, from GET /financial/calculate-data-refund — see §6 Alt-2) to form Total_Payout. Flow 4 then writes this Total_Payout into the SQL payouts table record for that specific promotion event, before triggering Flow 5.

When Flow 5 reaches this UC's Compliance Check / amount-determination step — whether immediately or after a compliance hold is later released (see BR_7.2.2) — it must use the exact amount already locked in the payouts table for each individual promotion, not re-derive it from a fresh Table A/B lookup at disbursement time. This is what allows a trader who is promoted multiple times while held under BR_7.2.2 to still receive the correct amount for each earlier level, even though their Current_Level has since moved on — a fresh lookup by Current_Level at payout time would silently return the wrong, more-recent level's bonus instead.


BR_7.2.4: Ops "Do Not Pay" list gate is out of scope for this phase

An Ops-maintained "Do Not Pay" list, checked as a separate gate before Compliance Check disburses funds, was proposed during analysis (with a corresponding Held_Ops hold state, distinct from the Held_Compliance state in BR_7.2.2). This gate is not part of the current phase's scope — the Compliance Check in this UC relies solely on Payout_Status (BR_7.2.1/BR_7.2.2). Do not build a payout_hold / "Do Not Pay" gate in this version.

(Source: QnA_STAGE5_PAYOUT_WITHDRAWAL.md A-19 — BA Trang Nguyen, 2026-10-04, descoped to a later phase)


BR_7.2.5: No race window between a Profit Target hit and a hard breach before the payout is locked

Flow 5 — and therefore this UC — is never triggered by a Profit Target being hit in isolation. It is triggered only once Flow 4 has fully completed and handed off locked payout data (see BR_7.2.3). Consequently, there is no window in which a trader could hit a Profit Target, then suffer a hard breach, before this UC's Compliance Check / amount lookup runs: if Flow 4 has not yet finished, the payout simply has not been triggered yet either.

(Source: QnA_STAGE5_PAYOUT_WITHDRAWAL.md A-77 — BA Trang Nguyen, 2026-10-04)


BR_7.2.6: Hitting Profit Target while in Defense mode does not trigger a payout

If a trader is in Defense mode (per Flow 4B) when they reach their Profit Target, this does not trigger a payout. The trader must instead return to standard trading and reach the Profit Target of the level prior to entering Defense in order to level up properly — only that produces a genuine promotion, and therefore a payout via Flow 4 → Flow 5.

This reverses an earlier BA assumption that Defense status would have no bearing on payout eligibility.

(Source: QnA_STAGE5_PAYOUT_WITHDRAWAL.md A-78 — BA Trang Nguyen, 2026-10-04, reversing the original BA-proposed assumption)


9. Update History

DateVersionSectionChange FromChange ToSource
2026-10-05v1All (new)UC_7.2 not yet written.Zapier Integration V7.pdf §Flow 5 described "Compliance Check" (Payout_Status gate) and "Matrix Lookup" (direct Table A/B lookup) as two simple sequential steps, followed by a "Minimum Check" ($100 floor + rollover).Initial SRS. Compliance gate confirmed to run on every promotion from internal PostgreSQL, not live Dots calls (A-09). Non-Approved status holds and bundles across promotions rather than cancelling (A-11, A-12). Minimum Check / rollover fully descoped (A-10, CR). "Matrix Lookup" reinterpreted: the amount is computed and locked by Flow 4 at promotion time, not re-derived by Flow 5 at payout time (A-76) — necessary for the bundling mechanism in A-11/A-12 to produce correct per-level amounts; empty/null Table A/B cell edge case confirmed removed (A-76, 2026-10-05). Lookup key confirmed asCurrent_Level, with the raw Table A/B grid's apparent 2-values-per-level ambiguity flagged as open pending the original spreadsheet (A-13). One account per trader, single asset class, user_id-keyed, confirmed (A-18). Ops "Do Not Pay" gate descoped to a later phase (A-19). No race window between target-hit and hard breach, since Flow 5 only fires once Flow 4's data is locked (A-77). Defense-mode target-hit does not trigger payout (A-78), reversing the original BA assumption.Zapier Integration V7.pdf §Flow 4, §Flow 5, Appendix A/B; RFQ_ Stack Trading Prop Tech V7.pdf §Financial & Transaction Endpoints; QnA_STAGE5_PAYOUT_WITHDRAWAL.md A-09→A-19, A-76→A-78
2026-10-08v1§4, §5 step 4, §8 (BR_7.2.3→BR_7.2.8, old BR_7.2.3 removed)BR_7.2.3 existed as a standalone rule ("Minimum Payout Threshold and Rollover Balance are fully descoped"), separate from the Flow-4-locks-the-amount rule (old BR_7.2.4). 9 BRs total (BR_7.2.1→BR_7.2.9).Old BR_7.2.3 removed. Client confirmed the flow still proceeds even when Total_Payout resolves to $0 — there is no minimum-amount floor and $0 is not an error/halt condition. This point is now folded as a note into (new) BR_7.2.3 (old BR_7.2.4, "payout amount computed and locked by Flow 4") rather than kept as its own rule, since both rules were about the same "no gatekeeping on the locked amount" idea. All subsequent BRs renumbered: old BR_7.2.4→new BR_7.2.3, 7.2.5→7.2.4, 7.2.6→7.2.5, 7.2.7→7.2.6, 7.2.8→7.2.7, 7.2.9→7.2.8. All in-document cross-references (§2 Trigger, §3 Pre-conditions, §4 Post-conditions, §5 Basic Flow, §8 Business Rules) and the UC_7.1-7.6 index updated to match. 8 BRs total.BA instruction, 2026-10-08 (total_payout = $0 proceeds — client-confirmed)
2026-10-08v1§2, §3, §8 (old BR_7.2.4, BR_7.2.5 removed; BR_7.2.4→BR_7.2.8 renumbered)8 BRs total (BR_7.2.1→BR_7.2.8), including BR_7.2.4 ("Table A/B lookup key isCurrent_Level, exact grid values still pending the original spreadsheet") and BR_7.2.5 ("One account per trader, one asset class per account").Old BR_7.2.4 and BR_7.2.5 removed per BA instruction — dropped as standalone rules. The Current_Level lookup-key detail is kept inline in (new) BR_7.2.3's own text (without its own numbered rule or the open-spreadsheet flag); the one-account-per-trader fact is no longer stated as a numbered BR (P-3's wording kept as plain pre-condition text instead of citing a BR). Remaining BRs renumbered: old BR_7.2.6→new BR_7.2.4 ("Do Not Pay" list out of scope), old BR_7.2.7→new BR_7.2.5 (no race window), old BR_7.2.8→new BR_7.2.6 (Defense mode does not trigger payout). All in-document cross-references (§2 Trigger, §3 Pre-conditions, §8 Business Rules) updated to match. 6 BRs total (BR_7.2.1→BR_7.2.6).BA instruction, 2026-10-08

On this page