A transaction protects you inside one database. A real checkout also talks to a card network and a mail server, and they aren't in your transaction. From here on, the failures are between machines.
Partial failure
When some of the work happened and some didn't, and you may not be able to tell which. On one machine, a thing either ran or it crashed. Across a network, you sent a request and heard nothing: it might have failed, or it might have worked and the reply got lost.
Agents write the happy path as a straight line: charge the card, save the order, send the email. Each line is correct, and a crash between any two leaves a state nobody designed. Ask what happens at every gap. Wrapping it all in a database transaction doesn't help, because a rollback can't uncharge a card.
“For this checkout, list every point it could crash and what state each one leaves. Then rewrite it so the order and a row in an outbox table commit in one transaction, and a worker makes the charge with the order id as the idempotency key. Add a test that kills it at each point.”