All work
Writing · Practice

What outsourced UAT actually looks like

UAT is the phase nobody owns. Outsourcing it means giving that phase a dedicated owner whose job is to carry it through, and getting it back with evidence instead of a feeling.

Why it’s worth handing off at all

By the time an integration reaches UAT, everyone involved has somewhere else to be. The developers have moved on to the next roadmap item. The vendor considers you onboarded. The product owner is waiting on a date. UAT sits in the gap between two companies and several teams, and work that belongs to everyone gets done by nobody.

That’s the case for an outside owner. Not that they test better than your team, but that UAT finally has someone accountable for carrying it through, so it stops competing with your roadmap. Nobody has to be pulled off something else to chase a vendor, rerun a flow, or answer “are we ready yet?”

Two kinds of UAT

It can start as soon as you have sandbox access, and it comes in two stages. You can hand over either one, or both.

Vendor-level UAT, before your team builds. The vendor’s API is tested against your requirements before anyone implements it in your platform: does it actually do what the contract and the documentation say, for the flows your business depends on? It’s the same discipline as how I evaluate a vendor API, and the example further down comes from this stage.

Platform UAT, once it’s built. Your finished integration is tested end to end in your test environment before it goes live: the flows your customers will actually use, through your platform, against the vendor’s sandbox.

What you hand over

Less than most teams expect. On day one I need:

  • The technical schedule from the contract, or whatever timeline has been agreed with the vendor. It tells me what’s expected from the start, and it’s what I set expectations against when something has been overlooked or an issue comes up.
  • Access: sandbox credentials and the vendor’s documentation, plus, for platform UAT, wherever your side of the integration runs in test.
  • The requirements: what this integration has to do for your business. Not a test plan, just the flows that matter and the ones that would hurt if they broke.
  • People: one contact on your side who can make decisions, and the vendor’s support or technical contact.

How that access is handled. Sandbox and test environments only, with the narrowest access that does the job, and no production customer data. Credentials are sent securely and stored encrypted, and access is removed or revoked when the engagement ends.

What happens

1. Plan. I write the acceptance flows from your requirements and the vendor’s documentation, including the failure cases: declines, timeouts, duplicate requests, webhooks that arrive late or twice. Those are where integrations go wrong in production, and they’re rarely in the happy-path demo.

2. Run. Every flow the sandbox can run is executed against it, and every call is recorded, request and response. That record is what turns “it seemed to work” into something you can check. Anything that can’t be run, because the sandbox doesn’t support it or a dependency isn’t ready, is recorded with the reason.

3. Chase. Testing is the quick part. When I ran UAT in-house, the testing itself was focused, precise and fast. What took time was everything around it: questions to the vendor, often across time zones, and waiting on answers while working through whatever else the API had turned up. Each defect is logged with the evidence attached, triaged with your team, and worked through with the vendor when the problem is on their side.

4. Retest and sign off. The flow that failed is rerun unchanged, so “fixed” means the original failure no longer happens. Where a fix touches related behavior, new checks are added to cover it.

What it catches

This one came from vendor-level UAT, and it’s a problem I ran into more than once in payments: a vendor’s API could show balances, but only at the tenant level. Early in UAT that was all anyone needed, because no customer accounts had been set up yet. Once they had, and I was testing transaction requests against them, I realized there was no way at all to tie a single transaction to a customer account on our side.

I checked with the vendor whether I was missing something: an endpoint, a gap in the documentation, or something I just wasn’t putting together. I wasn’t. The capability didn’t exist. It was “coming soon,” with no date attached.

So I kept testing, and tracked the balances for each test account by hand. The goalposts kept moving, so I suggested to the development team that we’d need our own transaction tracking, reconciling every time a balance was shown or used to check available funds. The vendor’s version didn’t arrive in time. Building ours took a lot of development time, and it added more places where things could fail.

UAT didn’t make that gap go away. What it changed was when the team found out. Short of seeing it before the contract was signed, that was the earliest anyone could have, and it’s exactly where vendor-level UAT earns its keep: well before the developers have the integration in their hands. They went into the build with a major issue already surfaced, and a workable solution with it.

What you get back

  • A UAT plan: the flows, and why each one matters.
  • The executed runs: every call, its result, and when it ran.
  • A defect log: what broke, the evidence, who owned the fix, and where it stands.
  • A go/no-go you can defend: what was verified, what wasn’t, and what’s still open with the vendor, so whoever signs off is deciding from one shared record, instead of piecing the status together in the meeting.
  • Documentation your team can keep: the flows and internal docs your developers and support team need after I’m gone. In-house, I wrote these for the developers before they built anything. Here, they’re written from what the integration actually did.

What “done” means

In an ideal world, done is when every real need is met. In practice it usually means most of the requirements are met, and anything that isn’t has a workable alternative, like the transaction tracking above. The go/no-go comes down to how much is still missing, and whether working around it is worth the risk and the hours.

That’s also what it isn’t. It isn’t a rubber stamp: if something isn’t ready, the go/no-go says so, with the evidence. And it isn’t QA for your whole product or development work. If a fix is needed on your side, your team makes it. I check it against the agreed flows and report whether the original failure, or anything related to it, remains.

Who it’s for

  • API and payments providers getting customers live on their platform.
  • Merchants and platforms integrating a gateway or a third-party API.
  • Agencies and in-house teams without a QA person free for the last mile.

I’ve done this job in-house: I ran complete UAT on vendor integrations myself, built the flows and internal docs the developers worked from, and worked the gaps through with the vendor. I also built UAT-Ops, so the record of every call exists without anyone keeping it by hand. Why the phase stalls in the first place is its own essay: UAT is where integrations go to die.

If you have a vendor API to prove out before your team builds on it, or an integration stuck between “built” and “live,” that’s the work.