How to Prevent Lost Payments and Duplicate Orders in Backend Systems
This article explains the typical order‑to‑payment flow, identifies why payments can be lost or duplicated, and provides concrete backend strategies—such as intermediate payment states, timeout queries, idempotent notifications, and Redis‑based duplicate‑submission checks—to ensure reliable order processing.
Payment Flow Overview
When a user places an order, the system first creates the order, then forwards the request to a payment gateway (e.g., WeChat, Alipay, UnionPay). The gateway interacts with the third‑party channel, and upon success sends an asynchronous notification back to the payment center, which updates its own order status and then notifies the business application to update its order status.
Common Issue: Lost Orders
If the notification is not received or processing fails, the payment may be successful but the server’s order status remains unchanged, leading to complaints or duplicate payments. Such lost orders caused by external factors (gateway timeouts, network failures) are called “external lost orders”; those caused by internal errors (application exceptions, missing callbacks) are “internal lost orders”.
Prevention Measures
1. Add an intermediate state “paying” to the payment order and lock the record while creating the pre‑pay request; after the payment completes, change the state to “paid”.
2. Define a timeout (e.g., 30 seconds) in the payment center; if no success callback is received within the window, actively query the payment result at intervals (10 s, 20 s, 30 s) and handle exceptions after the maximum attempts.
3. When the payment center receives the result, forward it to the business system via MQ or direct call with retry logic (e.g., SpringBootRetry).
4. Ensure idempotency of the notification interface so that each message is processed only once.
5. Business applications should also perform proactive timeout queries for payment results.
Preventing Duplicate Submissions
Generate a hash of the order data and store it as a key in Redis with an expiration time; if the key already exists, reject the request, otherwise create the order and set the key.
WeChat Pay Best Practices
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Backend Technology
Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
