May 2026 Reconciliation · Closed

The Whoop May ledger reconciles to the bank at zero variance.

Every May 1 through May 18 ticket sale on the workbook ties to a specific Stripe charge, that charge ties to a specific Stripe payout, and that payout ties to a specific Southern First Bank deposit. Eleven deposits, eleven matches, no residual.

Workbook: Whoop Here It Is - Daily Sales Report - CLAUDE.xlsx  |  Period: May 1 to May 18, 2026 (11:42 ET cap)  |  Prepared May 20, 2026
$90,008.31
May sales (446 active rows)
$43,565.23
11 May bank deposits
$43,565.23
11 Stripe payouts (T+1)
$0.00
Variance
446 / 446
Rows verified vs source
01 · Summary

What this report is

The Whoop Daily Sales Report is the canonical year-to-date ticket-sales ledger that feeds QuickBooks. Sheet 26 holds one row per money event (a card sale, an installment charge, a refund, a sponsor booking, a comp). Column T marks rows already posted to QB.

What changed this period

Rows 2 through 1425 (January 1 through April 30) were already reconciled by finance before this session and are unchanged at the value level. Rows 1426 through 1873 are the May 1 to May 18 11:42 ET append. New columns were added to make the file self-reconciling against the bank.

ColumnWhat it is
A to UExisting columns. Sales, fees, classification routing. Unchanged structure.
VNEW. Stripe Charge ID (ch_xxx) for every row that has a Vivenu transaction linkage. 572 rows populated.
WNEW. Stripe Payout ID (po_xxx) that the charge settled into. 511 rows populated.
XNEW. Bank Deposit Date for that payout (Stripe effective date + 1 business day).

Numbers at a glance

MeasureExisting (rows 2-1425)May (rows 1426-1873, 446 active)Grand total
Amount (C)$277,027.10$90,008.31$367,035.41
Stripe fee (D)$8,418.34$1,746.48$10,164.82
Settled (E)$268,545.73$88,261.83$356,807.56
Vivenu fee (G)$14,741.79$3,775.14$18,516.93
Mauldin pass-through (H)$22,807.50$4,640.00$27,447.50

May classification

Each row is bucketed by the actual Vivenu ticket category on the Accounting Transactions export. Untagged rows are everything that doesn’t fit a single bucket (single match, group, family pack, Summer of Soccer, Clemson, in-house, installment, refund).

BucketRowsSettled (E)Routes to
Parking (season parking pass + single-match parking)52$7,282.74N (Parking)
Full Season ticket buys (Full Season, Half Season, Suite)40$10,338.09O (Full Season)
Sponsor7$34,260.00R (Sponsor / Reimb)
Untagged (single match, group, family pack, Summer of Soccer, Clemson, installment, refund)348$36,381.00
Total May rows447 (1 cleared)$88,261.83
02 · Vivenu / Stripe / Bank

Eleven deposits. Eleven exact matches.

The Stripe Itemized Payout Reconciliation export tags every charge with the specific payout (po_xxx) it settled into. That collapses the prior 2-business-day-lag guesswork into an exact answer. Stripe releases payouts in the evening of a business day; the bank shows them arriving the next business day. The 11 May deposits map cleanly onto 11 Stripe payouts.

Bank arrivalStripe payout IDChargesStripe netBank depositVariance
Fri, May 1po_1TS5GOEiGAGag7IGaZtslLop3$537.04$537.04$0.00
Mon, May 4po_1TTAQcEiGAGag7IGhOPSB9V99$2,988.81$2,988.81$0.00
Tue, May 5po_1TTXBBEiGAGag7IG3d8yCHLX14$1,585.84$1,585.84$0.00
Wed, May 6po_1TTu2wEiGAGag7IGnM2xh7Yn31$3,129.96$3,129.96$0.00
Thu, May 7po_1TUFRPEiGAGag7IGmjS7GKaV19$3,020.79$3,020.79$0.00
Fri, May 8po_1TUchKEiGAGag7IGBux0fp9924$4,380.29$4,380.29$0.00
Mon, May 11po_1TVhx3EiGAGag7IGLg453bqm31$6,015.03$6,015.03$0.00
Tue, May 12po_1TW4W1EiGAGag7IGUsThPiJa48$3,958.03$3,958.03$0.00
Wed, May 13po_1TWQZ7EiGAGag7IGh4N665Zd119$9,515.36$9,515.36$0.00
Thu, May 14po_1TWnXlEiGAGag7IGNvhylsMe9$6,137.21$6,137.21$0.00
Fri, May 15po_1TX9hpEiGAGag7IGb10cZTbg13$2,296.87$2,296.87$0.00
Total320$43,565.23$43,565.23$0.00
Definition of done

The 11 May bank deposits totaling $43,565.23 exactly equal the sum of the 11 Stripe payouts containing the workbook's May charges. Variance: $0.00. Each Whoop row in column W is now tagged with the specific po_xxx it settled into, and column X holds the bank arrival date.

03 · How It Adds Up

The full money flow, source to bank

Each May sale moves through four systems. The Whoop row joins all four.

1. Vivenu
403 txns
391 card + 7 sponsor + 1 paymentplan + 4 comps. realPrice $84,629.62.
2. Stripe charges
406 paid
391 new sales + 40 prior-plan installments + 3 manual + 2 refunds. Net $55,242 (paid into 11 May payouts).
3. Stripe payouts
11
Released business-day evenings 4/30 to 5/14. Net $43,565.23 across the 11.
4. Bank deposits
11
Southern First Bank ····5948. Arrive next business day after each payout. Total $43,565.23.

What the Whoop $90,008.31 covers vs the $43,565.23 of deposits

The Whoop May sales total ($90,008.31) is larger than the deposits ($43,565.23) for three structural reasons:

ItemMay valueEffect on deposits
Card sales hitting Stripe in May$50,583.13Net to deposits
Sponsor bookings (paymentMethod = Sponsorship Payment)$34,260.00None. Internal booking, not a Stripe charge.
Free comps (paymentMethod = none)$5,165.18None. Internal, not a charge.
Refunds (negative rows)−$297.50Netted inside the original deposit; Stripe keeps its original fee.
Date-range overlap (Stripe charges 4/29 to 4/30 settle into 5/1 to 5/4 deposits)+~$2,400Adds to deposits, doesn't show in May Whoop sales.
May 1 to May 15 deposits$43,565.23Matches Stripe-side payouts exactly.

In short: Whoop is sales-side (every booking that happened, regardless of how the customer paid). Bank deposits are cash-side (only money that actually moved through Stripe). The Stripe payout reconciliation is the join.

04 · Red Flags

Traps that broke the report along the way

These are the bugs that caused wrong numbers in earlier versions. Documenting so we catch them next time.

Mauldin Fee was set to outerCharge

The Mauldin Facility Fee column was being populated with the customer-paid outer fee (outerCharge on the Vivenu transaction). That's the total customer-facing service fee, which on parking equals the Parking Processing Fee, not Mauldin. Result: 52 parking rows carried $28 Mauldin each when the truth is $0.

Fix: read only the line items whose name contains "Mauldin Facility Fee" from the Accounting Transactions export. Anything else is processing fee.

Cost: $1,724 of fake Mauldin pass-through

Vivenu Fee was set to outerCharge

898 historical rows had Vivenu Fee equal to the per-ticket external fee schedule ($5 single, $2.50 group) rather than the actual innerCharge Triumph pays Vivenu. Over-stated platform cost by $3,085 across the year.

Fix: G = innerCharge from Vivenu /transactions. Sean's rule.

Cost: $3,085 of over-stated Vivenu fees

Accounting timezone gotcha

The Vivenu transactions export uses UTC (Z suffix). The Vivenu Accounting Transactions export uses Germany local time (+02:00). Same instant, different representation. Stripping the timezone without converting silently shifted accounting timestamps 2 hours forward and dropped three 5/18 morning transactions out of scope.

Fix: parse with datetime.fromisoformat, convert to UTC via astimezone(timezone.utc), then subtract 4 hours for ET.

Cost: 3 rows missing Mauldin, $18 short-stated

Accounting amount vs totalPrice

The Accounting Transactions export has both an amount column and a totalPrice column. amount is the quantity (e.g. 4 tickets), totalPrice is the dollar value. Treating amount as dollars under-counts by orders of magnitude on multi-ticket rows.

Fix: always sum totalPrice, never amount. netPrice is also booby-trapped: per-unit on ticket lines, total on fee lines.

Cost: caught on first audit before publishing

Multi-line cart double-counting

One Stripe charge can pay for several Vivenu transactions (Whitney Marrero bought 7 separate tickets in one $210 cart, becoming 7 transactions with the same Stripe charge ID). Putting the full charge total on one row and the per-ticket realPrice on the rest inflates the file. Putting the per-ticket realPrice on all rows is correct.

Fix: Amount column always equals realPrice on the transaction, not the Stripe charge amount.

Affected: 39 transactions across 6 buyers

Payment plans don't link by Stripe ID

A paymentplan transaction's psp field stores a payment-plan ID (pp_xxx) rather than a Stripe charge ID (ch_xxx). Joining payments to transactions purely by the Stripe ID misses the first installment.

Fix: when the txn payment method is paymentplan, match the payment to the transaction by Vivenu ObjectId timestamp prefix (the first 8 hex characters are the unix timestamp of creation, identical for objects created in the same Vivenu operation).

Affected: 1 May row (Walter Roten), but applies to every new plan booked going forward

Subsequent installments don't exist in /transactions

Vivenu's /transactions ledger records the original plan booking only. Subsequent installment charges live in /payments. Naively pulling /transactions misses them entirely.

Fix: union /transactions COMPLETE rows with /payments rows that have no May /transactions match. In May, 40 such installments were charged for plans booked earlier in the year. Per the rule, subsequent installments carry $0 Vivenu fee and $0 Mauldin (all plan fees were booked on the first installment).

Cost: $6,512 of revenue would have been missed

±1 day match window drops orphan installments

The commission-side linker had a ±1 day tolerance on expected installment dates. Installments that drifted past 1 day (Bradley Durham 4/22, Justin Nobles 4/24) were silently dropped as "unmatched payment."

Fix: anchor on Stripe Card Name (the authoritative buyer identity) rather than date arithmetic. Order all SUCCEEDED payments under the parent plan by createdAt for installment numbering.

Affected: 2 known orphans in 3/30 to 5/3; check the full year

Stripe T+1 day shift on payout effective_at

Stripe's automatic_payout_effective_at is the time Stripe RELEASED the payout to ACH (evening of business day D). The bank shows the deposit arriving the next business day (D+1). Lining them up by date directly looks off by one and produces a $24 "variance" that does not exist.

Fix: bank arrival = effective_at + 1 business day (skipping weekends).

Cost: the earlier −$24.27 estimate. Real variance is $0.00.
05 · What Was Done

The work that closed it

Four-way source join

Every May Whoop row is cross-checked against Vivenu /transactions, Vivenu /accounting, Vivenu /payments, and the Stripe payments export. Amount, Stripe fee, Settled, Vivenu fee, Mauldin, and refund amounts all tie to the source.

446 / 446 rows pass on the audit.

Stripe Payout Reconciliation join

The Itemized Payout Reconciliation export tags every charge with its specific payout ID. Joining that into the Whoop file gives every row a payout and a bank arrival date. The 11 May deposits reconcile to $0.00 variance.

11 / 11 deposits, $0.00 variance.

Mauldin Fee corrected to accounting truth

The Mauldin column now sums the "Mauldin Facility Fee" line items from the Accounting Transactions export, never customer-paid outer fees. Parking rows correctly carry $0 Mauldin. 6/3+ single-match rows carry $2 per ticket. Season ticket plans carry $26 to $30 per package.

May Mauldin: $4,640. File-total Mauldin: $27,447.50.

Vivenu Fee corrected to innerCharge

898 historical rows were re-set to the actual Vivenu platform cut (innerCharge on the transaction). Net of corrections, the file's Vivenu Fee total dropped from $21,605 to $18,520. Aligns with Sean's documented methodology.

898 corrections, $3,085 movement.

Three new columns for full traceability

Column V = Stripe Charge ID. Column W = Stripe Payout ID. Column X = Bank Deposit Date. Finance can pivot any sub-total on these and get the bank-side answer instantly. No more guessing which charges settled into which deposit.

572 rows tagged with charge ID; 511 of those further tagged with payout + bank date.

Subsequent installments correctly $0 fees

40 prior-plan installments charged in May carry $0 Vivenu fee and $0 Mauldin per the rule (all plan-level fees were booked on the original installment). First installments still carry the full plan fees.

$6,512 of installment revenue captured correctly.

Sponsor Mauldin applied buyer-agnostic

Madison Wilson's $9,030 GE Vernova sponsorship carries $1,290 Mauldin pass-through ($30 x 43 P5 sponsor season tickets). Old convention zeroed sponsor Mauldin. Per the rule "season ticket = $2/match Mauldin" applies regardless of buyer type. Sponsor R column captures net of Mauldin pass-through.

7 May sponsor rows, $34,260 gross, $31,950 net to R column.

Refunds reconciled, not netted away

The two May refunds (Stacey Staggers 5/6 −$171.50, Elizabeth Melvin 5/8 −$126.00) appear as negative-amount rows. They reduce the original payout net; the Stripe fee on the original charge is not refunded by Stripe.

2 refund rows, −$297.50 combined.

06 · For Finance

Posting these rows to QuickBooks

Same convention as the pre-existing rows. Mark each row with Yes in column T as it posts.

ColumnQB GL account / handling
C AmountThe gross figure that was charged to the customer (or the booking value for sponsor/comp).
D Stripe CC FeePosts to Stripe fees expense. $0 on sponsor and comp rows (no Stripe charge).
E SettledC minus D. The amount Stripe sends to the bank before payout-level adjustments.
G Vivenu FeePosts to Vivenu platform expense. Sourced from innerCharge.
H Mauldin FeePass-through to Mauldin facility payable. Customer paid it inside the gross; Triumph remits to Mauldin. Sourced from the "Mauldin Facility Fee" accounting line item.
N ParkingParking revenue. Subject to its own commission rate (2%) per the Commission Report.
O Full Season (M)Full Season ticket buys only (Full Season, Half Season, Suite). Single-match and group tickets are intentionally left untagged.
R Sponsor / ReimbSponsor revenue, net of Mauldin pass-through (R = E minus H on sponsor rows).
V Stripe Charge IDFor reconciliation. ch_xxx. Click into the Stripe Dashboard for the original charge.
W Payout IDFor reconciliation. po_xxx. The Stripe payout this row settled into.
X Bank Deposit DateThe day this row's payout arrived at Southern First Bank ····5948.
T Posted in QB"Yes" once the row is in QB. Reconciliation lookups can filter on this.

How to confirm any single row to the bank

Pick a row. Read column W to get the payout ID. Find that payout in Stripe Dashboard or in the Itemized Payout Reconciliation export. Sum all its charges; that's the deposit amount that arrived on column X's date. Reconciles to the cent.

Status

May 2026 sales: Closed   Bank deposits: Closed   Variance: $0.00.