When Your Supplier's System Goes Down, What Does Yours Do?
A supplier outage is inevitable eventually. What matters is whether your software queues the work and carries on, or just fails in front of the customer.
A fire at a cable site or a dug-up line somewhere can knock out connectivity for a whole region, even when nothing local is broken. The same thing happens, on a much smaller scale, inside ordinary business software all the time. Your checkout works, your booking system works, your invoicing works, right up until the payment gateway, courier API or email provider you depend on has a bad hour. Then everything built on top of it stops too, unless someone designed it not to.
Most businesses never think about this until it happens to them. A Stripe wobble, a Royal Mail API timeout, a Companies House lookup that stops responding. None of these are rare events over a year of trading. The question worth asking isn't "could this happen" but "what does my software actually do when it does".
The dependency you don't notice until it breaks
Every integration is a point where your software hands control to someone else's system and waits for an answer. Most of the time that answer comes back in a few hundred milliseconds and nobody thinks twice about it. The trouble is that a lot of software is written as if that answer is guaranteed. The code calls the API, waits, and assumes success. If the call fails, the whole operation fails with it, often in front of a customer.
I see this most with:
- Payment processing, where a declined call from the gateway (not the card) stops a checkout dead
- Courier or shipping APIs, where a label can't be generated so the order can't be marked as dispatched
- Email and SMS providers, where a failed send silently drops a confirmation the customer was expecting
- Accounting or CRM syncs, where one slow response blocks a whole batch of records
In each case, the business logic and the third-party call have been welded together. If one fails, both fail. That's the pattern worth untangling.
What "graceful" actually means in practice
A lot of people reach for the word "graceful" without saying what it involves. For most business software it comes down to three things.
First, separate the parts of a process that must happen instantly from the parts that can happen a minute later. Taking a payment needs an instant answer. Sending the confirmation email doesn't. If the email send fails, the order should still go through, and the email should be queued to retry rather than lost. I've written before about moving slow work out of the main request, and this is exactly the situation it's built for: when a third-party call is involved, queuing isn't just about speed, it's what gives you somewhere to put the work when the call fails.
Second, decide what the user sees when something doesn't come back straight away. "Your order is confirmed, your receipt will follow shortly" is honest and keeps the customer calm. A spinning wheel that eventually times out with a generic error is not. The difference between these two outcomes is often a handful of lines of code, but it's the difference between a customer who trusts you and one who phones up worried they've been charged twice.
Third, make sure a failed call doesn't get retried in a way that makes things worse. Firing the same request five times in quick succession when a supplier's API is already struggling just adds to the pile-up, and can create duplicate orders or duplicate charges on your side. Retrying is the right instinct, but it needs limits and backoff, not blind repetition.
Testing the failure, not just the happy path
Most testing checks that things work when everything responds correctly. Fewer people test what happens when a supplier's API returns an error, times out, or comes back with something malformed. That's usually because it's awkward to simulate on purpose. It's worth doing anyway, even informally: point the integration at a dummy endpoint that refuses to respond, and watch what your software does. Does it queue the work and move on, or does it hang, or worse, silently drop it?
This matters more the more central the dependency is. A courier API outage that delays a dispatch email is an inconvenience. A payment gateway outage that leaves a customer unsure whether they've been charged twice is a support headache and a trust problem. Knowing in advance which of your integrations fall into which category tells you where it's worth spending the effort to build proper fallback behaviour, and where a simple "try again later" message is genuinely fine.
Where this fits into a build
None of this needs to be solved on day one of a project. But it's worth raising explicitly when you're scoping new integrations rather than discovering it the first time the supplier has an outage. A short conversation about "what should happen if this call fails" usually takes ten minutes and saves a much longer one later explaining to a customer why their order went missing. If you're connecting several systems together, that's exactly what I cover when I'm asked to look at API and systems integration work: not just getting two systems talking, but deciding what happens on the day one of them doesn't answer.
You can't stop a supplier's system going down. You can decide, ahead of time, whether that outage is something your customers notice or something your software quietly absorbs.