Backend Development 5 min read

Preventing Order Loss and Duplicate Submissions in Payment Systems

This article explains the typical payment order flow, identifies external and internal causes of order loss, and provides concrete backend strategies—such as intermediate payment states, timeout queries, idempotent handling, retry mechanisms, and Redis‑based duplicate‑submission protection—to ensure reliable order processing.

Java Architect Essentials
Java Architect Essentials
Java Architect Essentials
Preventing Order Loss and Duplicate Submissions in Payment Systems

The article outlines a simplified order‑placement process: a user submits an order, the system forwards the request to a payment gateway, which interacts with third‑party channels (WeChat, Alipay, UnionPay). After a successful payment, the gateway sends an asynchronous notification, updates its own status, and notifies the business application to update the order state.

Order loss can occur when callbacks are missed or internal errors happen, leading to situations where payment succeeds but the server does not update the order status, potentially causing complaints or duplicate payments. Losses caused by external factors (steps ③ and ⑤) are called external order loss; those caused by internal factors (steps ④ and ⑥) are internal order loss.

Prevention measures for order loss:

Introduce an intermediate status “Paying” for payment orders. When a payment is initiated, check for an existing “Paying” record and lock the pre‑pay operation. After payment succeeds, change the status to “Paid”.

Define a timeout (e.g., 30 seconds) in the payment center. If no success callback is received within this window, actively query the payment result at intervals (10 s, 20 s, 30 s). If the maximum number of queries is reached without a result, trigger an exception handling flow.

When the payment center receives the result, propagate it to the business system via MQ or direct calls; direct calls should include retry logic (e.g., SpringBoot Retry).

Both the payment center and business applications must enforce idempotency on result notifications, processing each message only once.

The business application should also perform active timeout queries for payment results.

Active timeout queries can be scheduled by storing pending payment orders in a dedicated table and scanning it with a periodic task.

Prevention measures for duplicate order submission:

When creating an order, compute a hash of the order data and check Redis for an existing key. If the key exists, reject the duplicate; otherwise, store the key with an expiration time and proceed with order creation, ensuring the same operation cannot be repeated within the set window.

The article also includes a visual “WeChat Pay Best Practices” diagram (image omitted) and concludes with a call to share the content and join a technical community for further learning.

backendRetryIdempotencypaymenttimeoutOrder Managementduplicate submission
Java Architect Essentials
Written by

Java Architect Essentials

Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.