Verit Global logo
Verit Global
Back to Industries

Pay marketplace partners without overpays or drift.

Stop overpays on late cancels. End rounding drift on surge/tips. Release only the proven set—tied to fresh Finance/Compliance approvals.

Marketplaces & Gig market hero

Who this is for

Rides / last-mile delivery platforms

Hundreds of thousands to millions of drivers/couriers daily or weekly; surge, bonuses, tips; multi-currency.

Where pain shows up

Rounding drift on surge/tips, re-runs that change cents, refunds after payout → clawbacks, PSP/GL mismatches.

Compliance & audit pressure

Need provable equality and approvals tied to the exact outputs—no ad-hoc evidence packs.

What you get (in plain English)

No rounding drift

Deterministic carry with late quantization—surge/tips stop “moving” on re-run.

Fewer clawbacks

Late cancels/refunds do not mutate prior windows; they land in the next window with reasons.

Cleaner recon

PSP/GL rows tie to window_id + output_digest; auditors verify by replay.

Before → After (at a glance)

Traditional stack & flow (before)

  • Data/compute: Kafka/Kinesis → Spark/Databricks or Snowflake/BigQuery with Airflow/dbt.
  • Logic: SQL/Python aggregates; per-ride rounding; surge/tips modeled ad hoc.
  • Payout rails: Stripe Connect / Adyen for Platforms; ACH/SEPA files.
  • Back office: NetSuite/Oracle; close/recs via BlackLine/Trintech.

Batches release when the “job finished” — not when replay equals the sealed transcript with fresh approvals.

Overlay architecture (after)

  • Deterministic engine: single-writer partitions, fixed fold order, 128-bit integers.
  • Late quantization + carry-ledger: one-time rounding; documented ≤½-unit bound per allocation.
  • Transcript + digest: content-addressed, replayable evidence of equality.
  • Acceptance gate: Finance ACK + CT (+ optional SPV) with freshness & quorum → only ALLOW releases.

How it works (60 seconds)

1) Ingest & compute

Order into single-writer logs; accumulate integers (no FP drift); surge/tips at native precision.

2) Window close

Close under a monotone watermark; fold in a fixed, published order; quantize once; assign carry deterministically.

3) Authorize & disburse

Replay equals transcript digest + approvals fresh/in quorum → ALLOW set releases; HOLDs are reason-coded.

Keep your rails—no rip-and-replace.

Hourly cadence (example)

  • T+0–55m: Ingest & compute deterministically
  • T+55m: Window close (watermark, fold, quantize, carry)
  • T+56m: Authorize(window_id) — equality + acceptance
  • T+57m: Disburse ALLOW; HOLDs reason-coded
  • Next window: Late cancels/refunds land here

Acceptance policy (example)

Required proofs

  • ACK (Finance reserves) — window-level
  • CT (KYC/OFAC/Tax) — principal/cohort-level
  • SPV (optional) — provider receipt/headers

Freshness & quorum

  • Freshness: ACK ≤ 60m; CT ≤ 24h; SPV ≤ 60m
  • Quorum: 2 of 3 (Finance, Compliance, Ops)

If unmet

  • HOLD with reason: STALE_PROOF, INSUFFICIENT_QUORUM, RIGHTS_MISMATCH
  • Owners alerted; re-check without mutating outputs

Fits your stack

Keep what works

Stripe Connect / Adyen for Platforms for payouts; ACH/SEPA rails; NetSuite/Oracle for GL. We run as a pre-release gate.

Add three fields

  • window_id — identifies the payout window
  • output_digest — ties to the sealed transcript (replay equality)
  • provider_batch_id — PSP/EBP batch reference

One pre-release call

Right before you create the PSP batch:

Authorize
POST /authorize { window_id }
→ ALLOW roster + HOLD roster with reason codes

Path A — Pay via PSP (fastest)

  • Create PSP batch from the ALLOW set
  • Record Vendor Bills (one per driver per window) in ERP
  • Tag rows with window_id and output_digest

Path B — Pay from ERP (EBP)

  • Use ALLOW set to build EBP payment file
  • Include window_id in memo; capture EBP batch as provider_batch_id
  • Gate release via Authorize(window_id) before export

Data intake options: S3/GCS/SFTP, read-only DB view, Kafka/Webhook — adapters provided.

Where these fields go

  • PSP/rails batch metadata: window_id, output_digest, provider_batch_id
  • GL (NetSuite/Oracle) custom fields: custbody_payout_window_id, custbody_output_digest, custbody_provider_batch_id

Technical details (for software engineers)

View endpoints, data contracts & mappings

API surface

Gate release and fetch evidence:

POST /authorize (window_id)
// Checks replay digest equality + acceptance matrix (freshness & quorum)
→ Returns: ALLOW roster + HOLD roster with reason codes
POST /proofs (submit attestations)
// Push CT/ACK/SPV payloads; we verify signatures & freshness and update decisions
GET /transcript/{window_id}
// Content-addressed transcript + output_digest for replay & audit

Data contracts (minimal)

Tier 0 — events
event_id,ts_occurred,principal_id(currency),amount_minor,source_type
// source_type ∈ { fare | surge | tip | refund | adjustment }
Tier 2 — attestations (signed JSON)
// Finance ACK (window-level)
{ "window_id":"2025-09-05/17:00", "reserves_ok":true, "signer":"fin-ops@...", "expires_at":"2025-09-05T18:00:00Z" }

// CT (driver/cohort-level)
{ "principal_id":"DRV-18472", "status":"cleared", "expires_at":"2025-09-06T00:00:00Z" }

// SPV (optional, window-level)
{ "window_id":"2025-09-05/17:00", "provider_batch_id":"ADY-88919", "totals_minor": "123456789", "headers_hash":"0x..." }
ERP/PSP delta
// Add to PSP batch metadata & GL:
window_id, output_digest, provider_batch_id

Results teams aim for

Replay equality ≥ 99.99%

Windows where digest(replay) == digest(transcript).

Time-to-release (p95)

Minutes from watermark close to authorized payout (not hours).

Disputes ↓ 30–60%

Transcript-based proofs reduce escalations and chargebacks.

Change MTTR (bounded)

Rollback & recovery bounded to a window via canary → equality → promote.

No rounding drift

Deterministic carry with ≤½-ULP bound; surge/tips stay consistent.

Targets are set together during a pilot; they are goals, not guarantees.

Risks & mitigations

See risks & how we handle them
  • Late/missing proofs → auto-HOLD; re-check without mutating outputs.
  • Policy/migration defects → digest mismatch; canary + rollback before release.
  • Hot partitions → versioned shard function; promote only on digest equality.

FAQ

What about late cancels and refunds?

They never mutate prior windows. We record them as new events in the next window with reason codes. Audit stays clean; no clawback chaos.

Do we change payout rails?

No. You keep Stripe/Adyen/ACH/SEPA and your ERP. We add a pre-release gate before funds move.

Will surge/tips still round strangely?

No. We quantize once per window and assign sub-cents in a fixed, documented order (carry-ledger). Replays match bit-for-bit.

Pilot in 30 days

What we’ll ask in discovery

  • What must be true before you release a payout file today? Who signs off?
  • How often do you see clawbacks from refunds after payout?
  • Where do PSP totals vs GL differ today, and by how much?

Next step

Gate one cohort for two windows; measure equality, reasons, and time-to-release.

Verit Global