Free tools Windows power users keep installed
One-click scans. No signup required.
To reduce duplicate charges when a payment agent retries, use two separate safeguards: a durable database uniqueness constraint to stop the same event from running through your local workflow twice, and the payment provider’s idempotency key to make retries of the same remote payment mutation safe. Neither makes the database and provider one atomic system. You still need a recovery path for a crash after the provider succeeds but before your service records the result.
What UNIQUE(event_id) prevents—and what it does not
A database constraint such as UNIQUE(event_id) can prevent two workers from claiming the same event identity in the same protected workflow. It is a local deduplication rule: it does not, by itself, stop two different event IDs from representing the same intended charge, nor does it prevent a payment provider from receiving the same mutation more than once.
As an Amazon Associate I earn from qualifying purchases.
The key design question is what an ID identifies. A webhook delivery event, the business operation “charge this order,” and a provider API request are different identity boundaries. They may use related identifiers, but they are not interchangeable. If two separate events can request the same charge, deduplicating only by event ID will not enforce the business rule “charge this order once.”
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Amazon Web Services’ Idempotency and retries guidance recommends writing events with a deterministic event ID. That supports stable event-level deduplication, but your application must decide which identifier represents the intended payment operation and enforce that invariant at the right boundary.
#1 Best Overall
- With Square Terminal, you can ring up sales, accept payments, and print receipts, all with one device. Use it at the counter or ring up customers anywhere in your store.
- Accept all major credit and debit cards and pay one low rate with no hidden fees and no long-term contracts.
- Process chip cards in just two seconds.
- Get your money as soon as the next business day.
- Use it cordlessly with the built-in battery, designed to last all day.
Use a local uniqueness gate and a provider key together
| Control | Identity it protects | What it does | What it does not do |
|---|---|---|---|
| Database uniqueness constraint or event ledger | A locally handled event identity, or a business-operation identity if you choose that as the unique key | Allows one durable claim for that key; a conflicting insert can be treated as a duplicate rather than permission to repeat work. | It cannot make a remote provider call atomic with a local database write. |
| Provider idempotency key | A particular intended provider-side mutation | Lets the provider recognize a retry as the same request under that provider’s contract. | It does not deduplicate local fulfillment, credits, notifications, or a different operation key. |
| Recovery and reconciliation | An attempt whose outcome is uncertain to your service | Resolves or safely retries work when the provider and local state may disagree. | It is not replaced by either uniqueness control alone. |
Stripe’s Idempotent requests documentation describes replaying the saved result for subsequent requests with the same key. Adyen’s API idempotency documentation says a timeout retry can safely resend the same request key without duplicating the payment. These controls address the remote request boundary; the event ledger addresses local processing.
Build the retry-safe flow in this order
- Choose stable identities. Record the incoming event ID, the business operation ID, and the provider request key as distinct values where their meanings differ. Reuse the same operation identity for retries of that intended charge. This is an architectural choice, not a universal identifier scheme prescribed by the providers.
- Claim work durably before non-repeatable local effects. Insert the event or operation key into a table protected by a database-enforced unique constraint. Treat a uniqueness conflict as evidence that this key has already been claimed; do not proceed with the protected side effect just because another worker is handling it. A separate “check, then insert” read is not a substitute for an enforced constraint under concurrent workers.
- Persist an in-progress state, then call the provider. Store enough information to resume or reconcile the attempt. Avoid treating an in-memory flag as the durable record that work began. Keep the provider call and local state transition coordinated through an explicit recovery design; a local transaction cannot roll back a provider’s completed charge.
- Send the same provider key on retries of the same mutation. Do not mint a fresh key for each transport retry. Keep the request parameters consistent with the provider’s rules. A changed amount or other changed parameters may no longer represent the same request.
- Record the outcome and make downstream effects idempotent too. Persist the provider result and the local payment state. Guard separate effects—such as fulfillment, account credit, or customer notification—at their own boundaries, since provider idempotency does not automatically protect them.
- Reconcile uncertain attempts. If your worker times out or crashes after sending a request, determine whether the provider completed it before deciding what to do next. When retrying the same payment attempt, use its original provider key within the provider’s supported window; do not turn uncertainty into a new charge with a new key.
Plan for the gap between remote success and local persistence
Consider this sequence: the worker claims the event, sends the payment request, the provider completes the charge, and the worker crashes before saving the provider response. Your database may still show “in progress,” while the payment exists remotely. Reprocessing the event without a stable provider key can create a second charge; refusing to retry forever can leave the local workflow stuck.
Rank #2
- Use the, easy-to-use, and customizable POS to get started.
- Accept contactless payments, chip cards, Apple Pay, and Google Pay from anywhere, with improved connectivity, extended battery life, and enhanced security. Pay one low rate for every tap or dip.
- No long-term commitments or contracts, no monthly fees- and with offline payments, keep taking payments for up to 24 hours.
- Safely and securely accepts payments anywhere. Plus, get data security, 24/7 fraud prevention, and payment-dispute management at no extra cost.
- Use the, easy-to-use, and customizable POS to get started.
Persist a state that distinguishes at least an accepted or in-progress attempt from a completed outcome, and retain the event or operation identity, the provider key, and the information needed to match the attempt to the provider’s result. On recovery, retry with the same provider key when its contract permits, or use the provider’s available status and reconciliation mechanisms before creating another mutation. The precise status lookup and reconciliation mechanisms depend on the provider and are not established by the cited idempotency guidance.
A unique event record can stop a duplicate delivery from launching an unguarded second workflow, but it cannot by itself tell you whether an interrupted remote call succeeded. That uncertain outcome needs explicit handling rather than a blanket “already seen” response or a new payment attempt.
Rank #3
- With Square Handheld, you can accept payments, take tableside orders, or scan barcodes anywhere. With a slim design and comfortable grip, the POS is easy to carry in your palm or pocket. Square Handheld is designed to withstand water splashes and dust. Add an optional protective case for accidental drops. A long-lasting battery and offline payments let you keep selling.
- Slim, pocketable, and lightweight so you can accept payments wherever your customers are.
- Take tableside orders, bust lines, or use the built-in barcode scanner, all with one sleek device.
- A battery that can power through your shift and offline payments let you keep selling, even if your internet is down.
- Accept all major credit and debit cards and pay one simple rate with no hidden fees and no long-term contracts required.
Provider key windows and behavior differ
The following operational details are from the current official documentation accessed on October 7, 2026. They are provider-specific, not general payment-industry guarantees; the documents did not provide publication dates.
| Provider | Key duration or limit | Scope and retry behavior |
|---|---|---|
| Stripe | Keys may be removed after they are at least 24 hours old. Maximum key length: 255 characters. | Stripe compares request parameters and returns an error if a key is reused with different parameters. It saves a result once endpoint execution begins, including failed status results; validation failures and concurrent execution conflicts are not saved as idempotent results. Reusing a pruned key can initiate a new request. |
| Adyen | Keys remain valid for a period of 7 to 14 days after first submission. Maximum key length: 64 characters. | Keys are stored at company-account level and are not checked for duplicates across regional endpoints. Retry later with the same key for a transient error only when the response marks the error transient. A duplicate arriving while the first request is processing can return a conflict or unprocessable response. |
Because the provider key can expire or have a limited scope, retain a local event or operation ledger for the replay and audit period your application requires. Do not assume that a provider key lasts forever or applies across regions.
Quick Recap
Best Value
- A complete countertop point of sale — Combine dual responsive touchscreens, built-in POS software, and durable hardware for a fast, reliable checkout experience.
- Serve customers faster — Run smoothly through busy shifts, complex menus, and big orders with high-speed processing, memory, and responsive touchscreen displays.
- Accept every way they pay — Take all major cards at one simple rate, with no hidden fees or long-term contracts. Receive funds as soon as the next business day.
- Handle real-world demands — Resist everyday spills, dust, and wear with a durable, IP54-rated design.
- Stay reliable through every rush — Maintain strong connectivity and consistent performance through your busiest hours.
Rank #4
- The Clover Compact and Clover Mini /Station sync with each other through the Clover Dashboard and cloud-based network. This allows you to manage transactions, track sales, and access business data across both devices seamlessly. Plug in, not battery/mobile. Requires New Processing account through Powering POS. (US, PR, USVI). CANNOT be used with a different Processor. Rate match guarantee. Contact us for questions
Failure modes to guard against
- Distinct events, same business intent: Two event IDs can still ask for the same order or payment. Enforce uniqueness on the business-operation key if that is the actual “once” rule.
- Two workers race: A read-before-write check can let both workers observe “not processed.” Let the database constraint arbitrate the claim and handle the conflicting insert as a duplicate.
- Provider succeeded, worker lost the response: Use the same provider key to retry the same attempt where allowed, and reconcile the uncertain outcome instead of issuing a new mutation.
- Provider returned a non-retryable or special response: Follow the provider’s response-specific rules. Stripe does not save every validation failure or concurrent conflict as an idempotent result; Adyen’s documented transient-error retry guidance applies when the response marks the error transient.
- Local side effect repeats: Provider idempotency is not a substitute for guarding fulfillment, crediting, or notifications. Give each independently repeatable effect its own idempotency boundary.
- Separate payment sessions: Adyen notes that separate sessions can appear as unique requests with separate PSP references; its support guidance says API idempotency can help avoid duplicate payments. A separate session is not made equivalent to an earlier request merely by a local event constraint.
A practical design checklist
- Identify whether each key means a delivery, a business operation, or a provider mutation.
- Make the local claim durable and database-enforced before the protected side effect.
- Define how duplicate claims are acknowledged without rerunning work.
- Reuse the provider key for retries of the same intended mutation, and follow that provider’s parameter, scope, expiration, and error rules.
- Persist enough attempt state to recover after a timeout or process crash.
- Guard fulfillment and other local side effects independently.
- Set a reconciliation policy for attempts whose remote outcome cannot be inferred from local state.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →




