Before Rewriting a Legacy System, Read Its Exceptions
An old payment retry check shows why a rewrite needs to investigate exceptions before deciding which behavior to keep.

The payment processor behind one of my systems once went down for 40 minutes. Clients retried their requests throughout the interruption. The service recognized each retry by the idempotency key it shared with the original request, so those attempts didn't become duplicate charges.
That retry check kept one payment from turning into two charges. It's exactly the kind of awkward branch I worry about in a rewrite. The normal path is usually easy to reproduce. The failure path carries the history.
A “simplify the payment handler” change can remove the repeat-request check while every existing test still passes. Each test sends one payment and expects one charge.
Before rewriting, I'd run the same request twice and see what the current system does.
The team can keep runnable copies of the old and new code, give each its own test data, and use a fake processor that records charge requests without moving money. Send the same payment request twice to both versions. One charge request from the old version and two from the replacement would expose the lost behavior.
I run the old and new versions with the same inputs and compare what they do. That gives the team a concrete difference to investigate.
I'd look beyond the payment handler too. A field that appears unused there may be read by another service or exported to another system. Every reader is another place where removing the field could change behavior.
I wouldn't preserve everything. That would copy old defects along with old requirements.
Another old check could reject a payment whenever the same customer has already paid that amount. It catches more than retries. Two separate purchases for the same amount, with different idempotency keys, should be allowed. If the old version records one charge and the replacement records two, the replacement may be the correct one.
Both tests changed. Someone who owns the payment rules has to decide which result is right.
With the same idempotency key, one intended payment should produce one charge. With different keys for two intended purchases, two charges may be right. The rule owner still has to settle those expectations. The old code can't make that decision for us.
Once the requirement is settled, the tests can preserve the retry protection without preserving the amount-based refusal. Where the rule remains unknown, I'd keep the proposed change away from live charging.