Backend Development 6 min read

Preventing Order Loss and Duplicate Submissions in Payment Systems: Best Practices

This article explains the typical order‑payment flow, identifies external and internal causes of lost orders, and provides concrete backend strategies—such as adding a "payment‑in‑progress" state, timeout‑based query retries, idempotent handling, and Redis‑based duplicate‑submission protection—to ensure reliable order processing and avoid duplicate payments.

Top Architect
Top Architect
Top Architect
Preventing Order Loss and Duplicate Submissions in Payment Systems: Best Practices

The article begins with a simplified order flow: a user submits an order, then proceeds to payment via a payment gateway that interacts with third‑party channels (WeChat, Alipay, UnionPay). After payment, the gateway sends an asynchronous notification to update the payment order status, which in turn notifies the business application to update its own order status.

During this process, "order loss" can occur when callbacks are missed, time‑outs happen, or the application throws errors, resulting in a successful payment that is not reflected in the server‑side order state. Such loss may lead to user complaints or duplicate payments. The article distinguishes external order loss (caused by third‑party issues) from internal order loss (caused by the business system).

Preventing order loss:

Introduce an intermediate status "payment in progress" for each order and lock the pre‑pay operation; after successful payment, transition the status to "payment successful".

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) and handle exceptions if the maximum attempts are exhausted.

When the payment center receives the result, propagate it to the business system via MQ or direct calls, adding retry mechanisms such as SpringBoot Retry.

Ensure idempotent handling of payment notifications on both the payment center and business side so that each message is processed only once.

Business applications should also perform proactive timeout queries for payment results.

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

Preventing duplicate order submissions:

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 request, otherwise store the key with an expiration and proceed with order creation.

The article concludes by encouraging readers to discuss the ideas, share questions, and explore additional resources such as interview question collections and best‑practice guides.

BackendBest PracticesIdempotencypaymentWeChat Payduplicate submissionorder loss
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn 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.