StackTrading Docs

SRS: Stage 3 KYC & Live Onboarding — UC_5.7: Flow 3G Market Data Payment

FieldValue
BA in Chargelinh.nguyen34
Date Created2026-08-08
Versionv1.6
Document ReferencesZapier Integration V7.pdf (Flow 3G lines 1251–1264; Flow 22 lines 2177–2215; Email Table D1 lines 730–732; Users table schema lines 339–352) · RFQ_ Stack Trading Prop Tech V7.pdf (Process Payment Webhook endpoint lines 1335–1373; Toggle Market Data endpoint lines 1218–1222; Generate Data Invoices endpoint lines 1575–1595; Get Market Data Status endpoint lines 1493–1498; Calculate Data Refund endpoint lines 1985–2000; customer_vault_id lines 1592–1595) · RFQ_ Website and Dashboard Implementation V7.pdf (Market Data Management UI lines 596–635; Market Data Lifecycle Disclosure lines 342–350; Step 7 Processing lines 506–512)

UC Index

UC_IDUse Case NameBusiness Description
UC_5.7Flow 3G — Market Data PaymentHandles the payment confirmation webhook from the payment processor after a Futures trader selects Option B (premium add-on feeds) in Flow 3F. On payment success: backend sets market_data_paid_until, pushes NEW_PAYMENT_SUCCESS event; Zapier Flow 3G sets setup_status = 'Complete', market_data_billable = True, evaluates the dual aggregation gate for Flow 3H. On recurring monthly billing failure (Flow 22 failure path): deactivates add-on feeds (NYMEX/CBOT/COMEX) via Rithmic API, keeps base CME feed active (firm-paid), sets market_data_billable = False, notifies the trader.

Changelog

DateVersionUpdated itemBeforeAfterNotes
2026-08-08v1Initial creationCreated SRS for UC_5.7 (Flow 3G)First authoring pass
2026-08-08v1.1Cross-check vs RFQ_ Stack Trading Prop Tech V7.pdfMultiple gaps and inaccuracies(1) Added backend Process Payment Webhook intermediary step between payment processor and Zapier; (2) Added market_data_paid_until field set by backend on MARKET_DATA payment; (3) Corrected Reactivate button to use POST /toggle-market-data (not POST /execute-checkout); (4) Added Inactive_Hold status for feed-paused traders; (5) Added GET /market-data-status endpoint and market_data_flags JSON field; (6) Added Calculate Data Refund endpoint to BR_5.7.7 Level 3 flow; (7) Clarified market_data_flags (JSON) vs market_data_billable (Zapier operational field)Source: RFQ_ Stack Trading Prop Tech V7.pdf §Process Payment Webhook, §Get Market Data Status, §Calculate Data Refund, §Toggle Market Data
2026-08-10v1.2Q12: Tiered billing formula resolved — conflict flag removed; BR_5.7.9 updated with confirmed authoritative formula⚠️ Source conflict flag (Zapier V7 summary vs RFQ V7 tiered spec)Formula confirmed: Level 1 & 2 = Total_Market_Data_Cost; Level 3+ = Total − Base_CME_Data_CostQnA STAGE3-013 confirmed 2026-08-10
2026-08-11v1.3Q4: Last_Data_Payment_Status reset confirmed — atomic reset at reactivation payment is mandatory; BR_5.7.13 added; §4, §5 Step 2c, §6 Reactivate Alt Flow updatedLast_Data_Payment_Status reset timing undefinedReset MUST occur atomically alongside Market_Data_Billable = True and market_data_paid_until at reactivation payment — deferring to next billing cycle causes State-Machine Lockout double-deactivation bugQnA STAGE3-031 confirmed 2026-08-11
2026-08-11v1.4Q13: T365/CR-20260730-001 flagged as [UNVERIFIED IN V7]; BR_5.7.11 reframed as universal gateway mandate; BR_5.7.12 updated to include correlation_idT365 treated as NMI equivalent (unverified assumption)T365 not documented in V7 specs; mandate reframed: ALL gateways must pass user_id/product_id/addon_ids in metadata; all gateways must support HMAC/JWS + IP allowlisting + provider_event_id + correlation_idQnA STAGE3-032 confirmed 2026-08-11
2026-08-12v1.6§5 Sub-flow A Step 2: market_data_flags write added to atomic transaction; BR_5.7.8 updated — market_data_flags written by Node.js middleware only (not Zapier); webhook security BR_5.7.12 cross-reference added to §8market_data_flags writer undocumented (Q1 open); BR_5.7.8 listed writer as "Backend / Zapier"Confirmed (STAGE3-047): Node.js middleware writes market_data_flags JSON column atomically with setup_status = 'Complete' and market_data_billable = True at Process Payment Webhook. Zapier does NOT write this field. BR_5.7.12 already present — security mandate note added to BR_5.7.8.STAGE3-047 confirmed 2026-08-12; Q8/STAGE3-016 confirmed 2026-08-10
2026-08-16v1.7§3 Pre-conditions Sub-flow A"payment link was emailed to trader" / "Trader completed checkout on payment processor's hosted page"Payment completed on Stack Trading dashboard widget — no email sent (STAGE3-042 / UC_5.5 v1.8).
2026-08-12v1.5Q2: LIVE_DATA_UPGRADE vs MARKET_DATA product_id clarified — two distinct identifiers, explicit backend routing required; BR_5.7.2 routing table updated; §2 Trigger scope note updatedproduct_id = "MARKET_DATA" was the only routing key documented; LIVE_DATA_UPGRADE was unclear at webhook stageBoth are confirmed distinct. LIVE_DATA_UPGRADE = one-time onboarding checkout (Flow 3F Option B → checkout initiation). MARKET_DATA = recurring subscription and reactivation (webhook callback to Process Payment Webhook). Backend MUST configure explicit routing for both to avoid broken flows.QnA STAGE3-033 confirmed 2026-08-12

Glossary

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


UC_5.7 — Flow 3G: Market Data Payment (Futures Only)

1. Overview

FieldContent
IDUC_5.7
Use CaseFlow 3G — Market Data Payment
DescriptionThis UC covers two coupled payment-handling paths for Futures-only market data add-on billing. Sub-flow A (Initial Payment Confirmation — Flow 3G): Triggered when the payment processor sends a webhook after the trader completes the Option B checkout initiated by Flow 3F. The backend Process Payment Webhook endpoint ingests the webhook first — it extracts customer_vault_id, updates market_data_paid_until = current_date + 1 Month, audits to the invoices table, and pushes NEW_PAYMENT_SUCCESS to Zapier. Zapier Flow 3G then sets setup_status = 'Complete' and market_data_billable = True, and re-evaluates the dual aggregation gate — if contract_status = 'Signed', Flow 3H (live provisioning) is triggered. Sub-flow B (Recurring Monthly Billing Failure — Flow 22 failure path): Triggered via the INVOICE_PAYMENT_FAILED event pushed by Middleware to Zapier when NMI recurring charge fails. The End-of-Month hard check (Day 0) calls POST /toggle-market-data to disable additional exchange feeds (NYMEX, CBOT, COMEX) via Rithmic API, keeps the base CME feed active (firm-paid), sets market_data_billable = False, and sends the Data_Feed_Downgraded email. The trader may reactivate via the Dashboard "Reactivate" button (POST /toggle-market-data, enable_data: true) or purchase new add-ons via "Manage Add-ons" (POST /execute-checkout).
Zapier FlowFlow 3G (Market Data Payment Handler — Futures Only) · Flow 22 (Monthly Data Fee Billing failure path)
Backend EndpointProcess Payment Webhook (POST — ingests NMI/T365 webhook, routes by product_id, sets market_data_paid_until, pushes NEW_PAYMENT_SUCCESS) · POST /toggle-market-data (Rithmic feed toggle: disable on EOM hard check; re-enable on Reactivate) · POST /generate-invoices (Middleware monthly batch — initiates Sub-flow B) · POST /execute-checkout (Dashboard Manage Add-ons re-purchase) · GET /market-data-status (read feed status per exchange)
Zapier TableUsers table (setup_status, market_data_billable, market_data_flags JSON, market_data_paid_until, Last_Data_Payment_Status, customer_vault_id)
3rd PartyZapier (Flow 3G, Flow 22) · NMI / T365 (payment vault charge; customer_vault_id saved on first payment) · Rithmic API (feed enable/disable via Toggle Market Data endpoint) · AWS SES (Urgent_Data_Payment_Required, Data_Feed_Downgraded, Monthly_Data_Invoice_Available emails)

Scope note — Futures only: Both sub-flows apply exclusively to Asset_Class = 'Futures' traders. Forex traders have setup_status = 'N/A' and are not in the market_data_billable = True cohort.

Scope note — two billing contexts: Sub-flow A is a one-time initial payment confirmation at the start of live phase (triggered by Flow 3F Option B). Sub-flow B is the recurring monthly billing failure path (triggered by Flow 22 scheduled job).

Scope note — payment webhook routing: The payment processor webhook does NOT go directly to Zapier. It hits the backend Process Payment Webhook endpoint first, which routes by product_id. The backend MUST configure explicit routing for BOTH product identifiers used in the market data billing pipeline — they are distinct and operate at different pipeline stages (confirmed STAGE3-033):

product_id valuePipeline stageContext
'LIVE_DATA_UPGRADE'Checkout initiation — Flow 3F Option BUsed when Flow 3F calls POST /initiate-checkout to generate the one-time onboarding payment link for the trader. This is the product_id the payment gateway receives at checkout creation.
'MARKET_DATA'Payment webhook callback — Flow 3G / Flow 22Used when the payment gateway sends the webhook to Process Payment Webhook after successful payment. Backend routes on this identifier to set market_data_paid_until = current_date + 1 Month and push NEW_PAYMENT_SUCCESS to Zapier. Also used for recurring monthly billing (Flow 22) and reactivation payments.

Why both must be routed: LIVE_DATA_UPGRADE is set by Stack Trading at checkout initiation; MARKET_DATA is the webhook-stage identifier in the payment gateway's response. If backend only handles MARKET_DATA, onboarding traders who pay via LIVE_DATA_UPGRADE will have their webhook unrecognised — setup_status stays 'Pending_Payment' permanently and Flow 3H is never triggered. If backend only handles LIVE_DATA_UPGRADE, recurring monthly billing via MARKET_DATA will fail to update market_data_paid_until — traders lose feeds incorrectly. (Source: RFQ_ Stack Trading Prop Tech V7.pdf §Process Payment Webhook lines 1335–1373; QnA STAGE3-033 confirmed 2026-08-12)

Scope note — market_data_flags vs market_data_billable: The Users table schema (zapier_v7_full.txt line 339) defines market_data_flags (JSON/Object) as the authoritative field storing per-exchange entitlement state. market_data_billable (Boolean) is the Zapier operational flag that controls Flow 22 billing inclusion. market_data_paid_until (Date) is set by the backend on each successful MARKET_DATA payment and read by GET /market-data-status to return Active/Inactive/Available per feed. All three coexist.


2. Trigger

Sub-flow A — Flow 3G (Initial Option B Payment Confirmation): Two-step trigger chain:

  1. Payment processor (NMI / T365) sends payment webhook to the backend Process Payment Webhook endpoint. Backend extracts customer_vault_id, routes on product_id = "MARKET_DATA", sets market_data_paid_until = current_date + 1 Month, inserts record to invoices table with fee_type = 'MARKET_DATA_ADDON', then pushes NEW_PAYMENT_SUCCESS event to Zapier.
  2. Zapier Flow 3G triggers on the NEW_PAYMENT_SUCCESS event, reads addon_ids from the event metadata (passed through from NMI/T365 custom metadata fields), and executes the DB writes and gate check.

Note: addon_ids and product_id metadata MUST be configured on NMI/T365 to pass through the payment payload to the webhook catcher, so both backend and Zapier can parse the add-on selection. (Source: RFQ_ Stack Trading Prop Tech V7.pdf lines 1555–1558)

Sub-flow B — Flow 22 failure path (Recurring Monthly Billing Failure): Two-stage trigger:

  1. INVOICE_PAYMENT_FAILED event pushed by Middleware to Zapier when NMI recurring charge against customer_vault_id fails during the monthly billing run (~3 days before EOM).
  2. End-of-Month hard check (Day 0 scheduled job): query SQL for Market_Data_Billable = True AND Last_Data_Payment_Status = Failed → proceeds to feed deactivation.

3. Pre-conditions

Sub-flow A:

  • Asset_Class = 'Futures' for user_id.
  • Flow 3F Option B has been executed: setup_status = 'Pending_Payment' in Users table.
  • POST /initiate-checkout was called in Flow 3F; payment link was emailed to trader payment completed on the Stack Trading dashboard (no email sent — STAGE3-042 / UC_5.5 v1.8 2026-08-14).
  • Trader has completed the checkout on the dashboard payment widget.
  • Payment processor sends webhook to backend Process Payment Webhook endpoint.
  • Backend routes on product_id = "MARKET_DATA" and pushes NEW_PAYMENT_SUCCESS to Zapier.

Sub-flow B:

  • Asset_Class = 'Futures' for user_id.
  • market_data_billable = True and Status = 'Active' in Users table.
  • Flow 22 monthly billing run has executed; NMI charge against customer_vault_id has failed.
  • Middleware has pushed INVOICE_PAYMENT_FAILED event to Zapier.
  • End-of-Month Day 0 scheduled job has detected Last_Data_Payment_Status = Failed.

4. Post-conditions

Sub-flow A — On payment success:

  • market_data_paid_until = current_date + 1 Month set by backend (before Zapier fires).
  • setup_status = 'Complete' in Users table (set by Zapier Flow 3G).
  • market_data_billable = True in Users table (set by Zapier Flow 3G).
  • invoices table: new record inserted with fee_type = 'MARKET_DATA_ADDON', status = 'paid'.
  • Aggregation gate evaluated: IF contract_status = 'Signed' → Flow 3H (UC_5.8) triggered via internal webhook.
  • IF contract_status ≠ 'Signed': Zap terminates; Flow 3H triggered by Flow 3E when contract is signed.

Sub-flow A — On Reactivation payment success (trader paying overdue invoice):

  • Process Payment Webhook receives webhook with product_id = 'MARKET_DATA'.
  • Middleware executes a single atomic DB transaction writing ALL of the following simultaneously:
    • market_data_paid_until = current_date + 1 Month
    • Market_Data_Billable = True
    • Last_Data_Payment_Status = NULL (cleared)
  • System calls POST /toggle-market-data with enable_data = True → Rithmic API re-enables NYMEX/CBOT/COMEX feeds.
  • Dashboard feed status returns to Green "Active"; "Reactivate" button disabled.

Note: The atomic reset of Last_Data_Payment_Status to NULL at reactivation is mandatory. If deferred, the next EOM Day 0 hard check reads Market_Data_Billable = True AND Last_Data_Payment_Status = 'Failed' and re-deactivates feeds despite the trader having paid — a State-Machine Lockout bug. See BR_5.7.13.

Sub-flow B — On initial payment failure notification (before EOM hard check):

  • Last_Data_Payment_Status = Failed flagged in DB.
  • Urgent_Data_Payment_Required email sent to trader via AWS SES.
  • Ops Slack notification sent.
  • Feeds remain active during grace period.

Sub-flow B — On End-of-Month hard check (payment failure confirmed):

  • POST /toggle-market-data called: Rithmic API disables additional exchange feeds (NYMEX, CBOT, COMEX). Base CME feed NOT toggled — remains active.
  • market_data_billable = False in Users table.
  • Feed status transitions to Inactive_Hold — visible in Dashboard as Grey "Paused" badge.
  • Data_Feed_Downgraded email sent to trader via AWS SES.
  • Trader may reactivate via Dashboard (see §6 Alternative Flow).

5. Basic Flow

Sub-flow A — Flow 3G: Initial Option B Payment Confirmation

  1. Payment processor sends webhook to backend Process Payment Webhook endpoint.
  2. Backend ingests webhook:
    • 2a. IF NMI payload: extract and save customer_vault_id to Users table.
    • 2b. Extract product_id and user_id from payload.
    • 2c. Route on product_id = "MARKET_DATA": execute single atomic DB transaction writing:
      • market_data_paid_until = current_date + 1 Month
      • market_data_flags JSON column: write per-exchange Active/Inactive flags by parsing addon_ids from gateway metadata (e.g. NYMEX_Bundle → nymex: true, CBOT_Bundle → cbot: true). This is the authoritative write for market_data_flags — Zapier does NOT write this field (confirmed STAGE3-047). All three fields written atomically: partial writes not permitted.
      • Last_Data_Payment_Status = NULL (if this is a Reactivation payment; see BR_5.7.13)
      • Market_Data_Billable = True (if this is a Reactivation payment; see BR_5.7.13)
    • 2d. Insert record to invoices table: fee_type = 'MARKET_DATA_ADDON', status = 'paid'.
    • 2e. Push NEW_PAYMENT_SUCCESS event (with full metadata including addon_ids) to Zapier.
    • 2f. Broadcast PAYMENT_RESULT event (status = SUCCESS) via WebSocket/Redis to client.
  3. Zapier Flow 3G triggers on NEW_PAYMENT_SUCCESS event.
  4. Zapier UPDATE Users table WHERE user_id = event.user_id:
    • setup_status = 'Complete'
    • market_data_billable = True
  5. Aggregation gate check: Zapier queries contract_status WHERE user_id.
    • IF contract_status = 'Signed' → fire internal webhook to trigger Flow 3H (UC_5.8).
    • ELSE → Zap terminates; wait for Flow 3E (contract signing will re-evaluate the gate).

Sub-flow B — Flow 22 Monthly Billing Failure Path

Phase 1 — Monthly billing run (~3 days before EOM):

  1. Scheduled job triggers Flow 22. Middleware calls POST /generate-invoices with billing_cycle_date.
  2. Middleware queries DB: Status = 'Active' AND Asset_Class = 'Futures' AND Market_Data_Billable = True.
  3. For each trader in scope: calculate Invoice_Amount using tiered formula (per BR_5.7.6).
  4. Query DB for active MIDs. Retrieve customer_vault_id array. Execute batch NMI charges using Weighted Round-Robin algorithm (weighted by remaining MID capacity).
  5. IF charge fails:
    • Flag Last_Data_Payment_Status = Failed in DB.
    • Push INVOICE_PAYMENT_FAILED event to Zapier.
    • Zapier sends Urgent_Data_Payment_Required email to trader via AWS SES + Ops Slack notification.
    • Feeds remain active during grace period.

Phase 2 — End-of-Month hard check (Day 0 scheduled job):

  1. Scheduled job runs on last day of month.
  2. Query SQL: Market_Data_Billable = True AND Last_Data_Payment_Status = Failed.
  3. For each trader in this state:
    • Call Middleware POST /toggle-market-data with user_id, enable_data = False → Middleware calls Rithmic Broker API to disable additional feeds (NYMEX/CBOT/COMEX) only. Base CME feed NOT toggled.
    • UPDATE Users table: market_data_billable = False.
    • Feed status becomes Inactive_Hold.
    • Send Data_Feed_Downgraded email to trader via AWS SES.

6. Alternative Flow

  • [Contract already signed when Sub-flow A payment webhook arrives]

    • contract_status = 'Signed' found at gate check Step 5.
    • Flow 3H triggered immediately in this Zap execution with market_data_billable = True.
    • Flow 3H provisions Professional Market Data + Add-ons via Rithmic API.
  • [Contract not yet signed when Sub-flow A payment webhook arrives]

    • contract_status ≠ 'Signed': Zap terminates.
    • When Flow 3E later processes the signed contract, it finds setup_status = 'Complete' and triggers Flow 3H at that time.
  • [Trader reactivates feeds after Sub-flow B downgrade — Dashboard Reactivate button]

    • Dashboard shows feed status as Inactive_Hold (Grey "Paused" badge).
    • Trader clicks "Reactivate" button (enabled only when status = Inactive_Hold).
    • Frontend calls POST /toggle-market-data with enable_data: true.
    • On success: "Success" toast displayed; connection credentials card refreshed; feed status returns to Green "Active".
    • Middleware simultaneously executes atomic DB transaction: market_data_paid_until = current_date + 1 Month, Market_Data_Billable = True, Last_Data_Payment_Status = NULL. All three writes in one transaction — partial writes not permitted. (See BR_5.7.13)
    • (Source: RFQ_ Website and Dashboard Implementation V7.pdf Market Data Management lines 599–608)
  • [Trader purchases new/additional add-ons — Dashboard Manage Add-ons button]

    • Trader clicks "Manage Add-ons" (Button 2, distinct from Reactivate).
    • Frontend calls GET /market-data-products (authenticated) — returns only products the trader does NOT currently have active.
    • Trader selects desired exchange feeds; 1-Click Confirmation Modal rendered ("Total: $[Amount]", "Pay with vaulted card").
    • Frontend calls POST /execute-checkout with product_id = 'MARKET_DATA', addon_ids = [selected_ids], payment_method = 'CC', user_id.
    • Backend executes charge against customer_vault_id (no re-entry of card details).
    • On success: "Feeds Activated" toast; account state refreshed.
    • Payment webhook → backend Process Payment Webhook → sets market_data_paid_until = current_date + 1 Month → pushes NEW_PAYMENT_SUCCESS → Zapier re-sets market_data_billable = True if needed.
    • (Source: RFQ_ Website and Dashboard Implementation V7.pdf lines 607–635)
  • [Level 3+ trader promotion — firm resumes full data cost coverage]

    • At Level 3 promotion, Promotion_Level_3 Klaviyo event fires — includes "data fee refund status".
    • Backend calculates refundable amount via GET /financial/calculate-data-refund: sums invoices.amount WHERE fee_type = 'MARKET_DATA_BASE' AND status = 'paid' for Level 1 & 2 period. Excludes add-on fees (non-refundable).
    • After Level 3 promotion, Market Data Lifecycle Disclosure confirms: "Level 3 to Level 24: The Firm pays 100% of data costs."
    • market_data_billable transitions to False at promotion. Exact Zapier flow step setting this is [MISSING] from Flow 3G source — likely in the Level-Up/Promotion flow.
    • (Source: RFQ_ Website and Dashboard Implementation V7.pdf lines 342–350; RFQ_ Stack Trading Prop Tech V7.pdf §Calculate Data Refund lines 1985–2000; Zapier Integration V7.pdf Promotion_Level_3 line 756)

7. Exceptional Flow

  • [Sub-flow A — NEW_PAYMENT_SUCCESS event received for unknown user_id]

    • [MISSING] — no handling documented if the event contains a user_id not in the Users table. Should Zapier filter halt silently or alert Ops?
  • [Sub-flow A — duplicate NEW_PAYMENT_SUCCESS event (re-delivery)]

    • Backend enforces provider_event_id deduplication: if Event_ID already exists in DB → HALT (zapier_v7_full.txt line 872).
    • Zapier-level dedup: [MISSING] — whether Flow 3G separately checks provider_event_id before re-writing setup_status is not documented in zapier source.
  • [Sub-flow A — payment processor sends webhook but backend Process Payment Webhook is unreachable]

    • [MISSING] — no retry or dead-letter queue documented for failed webhook delivery to the backend endpoint. Trader's market_data_paid_until and setup_status would not be updated.
  • [Sub-flow B — POST /toggle-market-data call to Rithmic fails on EOM Day 0]

    • [MISSING] — if the Rithmic API call to disable add-on feeds fails, the trader continues receiving feeds without payment. No retry or Ops escalation path documented for this specific failure.
  • [Sub-flow B — trader has no vaulted customer_vault_id for Manage Add-ons re-purchase]

    • [MISSING] — if the trader's vaulted card is expired or deleted, POST /execute-checkout fails on the vaulted charge. No fallback for entering a new payment method in this context is documented.
  • [Sub-flow B — INVOICE_PAYMENT_FAILED event never received (Middleware silent failure)]

    • [MISSING] — if Middleware fails to push the event, Zapier never fires the Urgent_Data_Payment_Required email. The only safety net is the Day 0 hard check. No monitoring alert for missing events is documented.

8. Business Rules

BR_5.7.1: Futures-Only Scope

Flow 3G and the Flow 22 failure path apply exclusively to Asset_Class = 'Futures' traders. Forex traders are not subject to Rithmic market data billing.

(Source: Zapier Integration V7.pdf Flow 3G line 1251; Flow 22 line 2179)

BR_5.7.2: Backend Processes Payment Webhook Before Zapier — Dual product_id Routing Required

The payment processor webhook hits the backend Process Payment Webhook endpoint first — not Zapier directly. The backend:

  1. Validates the webhook signature.
  2. Extracts and saves customer_vault_id (if NMI payload).
  3. Routes on product_id: for "MARKET_DATA" → sets market_data_paid_until = current_date + 1 Month.
  4. Inserts invoices record with fee_type = 'MARKET_DATA_ADDON'.
  5. Pushes NEW_PAYMENT_SUCCESS event to Zapier.
  6. Broadcasts PAYMENT_RESULT to client via WebSocket/Redis.

Zapier Flow 3G triggers on the NEW_PAYMENT_SUCCESS event, not directly on the payment processor webhook.

Mandatory dual routing — LIVE_DATA_UPGRADE AND MARKET_DATA (confirmed STAGE3-033):

LIVE_DATA_UPGRADE and MARKET_DATA are two distinct identifiers operating at different pipeline stages. Backend MUST configure explicit handling for both:

product_idWhen setWho sets itWhat backend must do on receipt
'LIVE_DATA_UPGRADE'At checkout initiationFlow 3F calls POST /initiate-checkoutRoute to onboarding payment processing; update setup_status-related fields via Flow 3G
'MARKET_DATA'At payment webhook callbackPayment gateway sends in webhookSet market_data_paid_until = current_date + 1 Month; push NEW_PAYMENT_SUCCESS to Zapier; handle reactivation atomic reset (BR_5.7.13)

Risk if routing is incomplete:

  • If backend only handles MARKET_DATA: onboarding payment webhook with product_id = 'LIVE_DATA_UPGRADE' is not recognised → setup_status stays 'Pending_Payment' indefinitely → Flow 3H never triggered → trader permanently blocked from live provisioning.
  • If backend only handles LIVE_DATA_UPGRADE: recurring monthly MARKET_DATA payments fail to update market_data_paid_until → feeds incorrectly deactivated on the next EOM hard check.

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

BR_5.7.3: Zapier Flow 3G Writes setup_status and market_data_billable

After the backend pushes NEW_PAYMENT_SUCCESS, Zapier Flow 3G writes two fields:

  • setup_status = 'Complete' — satisfies the setup leg of the Flow 3H dual aggregation gate.
  • market_data_billable = True — enrolls the trader in monthly Flow 22 billing.

Both writes occur before the aggregation gate check.

(Source: Zapier Integration V7.pdf Flow 3G lines 1254–1261)

BR_5.7.4: Flow 3H Provisioning Branches on market_data_billable

When Flow 3H (UC_5.8) is triggered after Sub-flow A, provisioning branches on this flag:

  • market_data_billable = True: Provision Professional Market Data + Add-ons via Rithmic API.
  • market_data_billable = False (Option A traders): Provision Standard Data (Firm Covered) as Professional.

(Source: Zapier Integration V7.pdf Flow 3H lines 1281–1283)

BR_5.7.5: Two-Stage Failure Response — Grace Period Then Hard Deactivation

Monthly billing failure does NOT immediately deactivate feeds:

StageTimingAction
Phase 1 — Soft failure~3 days before EOM (billing run)Flag Last_Data_Payment_Status = Failed; send Urgent_Data_Payment_Required email + Ops Slack; feeds remain active
Phase 2 — Hard deactivationDay 0 (last day of month)Disable NYMEX/CBOT/COMEX via POST /toggle-market-data; set market_data_billable = False; feed status = Inactive_Hold; send Data_Feed_Downgraded email

The grace period gives the trader time to update payment before hard deactivation.

(Source: Zapier Integration V7.pdf Flow 22 lines 2192–2204)

BR_5.7.6: Base CME Feed Preserved on Deactivation

When Phase 2 hard deactivation runs, ONLY add-on feeds (NYMEX, CBOT, COMEX) are disabled. The base CME feed (1 Level 2 feed, Base_CME_Data_Cost = $140/month) remains active — firm-paid regardless of trader payment status.

The POST /toggle-market-data call targets add-on feeds only.

(Source: Zapier Integration V7.pdf Flow 22 lines 2200–2203)

BR_5.7.7: Inactive_Hold Status and Reactivate Button

After EOM hard deactivation, the trader's feed state becomes Inactive_Hold. The Dashboard shows a Grey "Paused" badge. The "Reactivate" button (Button 1 in Market Data Management) is only enabled when status = Inactive_Hold.

  • Reactivate action: POST /toggle-market-data with enable_data: true → Middleware calls Rithmic API to re-enable feeds.
  • On success: "Success" toast; connection credentials card refreshed.

This is distinct from the "Manage Add-ons" button (Button 2), which purchases new/additional feeds via POST /execute-checkout.

(Source: RFQ_ Website and Dashboard Implementation V7.pdf Market Data Management lines 599–608; RFQ_ Stack Trading Prop Tech V7.pdf Toggle Market Data endpoint lines 1218–1222)

BR_5.7.8: market_data_flags, market_data_billable, and market_data_paid_until — Three Coexisting Fields

FieldTypeSet byPurpose
market_data_flags (JSON/Object)JSONNode.js middleware only — written atomically at Process Payment Webhook by parsing addon_ids from gateway metadata (confirmed STAGE3-047). Zapier does NOT write this field.Per-exchange entitlement state; evaluated by GET /market-data-status to return Active/Inactive/Available per feed (CME, CBOT, NYMEX, COMEX)
market_data_billable (Boolean)BooleanZapier (Flow 3F/3G/22)Controls whether Flow 22 includes this trader in monthly invoice batch
market_data_paid_until (Date)DateBackend (Process Payment Webhook)Tracks payment expiry per billing cycle; used with market_data_flags by GET /market-data-status

Security: Process Payment Webhook enforces three-layer webhook security per BR_5.7.12 (HMAC/JWS signature verification + IP allowlisting + idempotency via provider_event_id + correlation_id). The three-field atomic write is part of the same secure transaction.

(Source: Zapier Integration V7.pdf Users table schema line 339; RFQ_ Stack Trading Prop Tech V7.pdf §Get Market Data Status lines 1493–1498; §Process Payment Webhook line 1360)

BR_5.7.9: Tiered Monthly Invoice Formula

Flow 22 applies the following tiered formula when generating invoices for market_data_billable = True traders:

Trader levelInvoice formula
Level 1 & Level 2 (Provisional / Math)Invoice_Amount = Total_Market_Data_Cost (full cost — firm does NOT cover CME base at Level 1/2)
Level 3+ (Senior)Invoice_Amount = Total_Market_Data_Cost - Base_CME_Data_Cost ($140) (firm covers CME base from Level 3+)

Consistent with GET /financial/calculate-data-refund: at Level 3 promotion, backend refunds only MARKET_DATA_BASE fees paid during Level 1 & 2 (confirming those were trader-paid).

Source resolution: Zapier Integration V7.pdf Flow 22 lines 2186–2187 showed only Total − Base_CME (shorthand for Level 3+ formula). The detailed "Perks & Batch Process Endpoints" section in the same Zapier V7 document explicitly states the tiered logic, consistent with RFQ_ Stack Trading Prop Tech V7.pdf lines 1585–1590. Conflict resolved — confirmed by client 2026-08-10 (QnA STAGE3-013).

(Source: Zapier Integration V7.pdf §Perks & Batch Process Endpoints — tiered billing logic; RFQ_ Stack Trading Prop Tech V7.pdf lines 1575–1595; QnA STAGE3-013 confirmed 2026-08-10)

BR_5.7.10: Level 3 Promotion — Firm Resumes Full Data Cost Coverage and Refund

At Level 3 promotion:

  • Market Data Lifecycle Disclosure: "Level 3: Trader is 100% reimbursed for Level 1 and 2 market data costs incurred. Level 3 to Level 24: Firm pays 100% of data costs."
  • Backend endpoint GET /financial/calculate-data-refund calculates the refundable amount: SUM(invoices.amount) WHERE fee_type = 'MARKET_DATA_BASE' AND status = 'paid' for the trader's Level 1 & 2 period. Add-on fees (NYMEX/CBOT/COMEX) and platform fees are excluded — non-refundable.
  • After Level 3, market_data_billable transitions to False. The exact Zapier flow step that sets this is [MISSING] from Flow 3G source — likely in the Level-Up/Promotion flow (UC for level promotion, not UC_5.7).

(Source: RFQ_ Website and Dashboard Implementation V7.pdf Market Data Lifecycle Disclosure lines 342–350; RFQ_ Stack Trading Prop Tech V7.pdf §Calculate Data Refund lines 1985–2000)

BR_5.7.11: Universal Metadata Mandate — All Payment Gateways

⚠️ Source note: "T365" and "CR-20260730-001" referenced in the original audit question are not documented or mentioned anywhere in the V7 architecture specifications. Their specific payload schema and webhook auth cannot be verified from current source materials. The following mandate applies to ALL gateways per V7 §1.3 Vendor Requirements & Scalability — including any future replacement aggregator.

Regardless of which payment gateway processes a transaction (NMI, Triple-A, Skrill, Nomupay, EBANX, Dusupay, or any future/replacement gateway), the custom metadata attached to each payment MUST be structurally identical. The middleware Process Payment Webhook endpoint and downstream Zapier automation chains (Flow 1, Flow 22) are hardcoded to parse the exact same custom fields:

FieldTypePurpose
user_idUUIDMaps transaction to correct PostgreSQL profile
product_idStringIdentifies transaction type ('EVAL_L1', 'LIVE_DATA_UPGRADE', 'MARKET_DATA', 'RESET', 'REBUY')
addon_idsArrayPurchased premium exchange feeds (e.g. ['NYMEX_Bundle', 'CBOT_Bundle'])

If a gateway does not natively support custom metadata dictionaries, or fails to pass these exact keys through its payment webhook payload, Process Payment Webhook will fail to parse the payment and automated onboarding/billing systems will break entirely.

(Source: RFQ_ Stack Trading Prop Tech V7.pdf lines 1555–1558; Zapier Integration V7.pdf line 2691; V7 §1.3 Vendor Requirements & Scalability; QnA STAGE3-032 confirmed 2026-08-11)

BR_5.7.12: Webhook Security Mandate — All Payment Gateways

Per V7 §1.3 Vendor Requirements & Scalability, ALL payment gateways integrated into the Stack Trading ecosystem must comply with the following security standards:

RequirementDetail
Signed Webhook Verification (HMAC/JWS)Middleware receiver endpoint MUST cryptographically validate the incoming payload signature using a securely stored gateway secret — comparable to Veriff and Trustpilot webhook validation
IP Address AllowlistingWhen supported by the provider, inbound IP ranges MUST be explicitly allowlisted at the Cloudflare reverse proxy/WAF or AWS Ingress layer to block spoofed/malicious traffic
Idempotency EnforcementEach webhook MUST carry both a unique provider_event_id (or transactional event_id) AND a correlation_id — both are required for the DB event-log to prevent double-charging or duplicate account provisioning on gateway re-transmission

The backend Process Payment Webhook endpoint enforces idempotency: if provider_event_id already exists in DB → HALT, no re-processing.

(Source: Zapier Integration V7.pdf lines 872, 2700; V7 §1.3 Vendor Requirements & Scalability; QnA STAGE3-032 confirmed 2026-08-11)

BR_5.7.13: Atomic Reset of Last_Data_Payment_Status on Reactivation Payment

When a trader in Inactive_Hold state (EOM hard-deactivated) pays their overdue invoice, the backend Process Payment Webhook endpoint MUST execute a single atomic DB transaction that writes ALL of the following simultaneously:

FieldValue setRequired
market_data_paid_untilcurrent_date + 1 MonthYES
Market_Data_BillableTrueYES
Last_Data_Payment_StatusNULL (or 'Paid'/'Success')YES — atomic with above

Simultaneously, system calls POST /toggle-market-data with enable_data = True to re-enable NYMEX/CBOT/COMEX feeds via Rithmic API.

Why atomic reset is mandatory — State-Machine Lockout prevention:

The EOM Day 0 hard check queries: Market_Data_Billable = True AND Last_Data_Payment_Status = 'Failed'.

If Last_Data_Payment_Status is NOT cleared at reactivation:

  • At next EOM: Market_Data_Billable = True (restored) AND Last_Data_Payment_Status = 'Failed' (stale) → hard check condition is met again.
  • System re-deactivates the trader's feeds despite them having paid — a false double-deactivation.

Partial writes are not permitted. All three fields must succeed or the transaction rolls back entirely.

(Source: QnA STAGE3-031 confirmed 2026-08-11)


9. Wireframe / UI

WBS status_design = 'Done'. Four screens referenced in WBS mapping_design:

ScreenFigma ReferenceWireframe fileContext
Confirm market data add-onFigma node 1-29891Stage 3: Total wireframe/Flow 3G: Market data checkout.png1-Click Confirmation Modal — "Total: $[Amount]", "Pay with vaulted card"
Change PaymentFigma node 1-30011Update payment method before re-attempting
ProcessingFigma node 1-30247Stage 3: Total wireframe/Flow 3G: Payment loading.pngPayment processing interstitial
SuccessFigma node 1-30345"Feeds Activated" confirmation

Additional Flow 3G wireframes (error/edge states):

ScreenWireframe fileContext
Payment fail popupStage 3: Total wireframe/Flow 3G: Payment fail popup.pngPayment failure modal — error message + retry/change payment options
Market price updated popupStage 3: Total wireframe/Flow 3G: Popup Market price updated .pngPrice-change notification popup — shown when market data price changes before confirmation
Payment methods unavailable popupStage 3: Total wireframe/Flow 3G: Popup Payment methods unavailble.pngSystem popup when no payment method is available to process

All wireframe files are located in: References/Wireframe/Stage 3/Stage 3: Total wireframe/

The backend webhook receipt (Sub-flow A trigger) has no trader-facing UI — it is a server-to-server event. The Dashboard Market Data Management panel displays feed status (Green "Active" / Grey "Paused") and hosts both the Reactivate and Manage Add-ons buttons.

(Source: WBS mapping_design UC_5.7; RFQ_ Website and Dashboard Implementation V7.pdf lines 596–635)


10. Screen Description and Business Rules

Screen 1: 1-Click Confirmation Modal (Confirm Market Data Add-on)

Rendered when trader selects add-ons via "Manage Add-ons" button (Button 2). Overlays the Dashboard.

ElementTypeBehavior
Feed listRead-onlySelected exchange bundles with individual prices
TotalRead-only"Total: $[Amount]" — from GET /market-data-products pricing
Payment methodRead-only"Pay with vaulted card [last 4 digits]"
CTA — ConfirmPrimary buttonCalls POST /execute-checkout with product_id = 'MARKET_DATA', addon_ids, payment_method = 'CC'
Change Payment MethodText linkOpens Screen 2

Business rule: Backend executes against stored customer_vault_id. Frontend must NOT prompt re-entry of card details.

(Source: RFQ_ Website and Dashboard Implementation V7.pdf lines 614–635)

Screen 2: Change Payment (Update Payment Method)

Displayed when trader clicks "Change Payment Method" from Screen 1.

[MISSING] — dashboard_v7_full.txt line 697 references this screen but the continuation is truncated. Full behavior [MISSING] from source.

Screen 3: Processing (Payment Interstitial)

Loading state while POST /execute-checkout is in flight. Pattern consistent with checkout Step 7 (dashboard_v7_full.txt line 509: "Headline (H4): Processing Payment").

Wireframe: Stage 3: Total wireframe/Flow 3G: Payment loading.png

Screen 4: Success (Feeds Activated Confirmation)

ElementTypeBehavior
ToastSuccess"Feeds Activated"
Account stateAuto-refreshNew feeds shown as "Active"; Data Feed Status badge → Green

(Source: RFQ_ Website and Dashboard Implementation V7.pdf lines 628–635)

Screen 5: Payment Fail Popup

Wireframe: Stage 3: Total wireframe/Flow 3G: Payment fail popup.png

Displayed when POST /execute-checkout returns a payment failure. Trader is offered retry or change payment method options.

Screen 6: Market Price Updated Popup

Wireframe: Stage 3: Total wireframe/Flow 3G: Popup Market price updated .png

Displayed when market data pricing changes between the time the trader opens the confirmation modal and the time they confirm. Frontend must re-fetch pricing and display the popup before allowing re-confirmation.

Screen 7: Payment Methods Unavailable Popup

Wireframe: Stage 3: Total wireframe/Flow 3G: Popup Payment methods unavailble.png

Displayed when no payment method is available (e.g., customer_vault_id IS NULL and no fallback active). Trader prompted to add a payment method.


END OF UC_5.7

On this page

UC IndexChangelogGlossaryUC_5.7 — Flow 3G: Market Data Payment (Futures Only)1. Overview2. Trigger3. Pre-conditions4. Post-conditions5. Basic FlowSub-flow A — Flow 3G: Initial Option B Payment ConfirmationSub-flow B — Flow 22 Monthly Billing Failure Path6. Alternative Flow7. Exceptional Flow8. Business RulesBR_5.7.1: Futures-Only ScopeBR_5.7.2: Backend Processes Payment Webhook Before Zapier — Dual product_id Routing RequiredBR_5.7.3: Zapier Flow 3G Writes setup_status and market_data_billableBR_5.7.4: Flow 3H Provisioning Branches on market_data_billableBR_5.7.5: Two-Stage Failure Response — Grace Period Then Hard DeactivationBR_5.7.6: Base CME Feed Preserved on DeactivationBR_5.7.7: Inactive_Hold Status and Reactivate ButtonBR_5.7.8: market_data_flags, market_data_billable, and market_data_paid_until — Three Coexisting FieldsBR_5.7.9: Tiered Monthly Invoice FormulaBR_5.7.10: Level 3 Promotion — Firm Resumes Full Data Cost Coverage and RefundBR_5.7.11: Universal Metadata Mandate — All Payment GatewaysBR_5.7.12: Webhook Security Mandate — All Payment GatewaysBR_5.7.13: Atomic Reset of Last_Data_Payment_Status on Reactivation Payment9. Wireframe / UI10. Screen Description and Business RulesScreen 1: 1-Click Confirmation Modal (Confirm Market Data Add-on)Screen 2: Change Payment (Update Payment Method)Screen 3: Processing (Payment Interstitial)Screen 4: Success (Feeds Activated Confirmation)Screen 5: Payment Fail PopupScreen 6: Market Price Updated PopupScreen 7: Payment Methods Unavailable Popup