A Refund Page That Only Handles Full Orders: 200 Complaints in 3 Days
Last year Q3, we had an incident in production. It wasn't a white screen, an API error, or broken styles. The page ran fine, features were smooth, Sentry reported zero errors, and automated tests were all green. But customer service received more than 200 complaint tickets within three days. The content was all similar: I only wanted to return two items, why did the system return the entire order?
Root Cause Analysis
We spent two days investigating and when we finally located the cause, the whole tech team went silent: the code had no technical bug. API calls were correct, parameters passed correctly, state updates correct, UI rendering correct.
The problem: the frontend engineer who wrote this refund page never knew that partial refunds exist.😖
He got the requirements document, saw the refund feature, and the model in his head was: user clicks refund → call API → return entire order → jump to success page. So he wrote a clean and elegant refund flow, high code quality, nicely split components, meticulous TypeScript types.
But he never asked: is the refund for the entire order or can it be per item? Does shipping get refunded? Is there a refund cap? How are used coupons split?
The PM's requirements document did say partial refunds are supported, but it was hidden in a collapsed notes field. During Code Review, the reviewer looked at the code logic: call refund API, pass order ID, handle response, logical consistency, no problem. The test cases also followed the path of initiating refund → refund success.
Every step was right, but the result was wrong.
This is the scariest part of frontend not understanding business: it creates not a technical bug, but a business incident. And the cost of a business incident is far more severe than a white screen.🫡
Technical bugs have safety nets, business bugs don't
A TypeError is caught by Error Boundary, reported by Sentry, spotted by a colleague in code review.
But a business logic error is transparent to all automated defenses.
ESLint won't tell you to pass orderItemIds instead of orderId. TypeScript won't tell you refund amount should allow manual modification. Jest unit tests only verify that your logic runs as you understand it; but if your understanding itself is wrong, then 100% test pass just verifies a wrong implementation 100%.
I've worked in big companies and cross-border e-commerce teams, and I've seen far more business logic bugs than technical bugs. They share a common trait: nobody finds them before launch, and users are the first to discover them after launch.
Why frontend easily falls into not understanding business?
These bugs are not because frontend devs are stupid, but because the working pattern of frontend roles in China naturally creates this problem.
How to break it? Some practices I actually pushed in my team
These aren't methodologies, just crude tricks forced out after getting burned.
Requirement review must go in with questions
I require my frontend devs to read the PRD before attending requirement review and bring at least 3 questions into the meeting. If you can't ask questions, it means you haven't read it, or your business understanding is superficial.
The direction of questions is fixed:
Key business logic must have comments
Not technical comments, but business comments.
/**
* 退款金额计算逻辑:
* - 部分退支持退单个商品,退款金额 = 商品实付价(分摊优惠后)
* - 运费只在整单全退时才退
* - 已使用的优惠券按商品金额比例分摊扣回
* - 退款金额上限 = 该商品的实付金额,不能超出
*
* 业务文档: https://wiki.internal/refund-rules-v3
* 最后确认人: 产品经理阿良 2026-08-15
*/
function calculateRefundAmount(
orderItem: OrderItem,
order: Order,
): number {
// ...
}
// 计算退款金额
function calculateRefundAmount(item: OrderItem, order: Order): number {
// ...
}
The first comment, even if the author leaves, the successor can understand in 30 seconds why we divide by total amount and multiply by item amount: because coupons are split proportionally.
The second comment is as good as none.
Test cases must cover business scenarios, not just code branches
Most frontend devs write tests by code branch: if branch left, test it, branch right, test it, 100% coverage, done.
But business bugs are often not about code branches, but that you never wrote that branch. In the refund example, the engineer's code never had a partial refund branch, so 100% coverage didn't help.
So now I require key business modules' test cases to be written by business scenario, not by code logic:
describe('退款流程', () => {
// 按业务场景组织,而不是按函数名组织
it('单个商品退款:只退选中商品,不影响其他商品状态', () => { /* ... */ });
it('整单退款:所有商品退回,运费一并退回', () => { /* ... */ });
it('含优惠券订单的部分退:优惠金额按比例分摊扣回', () => { /* ... */ });
it('退款金额不能超过该商品的实付金额', () => { /* ... */ });
it('已发货商品退款需要走退货流程,不能直接退款', () => { /* ... */ });
});
Such test cases are understandable by PMs. During review, have the PM look at your test scenarios, and missing business branches are exposed immediately.
After leading a team for a few years, I'm increasingly convinced of one thing: a frontend engineer's salary ceiling is not determined by his depth of understanding of React or Vue, but by his depth of understanding of the business domain.
Frontend devs who write good code are everywhere. But a frontend who can point out during requirement review that this refund flow is missing the partial refund scenario, who can say during technical design that this inventory display needs to consider locked inventory: such people are maybe one or two in the whole team.
Their code may not be the prettiest, but the features they write won't get user complaints after launch, won't make customer service work overtime, won't lose the company money!
Do you agree?
喜欢我的文章,也欢迎关注我的微信公众号:【前端技术官】。
主要分享:前端架构 · AI 编程 · 职场认知 · 开发者成长
微信扫码关注 👆
不定期更新,不刷屏,聊点真正有用的干货。
Top 9 of 14 from juejin.cn, machine-translated. The original thread is authoritative.
Layoffs: What are you mumbling about?
Last year, Yihaodian's app had this same bug—refunds could only be for the entire order. Hilarious.
This script has too many plot holes [facepalm]
Here I am, submitting my homework [thumbs up]
So fast!!!
Many companies' internal business requirement review meetings don't require design or frontend developers to attend. A significant number of backend and product people view UI as merely how good the page looks, and their understanding of frontend is—just an 'image slicing kid'.
How can this be blamed on the frontend missing it? Clearly, aside from the product manager, nobody knew about partial refunds. The product manager probably misses things often, and developers are too lazy to even bring it up. Something this obvious, and it still gets missed?
First, the product's business requirements weren't clear, and no step in the entire development process raised any objection. The whole scapegoat is put on the frontend alone.
Genuine question: what tool was used to generate this comic-style image?
GPT
1. Didn't the product review mention partial refunds? 2. Didn't test cases cover partial refunds? 3. During acceptance, didn't the product verify its own partial refund requirement? 4. Did the backend even implement partial refunds?
Indeed
The frontend missed it.