Skip to content
All posts

Disputes on connected accounts: who pays, in what order

Disputed funds and dispute fees land on different balances depending on charge type; destination and separate charges put the platform balance first in line.

FeeGuard13 min read

Disputes on connected accounts: who pays, in what order

When a cardholder disputes a payment on your Connect platform, Stripe does not always take the money from the same place. This article answers, for platform operators: which balance gets debited for the disputed amount and the dispute fee under direct, destination, and separate charges, and how platforms recover from sellers afterward.

The life of a dispute in four events

Per Stripe's dispute overview, a dispute starts when a cardholder questions a payment with their issuer, and the network formally reverses the payment immediately, pulling the payment amount plus network dispute fees. From there the lifecycle runs through webhooks, and four event names carry the entire timeline:

EventFires whenMoney movement it accompanies
charge.dispute.createdCardholder files; evidence window opensDisputed amount debited under the rules below
charge.dispute.updatedEvidence submitted or status changesNone directly
charge.dispute.closedOutcome decided (won or lost)On a loss, the dispute fee posts against the responsible balance
charge.dispute.funds_reinstatedA won challenge releases held fundsDisputed amount returned to the balance that was debited

Two properties of this timeline shape everything else. First, the debit happens up front: you respond to evidence with the money already gone, which makes the question of which balance was debited the most consequential design fact in your Connect setup. Second, the dispute object carries its own response deadline inside the evidence window; missing it closes the dispute as lost by default, so platforms that route responses to sellers need the deadline surfaced somewhere someone actually watches. The charge.dispute.created explainer covers the fields involved.

Inside that window your options are to challenge by submitting evidence before the deadline or to lose by default when it passes. Winning releases the held funds back to the balance that was debited via charge.dispute.funds_reinstated; losing makes the debit permanent and posts the dispute fee against the same allocation rules. The outcome changes nobody's liability; it only decides whether the money comes home.

Wire these events to real handling rather than inbox rules: delivery is at-least-once with retries stretching to roughly three days, signatures should be verified with stripe.webhooks.constructEvent, handlers must be idempotent, and endpoints should respond 2xx quickly and process asynchronously afterward.

On Connect specifically, the charge type determines not only who responds to the dispute but which account's balance absorbs each debit. That allocation is the subject of the next section, and the closing event's aftermath, including what you can still recover, is covered near the end; the charge.dispute.closed explainer tracks the post-close decisions.

Which balance gets debited, by charge pattern

Stripe's own wording on disputes on Connect platforms draws the line cleanly:

For destination charges and separate charges and transfers, with or without on_behalf_of, Stripe debits dispute amounts and fees from your platform account.

That is the sentence to internalize: setting on_behalf_of changes settlement currency and statement descriptors, but it does not move dispute liability off your platform balance for destination and separate charges. The table below shows who gets debited under each pattern.

Charge patternDisputed amount debited fromDispute fee debited from
Direct chargeConnected account's balanceDepends on account configuration; see next section
Destination charge, with or without on_behalf_ofPlatform balancePlatform balance
Separate charge and transfer, with or without on_behalf_ofPlatform balancePlatform balance

For direct charges, Stripe attempts to debit the connected account for the disputed amount, because the charge lives on that account. If the connected account cannot cover it, ultimate responsibility follows whichever party is configured as responsible for negative balances.

For the other two patterns the platform balance pays both line items, every time. The seller whose sale drew the dispute keeps their transferred funds untouched unless you act; recovery is a manual transfer reversal, never an automatic one.

Why operators should care about the row order: platform-balance liability converts seller problems into platform cash-flow problems on day one. Every disputed destination-charge dollar is money your balance pays immediately and hopes to reclaim later, and in dispute-prone categories the receivable-from-sellers float becomes a working-capital line item nobody budgeted. The allocation table is not trivia. It decides whose balance sheet absorbs the weeks between dispute creation and recovery.

The dispute fee is its own line item

Treat the dispute fee as a distinct debit, not a percentage of the disputed amount. It is assessed separately from the disputed funds, and its size varies by card brand and country; Stripe notes that a single chargeback can pull "one or more network dispute fees," and current figures live on Stripe's published pricing page. Check the schedule for your countries and card mix rather than assuming one number applies everywhere.

On direct charges there is a configuration layer deciding who even pays that fee. Under v1 account configuration the field is controller.fees.payer; under v2 it is defaults.responsibilities.fees_collector. The mapping, summarized from Stripe's Connect disputes guide:

Configuration valueWho pays the dispute fee
v1 controller.fees.payer = applicationPlatform
v2 responsibilities.fees_collector = applicationPlatform
v1 controller.fees.payer = account or legacy Standard/Express/Custom variantsConnected account
v2 responsibilities.fees_collector = stripe or legacy Standard/Express/Custom variantsConnected account

Read that against the previous table and the asymmetry appears: on a direct charge with fees.payer = application, your platform pays the dispute fee while the connected account pays the disputed amount. On a destination charge, your platform pays both, unconditionally. Platforms sometimes discover the second fact during their first heavy chargeback week. The fee-payer mapping is worth checking once, deliberately, in code instead of learning it from a balance statement.

Worked exposure: a $600.00 destination charge goes bad

Assumptions, all labeled:

  • Destination charge on a US platform, USD card, amount 60000 cents ($600.00).
  • Your marketplace contract charges sellers a flat 10% take rate (an assumption about your terms, not a Stripe figure): application_fee_amount = 60000 x 0.10 = 6000 cents ($60.00).
  • transfer_data[amount] unset, so Stripe transfers the remainder to the seller: 60000 − 6000 = 54000 cents ($540.00).
  • F = the applicable dispute fee for this card brand and country, per Stripe's published pricing.
  • Processing costs excluded to keep the exposure arithmetic clean.

The dispute is lost. Each movement, shown separately:

platform debit: disputed amount      -60000        (-$600.00)
platform debit: dispute fee          -F
total platform debit                 -(60000 + F)
seller position                      +54000        (unchanged; transfer intact)

Recovery ceiling, if you pursue it perfectly:

recoverable via reversal             = min(seller holdings, transfer amount)
                                     = min(54000, 54000) = 54000
platform position after full reversal = -(60000 + F) + 54000 = -(6000 + F)

Conclusion in dollars and cents: the platform is debited $600.00 plus F, can claw back at most $540.00, and therefore eats an unavoidable residual of

residual platform loss = 60000 - 54000 + F = 6000 + F = $60.00 + F

If nobody reverses anything, the loss is the full $600.00 plus F, and the seller keeps $540.00 for a sale that unwound. Notice what the perfect-recovery number tells you: the unprotected portion of every destination-charge dispute is exactly your own fee income on the sale, plus the dispute fee on top. No flag, setting, or on_behalf_of variant changes that. Only your recovery operations and your seller contract do.

Tracking every dollar through the same scenario produces the conservation table below (processing costs excluded; F carried symbolically).

PartyAfter saleLost, nothing recoveredLost, full $540.00 reversed
Platform+$60.00-$540.00 - F-F
Seller+$540.00+$540.00$0.00
Buyer-$600.00$0.00 (issuer made them whole)$0.00

Each column sums to zero, which is the point: no dollar vanishes, they only change owners. Read the middle column as the lifetime view, where the platform kept $60.00 of margin and then paid $600.00 plus F out of its balance. Measured instead against the no-dispute baseline, where the platform would have kept its $60.00 margin, the cost of the lost dispute is exactly the residual computed above: $60.00 + F. Both views describe the same dollars from two directions.

Recovery paths and their timing traps

Reversal is the only lever, and timing changes its cost. You can create a reversal the moment charge.dispute.created fires:

curl https://api.stripe.com/v1/transfers/tr_example123456789/reversals \
  -u "$STRIPE_SECRET_KEY:" \
  -d amount=54000

Timing matters because seller balances drain. Charge amounts sit in pending before becoming available on a rolling schedule, and payouts sweep available funds on whatever schedule each connected account runs. Every day between dispute creation and your reversal is a day the recoverable balance shrinks. Early reversal draws against pending and available funds before a payout intervenes. Late reversal still succeeds mechanically (reversals drive the connected account's balance negative), but it moves the conversation from reconciliation to collections, covered in the next section.

Winning the dispute adds a symmetrical obligation. Funds come back to the debited balance via charge.dispute.funds_reinstated, and if you reversed the transfer during the fight, Stripe's guidance is explicit: you can transfer the previously reversed funds back to the connected account, and if your platform has an insufficient balance, that retransfer fails. Budget for the round trip before you claw back.

One caution is load-bearing for cross-border platforms. Stripe advises waiting to recover disputed cross-border payment transfers for destination charges made with on_behalf_of until after a dispute is lost, because retransferring across borders can be restricted and leave you unable to repay the seller even though you want to. Domestic destination charges do not carry this constraint; cross-border ones invert the usual instinct to claw back fast.

Finally, communicate. A seller who wakes up to a vanished $540.00 files support tickets and churns; a seller told "a dispute landed, here is the evidence deadline, here is our policy on holds and returns" mostly does not. Whatever policy you pick (claw back immediately, hold until resolution, or absorb below a threshold), write it into seller terms first and automate it second. The dispute-loss clawback playbook walks the sequencing, and platforms that want the decision tree codified end-to-end can look at dispute clawback automation.

When the connected account cannot pay

Direct-charge disputes debit the seller's balance, and sometimes that balance cannot cover the debit. The resulting mechanics, documented under connected account balances, run as follows.

A negative balance blocks payouts on that account entirely; nothing flows out until future payments push the balance positive again, and incoming payments offset the debt first. Responsibility for the shortfall depends on configuration: v1 controller.losses.payments or v2 defaults.responsibilities.losses_collector, valued either stripe or application. Set it to application and unresolved connected-account debts become yours.

Platforms can shorten the wait with debit_negative_balances=true, which authorizes Stripe to attempt debiting the connected account's external bank account when the balance goes negative. Support covers US, Canada, Australia, New Zealand, and SEPA including the UK.

There is a backstop, and it points at you: reserve machinery in the form of reserve_transaction entries protects platforms, and a connected-account negative balance older than 180 days triggers a connect_collection_transfer, meaning Stripe moves funds from your platform reserves to zero out the seller's debt. Stripe's own guidance is to stop doing business with accounts that reach this state. The practical takeaway for finance teams: platform-level exposure to a seller's dispute is never fully zero, only deferred, and the deferral expires at 180 days. Reviewing negative-balance accounts weekly, with the responsible-party configuration confirmed in code, keeps that deferral from turning into a surprise journal entry.

Detection: finding losses the platform paid for

Everything above degrades quietly at scale. The signature of an uncovered loss is specific enough to detect mechanically: pair charge.dispute.closed with status = lost against the transfer and reversal state of the related destination or separate transfer. When the platform balance was debited for the disputed amount and reversals do not match the exposure, you have a loss your platform funded and has not reclaimed.

Run it as a procedure:

  1. Pull every charge.dispute.closed event in the window whose status is lost.
  2. Map each dispute to its charge, then to the destination or separate transfer behind that charge.
  3. Sum the reversals on that transfer and compare the total against the disputed amount; any shortfall, plus the fee, is the uncovered loss, reported as principal and fee separately.

Three implementation realities make ad hoc versions of this check fail. Webhook delivery is at-least-once, so handlers must be idempotent or you will double-reverse while cleaning up. Reversals come in partial amounts, so the comparison is a sum against a ceiling, not a boolean. And seller-side state moves independently, because payouts drain recoverable funds daily, so the gap between detection and action converts recoverable losses into permanent ones. The operational checklist lives in the disputes-the-platform-paid-for detector, and the deeper methodology, including the join between dispute objects and reversal sums, is written up in the dispute clawback audit.

Run the pairing yourself over your last quarter of closed-lost disputes and list every one whose transfer shows no matching reversal. That list is the exact set of dollars, disputed principal plus fees, that your platform balance donated.

Frequently asked questions

Does Stripe automatically take the money back from the seller when a dispute lands?

No, not on destination charges or separate charges and transfers. Stripe debits the platform balance for the disputed amount and fee, and the seller's transferred funds stay put until you create a transfer reversal yourself. Only direct charges debit the connected account directly, because the charge itself lives on that account.

Who pays the dispute fee on a direct charge?

It depends on the account configuration. With v1 controller.fees.payer set to application, or the v2 equivalent responsibilities.fees_collector set to application, the platform pays. With account, stripe, or the legacy Standard/Express/Custom values, the connected account pays. The disputed amount hits the connected account either way.

We won the dispute. Does the seller automatically get their funds back?

No. Winning reinstates funds to the balance that was debited, which is usually your platform balance on destination and separate charges. If you reversed the seller's transfer during the dispute, returning the money requires a deliberate new transfer, and that transfer fails if your platform balance is insufficient at that moment.

What happens when a connected account cannot cover a lost direct-charge dispute?

Its balance goes negative, payouts pause until future payments offset the debt, and Stripe attempts an external-account debit only if debit_negative_balances=true. If the negative balance persists past 180 days, Stripe zeroes it via a connect_collection_transfer against platform reserves, moving the loss to you.

Find the disputes your platform paid for

On destination and separate charges, your platform balance absorbs every disputed dollar and every dispute fee until you reverse, and nothing in the Dashboard joins the two sides for you. FeeGuard reads your last 90 days of Connect activity through a restricted, read-only API key and reports every uncovered dispute loss, unreversed transfer, and unreclaimed application fee with the amounts attached. You get the answer first; ongoing monitoring is optional afterward.

Run the free 90-day audit.

FeeGuard is an independent product and is not affiliated with, endorsed by, or sponsored by Stripe, Inc.