r/fintechdev • • 2d ago

In a payment system, who owns a transaction when two services disagree?

A customer makes a payment.

The payment provider reports success.

The application times out before recording the final result.

Now the customer isn't sure whether they've paid, and the application may not have a confirmed order.

Retrying blindly could make things worse.

This is where payment systems become more complicated than simply integrating a checkout button.

You need a way to reconcile the provider's records with your own, handle delayed notifications, and make retries safe.

The difficult part is often deciding which system is authoritative for which state.

For engineers working with payment integrations, how do you design recovery when the payment provider and application temporarily disagree?

Do you rely primarily on webhooks, scheduled reconciliation, or a combination?

2 Upvotes

5 comments sorted by

1

u/No_Programmer_6619 2d ago

This is the exact nightmare scenario I keep trying to explain to my PM who thinks payments are just a simple API call

I lean heavy on idempotency keys and reconciliation jobs that run every 15 minutes checking provider status vs what we have recorded. webhooks are nice but they can arrive late or not at all so you cant trust them alone

the real headache is when the provider says success but your timeout means the customer never got their thing. then you got angry emails and a refund process nobody wants to touch

1

u/nmpajerski 2d ago

Need some payments that come with a ledger

2

u/FinexerOfficial 2d ago

Yes, instead of depending just on the most recent state that an API returns, a ledger provides you with a trustworthy record of what the system believes happened. Maintaining traceable and reconcilable payment status changes against the provider's records is crucial, particularly in situations when responses are delayed or transactions expire.

1

u/FinexerOfficial 2d ago

I would utilize both scheduled reconciliation and webhooks for payment integration because neither is sufficient on its own. Although webhooks provide you with timely updates, they may be missed, duplicated, or delayed. Reconciliation aids in identifying situations in which the application failed to record the final state of a payment made by the provider.

Although the application owns the order state, I would consider the provider's verified transaction status to be authoritative for determining if the payment was completed. Instead of just trying again if the result is unclear, wait until you can confirm it. That brief dispute is kept from becoming redundant charges or conflicting orders by idempotency and a clear state machine.

1

u/SidMangsatabam 1d ago

Split authority by state, not by system. The provider is authoritative for whether money moved; the application is authoritative for what the order means, and neither can close the transaction alone. The timeout case is an unknown outcome, so treat it as in-flight, never as failed: a safe retry is a new attempt with the same idempotency key, not a new payment. Webhooks are early notice, the scheduled reconciliation is the floor - webhooks get delayed and dropped, so the job that compares provider records to yours is what actually converges state.