Commit Graph

2 Commits (4eb90c834af9723b4d30fb70cc8aaeba73833cbd)

Author SHA1 Message Date
nexxo cdea9e923f One source for what counts as the same call
IdempotencyKey::forPrice()/forProduct() built the parameter array they
fingerprint, and FakeStripeClient::createPrice()/createProduct() rebuilt the
identical array literal by hand purely to feed replay()/rememberKey(). Nothing
tied those two literals together — a later change to what a Price call
fingerprints could drift from what the fake checks for a collision, and no
test would catch it, because the HttpStripeClient tests exercise forPrice()
alone and the FakeStripeClient tests exercise its own local array alone.

priceParameters()/productParameters() are now the one answer to "what counts
as the same call"; forPrice()/forProduct() and the fake both ask it instead of
each keeping their own copy. Fingerprint and key format are unchanged — this
is the duplication coming out, not new behaviour. refund(),
cancelSubscription(), addSubscriptionItem() and createCheckoutSession() are
untouched: their local parameter arrays are the fake's own record of the call,
never fingerprinted into a key, so there was nothing to duplicate there.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 10:46:46 +02:00
nexxo 60e93aafd7 Put in the key everything the call actually sends
A key says "I already sent this call", not "this is what the object is". The
catalogue calls sent metadata that the key knew nothing about, so adding the
tax_treatment field in 9da1358 poisoned yesterday's key for a day — and
AddonPrices::ensure() runs inside a customer's module booking, not only in the
sweep.

createPrice and createProduct now fold a fingerprint of their parameters into
the key. refund, cancelSubscription, addSubscriptionItem and the checkout
deliberately do not: there a second object is the customer's money taken twice,
and Stripe's refusal is the thing worth keeping.

The fake could not see any of this. Its ledger replayed the first id for a
repeated key without ever comparing what the second call asked for.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 10:30:32 +02:00