Preventing Order Loss and Duplicate Submissions in Payment Systems
This article explains the typical payment flow, identifies causes of external and internal order loss, and provides concrete backend strategies—including intermediate payment states, timeout queries, idempotent handling, retry mechanisms, and Redis‑based duplicate‑submission protection—to ensure reliable order processing.
The simplified order process starts with order submission, followed by payment through a payment gateway that interacts with third‑party channels such as WeChat, Alipay, or UnionPay. After a successful payment, an asynchronous notification updates the payment order status, which then notifies the business application to update its own order status.
Common issues arise when notifications are missed or errors occur, leading to "order loss" where the user has paid but the server does not reflect the updated status. Loss caused by external factors (e.g., missing callbacks) is called external order loss, while loss caused by internal errors is internal order loss.
To prevent order loss, the article recommends:
Add an intermediate state "Paying" to the payment order, lock the pre‑pay process, and only change to "Paid" after successful completion.
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 if the result remains unknown.
Synchronize the payment result to the business system via MQ or direct calls, adding retry logic (e.g., SpringBoot Retry) for direct calls.
Ensure idempotency on both the payment center and business side so that each notification is processed only once.
The business application should also perform proactive timeout queries for payment results.
Store pending payment orders in a dedicated table and use a scheduled task to scan and process them.
To avoid duplicate order submissions, compute a hash of the order data and check Redis for an existing key; if the key exists, reject the duplicate, otherwise create a new key with an expiration time before creating the order.
The article concludes with a reference to WeChat Pay best practices (illustrated in the original image).
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
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.