{"record":{"id":"cd87b76718629e7e","repo":"paascloud/paascloud-master","slug":"omc10031004","errorCode":"OMC10031004","errorMessage":"OMC10031004","messagePattern":"OMC10031004","errorType":"error_code","errorClass":"OmcBizException","httpStatus":null,"severity":"error","filePath":"paascloud-provider/paascloud-provider-omc/src/main/java/com/paascloud/provider/service/impl/OmcOrderServiceImpl.java","lineNumber":134,"sourceCode":"\t\tthis.reduceProductStock(omcOrderDetailList);\n\t\t//清空一下购物车\n\t\tthis.cleanCart(cartList);\n\n\t\t//返回给前端数据\n\n\t\treturn assembleOrderVo(order, omcOrderDetailList);\n\t}\n\n\t@Override\n\tpublic int cancelOrderDoc(LoginAuthDto loginAuthDto, String orderNo) {\n\t\tLong userId = loginAuthDto.getUserId();\n\t\tOmcOrder order = omcOrderMapper.selectByUserIdAndOrderNo(userId, orderNo);\n\t\tif (order == null) {\n\t\t\tlogger.error(\"该用户此订单不存在, userId={}, orderNo={}\", userId, orderNo);\n\t\t\tthrow new OmcBizException(ErrorCodeEnum.OMC10031003);\n\t\t}\n\t\tif (order.getStatus() != OmcApiConstant.OrderStatusEnum.NO_PAY.getCode()) {\n\t\t\tthrow new OmcBizException(ErrorCodeEnum.OMC10031004);\n\t\t}\n\t\tOmcOrder updateOrder = new OmcOrder();\n\t\tupdateOrder.setId(order.getId());\n\t\tupdateOrder.setStatus(OmcApiConstant.OrderStatusEnum.CANCELED.getCode());\n\n\t\treturn omcOrderMapper.updateByPrimaryKeySelective(updateOrder);\n\t}\n\n\t@Override\n\tpublic PageInfo queryUserOrderListWithPage(Long userId, BaseQuery baseQuery) {\n\t\tPageHelper.startPage(baseQuery.getPageNum(), baseQuery.getPageSize());\n\t\tList<OmcOrder> orderList = omcOrderMapper.selectByUserId(userId);\n\t\tList<OrderVo> orderVoList = assembleOrderVoList(orderList, userId);\n\t\treturn new PageInfo<>(orderVoList);\n\t}\n\n\t@Override\n\tpublic boolean queryOrderPayStatus(Long userId, String orderNo) {","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/paascloud/paascloud-master/blob/781281a9503332ed3cef44ea618349d14230a127/paascloud-provider/paascloud-provider-omc/src/main/java/com/paascloud/provider/service/impl/OmcOrderServiceImpl.java#L116-L152","documentation":"OmcBizException with ErrorCodeEnum.OMC10031004 (code 10031004, message \"已付款, 无法取消订单\" / order already paid, cannot cancel). Thrown by cancelOrderDoc when the order exists but its status is not NO_PAY (unpaid); only unpaid orders may be cancelled via this API.","triggerScenarios":"Calling cancelOrderDoc on an order whose status is PAID, SHIPPED, CANCELED, or any state other than OmcApiConstant.OrderStatusEnum.NO_PAY; a payment callback flipped the order to PAID between the user viewing it and clicking cancel.","commonSituations":"User pays in one tab then cancels in another; race between payment success callback and manual cancellation; client UI showing stale unpaid status; attempting to cancel shipped/completed orders instead of using a refund flow.","solutions":["Check order status before calling cancel (order.getStatus() == NO_PAY) and hide the cancel option otherwise.","If the order is already paid, use the refund/return flow instead of cancellation.","Reload the order status to get the latest state; the frontend may be showing stale data.","Retry-safe handling: treat OMC10031004 as an expected business outcome and surface 'order already paid' to the user."],"exampleFix":"// before\norderService.cancelOrderDoc(loginAuthDto, orderNo); // throws if paid\n// after\nOmcOrder order = orderService.queryByUserIdAndOrderNo(userId, orderNo);\nif (order.getStatus() == OmcApiConstant.OrderStatusEnum.NO_PAY.getCode()) {\n    orderService.cancelOrderDoc(loginAuthDto, orderNo);\n} else {\n    log.info(\"Order {} not cancellable, status={}\", orderNo, order.getStatus());\n}","handlingStrategy":"validation","validationCode":"OmcOrder order = orderService.queryByUserIdAndOrderNo(userId, orderNo);\nif (order == null || order.getStatus() != OmcApiConstant.OrderStatusEnum.NO_PAY.getCode()) {\n    throw new IllegalStateException(\"order \" + orderNo + \" is not in cancellable (NO_PAY) state\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    orderService.cancelOrderDoc(loginAuthDto, orderNo);\n} catch (OmcBizException e) {\n    if (e.getCode() == 10031004) {\n        // already paid: route user to refund flow instead of cancel\n    } else { throw e; }\n}","preventionTips":["Only render the cancel button when the latest server-side status is NO_PAY.","Re-check status right before cancelling to avoid pay/cancel races.","Route paid orders to the refund flow, never to cancel.","Treat 10031004 as an expected business outcome and show a clear 'already paid' message."],"tags":["order","cancel","status-conflict","business-exception"],"backgroundTag":"invalid-state-transition","analyzedSha":"781281a9503332ed3cef44ea618349d14230a127","analyzedAt":"2026-09-10T10:59:02.070Z","contentChangedAt":"2026-09-10T10:59:02.070Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}