Repository navigation
v0.1.6 — FX dispute support
Fixed
-
FX disputes are now supported.
charge.dispute.funds_withdrawn
events whosebalance_transactionsare in a different currency than
dispute.currency(the standard case for Connect platforms or any
Stripe account where the customer-facing currency differs from the
account's settlement currency) used to throw
"FX disputes not yet supported"; they now produce balanced journal
entries in the settlement currency.The previous fee-detection heuristic compared
|bt.amount|against
dispute.amount, which only works when both sides share a currency.
The new heuristic identifies the clawback BT as the one with the
largest|bt.amount|within the dispute-category set, and every
other dispute-category BT contributes both its|amount|and its
inlinefeeto the fee total. This works across the three documented
Stripe BT shapes (single combined BT, split clawback + fee BTs, FX
variants of either) without comparing amounts across currencies.The entry's
currencyfield now derives from the BT settlement
currency (notdispute.currency), so an FX dispute posts in the
account's settlement currency — matching what the FX-safe
chargeSucceededhandler already does for the original receivable.
This keeps the1200 Disputes Receivableaccount single-currency in
the operator's books.Same-currency dispute behavior is unchanged: the existing
dispute_funds_withdrawn_standardfixture passes byte-identical. The
new heuristic produces the same(clawback, feeTotal, totalWithdrawn)
tuple as the old one whenbt.currency == dispute.currency, for both
single-BT and split-BT shapes.
Added
- New fixture
dispute_funds_withdrawn_fxcovering a Canadian-settling
account disputing a $50 USD charge with a split-fee CAD BT shape
(C$68.75 clawback BT + C$20 fee BT = C$88.75 total withdrawn).
Engine + QBO + Xero goldens validate end-to-end. - Two defensive guards in
disputeFundsWithdrawn: empty
dispute-category BT array, and mixed-currency BT array. Both throw
with clear messages rather than silently producing wrong entries.
Notes
The FX implementation is best-effort against Stripe's
documented BT shapes for
dispute withdrawals; the synthetic fixture uses plausible amounts and
an exchange-rate hint. Operators hitting a real FX dispute whose BT
shape doesn't match (e.g. Stripe attaches a third BT for an unmodeled
adjustment) should open an issue with the actual BT structure so the
heuristic can be refined against real data.
charge.dispute.closed paths under FX without a preceding
funds_withdrawn still post in dispute.currency — that path doesn't
expand BTs the way funds_withdrawn does, so it can't reach the
settlement currency without an extra Stripe API call. Same caveat as
before.