Imagine you're ordering a pair of shoes for ₹999.
You click Place Order, complete the payment, and wait for confirmation.
A few seconds later, the website shows that your order is confirmed.
Everything looks simple. But what if your payment succeeds and the website never receives the confirmation? What if you click Pay again because the page appears stuck? Could the system charge you twice?
Behind that single click, multiple systems must coordinate to make sure your order is processed correctly.
Let's explore what happens behind the scenes.
What Happens Behind That One Click?
An online purchase involves a website, a backend, a database, and a payment provider.
Here's a simplified view of how the process might work:
Customer Clicks "Place Order"
↓
Backend Processes Request
↓
Order Is Created
↓
Payment Is Requested
↓
Payment Provider
↓
Payment Result
↓
Backend Verifies It
↓
Database Is Updated
↓
Order Is Confirmed
The exact sequence depends on how the application is designed. Payment processing and order confirmation may involve additional steps.
The important part is that a successful payment request doesn't guarantee that every other step will succeed.
Let's look at the problems developers need to solve.
1. Idempotency — What If We Retry?
Imagine you click Pay for your ₹999 shoes.
The payment provider processes your payment successfully, but a network problem prevents your website from receiving the response.
Your website doesn't know whether the payment succeeded or failed.
If it blindly sends another payment request, you could be charged twice.
This is where idempotency becomes important.
Idempotency means that repeating the same operation doesn't repeat its effect.
A payment request can include a unique identifier called an idempotency key.
For example:
pay_order_8472_attempt_1
If the response gets lost, the application can retry the same operation using the same key. A payment provider that supports idempotency can recognize the repeated request and return the original result instead of processing another charge.
The key should be reused for retries of the same operation, not for a genuinely new payment attempt.
The main idea is simple: a missing response doesn't necessarily mean the operation failed.
2. Webhooks — How Does the Website Know?
Now imagine your payment succeeds, but you close the browser before the confirmation appears.
How does your website learn what happened?
Many payment providers support something called a webhook.
A webhook is an HTTP request sent by one system to another when a particular event occurs.
For example, when your payment succeeds, the payment provider can send a notification to your backend.
The backend verifies the notification, identifies the corresponding payment, and processes the necessary updates.
The flow looks like this:
Payment Succeeds
↓
Provider Sends Webhook
↓
Backend Receives Event
↓
Event Is Verified
↓
Payment and Order Records Updated
But there's a catch.
A webhook might arrive more than once, arrive late, or fail during processing. That's why the backend needs to verify incoming events and handle repeated notifications safely.
Receiving a notification is only one part of the process. The application must also make sure the event is processed correctly.
3. What If the Payment Succeeds but the Order Doesn't Update?
Let's return to our shoe order.
Your payment provider confirms that your ₹999 payment succeeded. However, the shopping website encounters a database error before updating your order.
The records might now look like this:
- Payment provider:
SUCCESS - Order database:
PENDING
You've paid, but the website still shows your order as pending.
Why does this happen?
The payment provider and the shopping website's database are separate systems. A database transaction can protect related changes inside that database, but it cannot automatically reverse a payment already processed by an external provider.
This connects to the ACID properties we explored in our earlier article about database transactions.
However, keeping one database consistent is different from coordinating multiple independent systems.
So how can the application discover and fix the mismatch?
4. Reconciliation — Finding What Went Wrong
This is where reconciliation becomes useful.
Reconciliation means comparing records from different systems to identify discrepancies.
For example:
| System | Status |
|---|---|
| Payment provider | SUCCESS |
| Order database | PENDING |
A reconciliation process can identify this mismatch, check the payment provider's records, and safely retry the missing order update.
If the payment status is uncertain, the application should verify it instead of assuming that the payment succeeded or failed.
Reconciliation can run periodically or be triggered by particular failures.
In simple terms, it helps the application discover when its records don't match what actually happened.
What If Something Goes Wrong?
Let's put everything together.
You order your ₹999 shoes. The payment succeeds, but the website temporarily loses the response.
Here's how the application might recover:
Payment Succeeds
↓
Response Gets Lost
↓
Website Doesn't Know the Result
↓
Retry or Check Payment Status
↓
Verify the Original Payment
↓
Update the Order Safely
↓
Confirm the Order
During this process:
- Idempotency helps prevent duplicate payment processing when the same operation is retried.
- Webhooks communicate payment events to the backend.
- Reconciliation helps detect and resolve mismatches when an update fails.
Each mechanism solves a different problem. Together, they help the application handle network failures, duplicate requests, delayed notifications, and database errors.
What I Learned
A single click on a shopping website can trigger operations across several independent systems.
Making those systems work together reliably is more complicated than simply sending a request and receiving a response.
A payment can succeed while the order remains pending. A notification can arrive more than once. A request can time out even though the operation completed successfully.
That's why developers need to think beyond the normal, successful path.
Idempotency helps manage retries. Webhooks communicate events. Reconciliation helps identify and resolve mismatches.
The biggest lesson is that reliable software isn't just about making things work when everything goes right. It's also about handling what happens when things go wrong.
The next time you place an online order, remember that behind that one click, multiple systems must coordinate to make sure the result is correct.
Thanks for reading!
Top comments (1)
payment succeeded, order pending. reconciliation is where that story actually ends.