The real solution is to never rely on one party. We fall back to another payment processor after using a heuristic to see if the error isn’t one that makes sense. If it’s a problem with the payment card, it’ll fail again, no harm done. If it’s a problem with the provider, it’ll go through.
(We wrote a payments abstraction library easy enough to (partially or fully) fill for any payment provider’s core functionality, so it’s literally just a couple more lines of code at the call site. It took several rewrites to get the abstraction to cover all the oddities each time we added a new provider implementation, though!)