Every fixture is a well-formed JSON success, and the response that takes an application down is an HTML error page from somebody’s load balancer.
Http::fake([
'rates.example/*' => Http::sequence()
->push(file_get_contents(__DIR__ . '/fixtures/502.html'), 502)
->push(['rates' => []], 200),
]);
// the client must not call json_decode unconditionally:
// a parse error inside the HTTP client becomes a 500 at
// the checkout, which is our outage from their degradation.
Checking the content type before decoding is the fix and it is the sort of defensive line that gets removed as unnecessary during a refactor — which is why the test matters more than the code. Recording the real body from a sandbox rather than writing one by hand is what produces a fixture nobody would have thought to invent.