# One tap. Two orders.

> A double tap charges the customer twice.

- **Format:** short video, 10 steps, ~57 seconds
- **Topic:** A duplicate order from a double tap or a retry after a timeout — why disabling the button is not enough, and how an idempotency key from the app plus a unique index in Azure SQL guarantees one order and one charge.
- **Author:** Suthahar Jegatheesan (MSDEVBUILD)
- **Category:** Azure · Azure
- **Published:** 2026-10-01
- **Tags:** azure, azuresql, sqlserver, idempotency, apidesign, systemdesign, payments, flutter, dotnet, backenddeveloper, microsoftazure, interviewprep, msdevbuild
- **Canonical URL:** https://blog.msdevbuild.com/shorts/azure-sql-idempotency-duplicate-order/

---
## What you'll learn

- Why a double tap or a retry after a timeout creates two orders
- What an idempotency key is, and why the app has to create it
- How a unique index in Azure SQL stops the duplicate, on any server

## Understand it one step at a time

### 1. One tap, two orders

A double tap sends the same order twice, to two different servers.

### 2. Or a slow network

The order succeeds at 10.4 s. The app gave up at 10 s and says "try again".

### 3. The server can't tell

Same user, same cart, same total. Nothing says the two requests are one order.

### 4. Disable the button?

It stops a double tap. A retry after a timeout still gets through.

### 5. One key per order

The app creates a random key when checkout starts. Every retry reuses it.

### 6. The database decides

A unique index on (UserId, IdempotencyKey). The second insert fails with 2601.

### 7. Return the same order

The repeat gets the original order back. Nothing is inserted twice.

### 8. Charge once

The payment gateway gets the same key, so even a resent charge counts once.

### 9. The next Friday

Slow gateway again. 311 retries, all answered with the saved order.

### 10. Let the database decide

A key from the app. A unique index in Azure SQL. One order per tap.

---

## The takeaway

**One tap. One order. Let the database decide.**

Send an idempotency key from the app, and enforce it with a unique index in Azure SQL.
