CRITICAL financial defect. Cart UI showed the negotiated $21 total
for an accepted offer (list was $42), but EVERY payment pipeline —
Stripe (cart.py:848), PayPal (cart.py:1164), Monero quote
(crypto.py:269), Dogecoin quote (crypto.py:538) — pulled
invoice.total_in_cents, which summed line items and ignored the
cart_offer / cart_auction override entirely. Buyer's DOGE quote
asked for ~373 DOGE (≈$42 USD) for an offer they negotiated to $21.
Seller would have eaten $21 per accepted offer.
Fix:
- New column mps_invoice.negotiation_override_in_cents (nullable
BigInteger). Migration 27bc1bfc33dc adds it idempotently.
- Invoice.total_in_cents short-circuits to the override + handling
when the column is set. Coupons / discount math is bypassed (the
buyer already negotiated; we don't stack on top).
- Invoice.apply_cart_negotiation(cart) helper copies the cart's
override onto the invoice in one call. Idempotent. No-op for
non-negotiated carts.
- Wired into every invoice-from-cart construction site (7 total):
- views/crypto.py:161 (Monero quote)
- views/crypto.py:454 (Dogecoin quote — fox's screenshot)
- views/cart.py:827 (Stripe checkout)
- views/cart.py:974 (PayPal create-order)
- views/cart.py:1153 (Adyen sessions)
- views/cart.py:1258 (PayPal complete-checkout)
- views/cart.py:1388 (post-PayPal-approval finalize)
Two integration tests cover the model:
- test_negotiation_override_short_circuits_total walks the
invoice-from-negotiated-cart flow, asserts $42 → $21 transition
after apply_cart_negotiation, and confirms handling still adds
on top.
- test_apply_cart_negotiation_noop_when_not_negotiated proves the
helper is safe to call on plain carts (no negotiation_override
set, line items sum normally).
Legacy invoices already in the DB have NULL on the new column —
they keep their line-item-summed totals, untouched.