paascloud/paascloud-master · error · OmcBizException
OMC10031004
OMC10031004
Error message
OMC10031004
What it means
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.
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.
Example fix
// before
orderService.cancelOrderDoc(loginAuthDto, orderNo); // throws if paid
// after
OmcOrder order = orderService.queryByUserIdAndOrderNo(userId, orderNo);
if (order.getStatus() == OmcApiConstant.OrderStatusEnum.NO_PAY.getCode()) {
orderService.cancelOrderDoc(loginAuthDto, orderNo);
} else {
log.info("Order {} not cancellable, status={}", orderNo, order.getStatus());
} Defensive patterns
Strategy: validation
Validate before calling
OmcOrder order = orderService.queryByUserIdAndOrderNo(userId, orderNo);
if (order == null || order.getStatus() != OmcApiConstant.OrderStatusEnum.NO_PAY.getCode()) {
throw new IllegalStateException("order " + orderNo + " is not in cancellable (NO_PAY) state");
} Try / catch
try {
orderService.cancelOrderDoc(loginAuthDto, orderNo);
} catch (OmcBizException e) {
if (e.getCode() == 10031004) {
// already paid: route user to refund flow instead of cancel
} else { throw e; }
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
AI-assisted analysis of paascloud/paascloud-master@781281a950 (2026-09-10).
Data as JSON: /api/errors/cd87b76718629e7e.
Report an issue: GitHub.
Appendix: source
Thrown at paascloud-provider/paascloud-provider-omc/src/main/java/com/paascloud/provider/service/impl/OmcOrderServiceImpl.java:134
this.reduceProductStock(omcOrderDetailList);
//清空一下购物车
this.cleanCart(cartList);
//返回给前端数据
return assembleOrderVo(order, omcOrderDetailList);
}
@Override
public int cancelOrderDoc(LoginAuthDto loginAuthDto, String orderNo) {
Long userId = loginAuthDto.getUserId();
OmcOrder order = omcOrderMapper.selectByUserIdAndOrderNo(userId, orderNo);
if (order == null) {
logger.error("该用户此订单不存在, userId={}, orderNo={}", userId, orderNo);
throw new OmcBizException(ErrorCodeEnum.OMC10031003);
}
if (order.getStatus() != OmcApiConstant.OrderStatusEnum.NO_PAY.getCode()) {
throw new OmcBizException(ErrorCodeEnum.OMC10031004);
}
OmcOrder updateOrder = new OmcOrder();
updateOrder.setId(order.getId());
updateOrder.setStatus(OmcApiConstant.OrderStatusEnum.CANCELED.getCode());
return omcOrderMapper.updateByPrimaryKeySelective(updateOrder);
}
@Override
public PageInfo queryUserOrderListWithPage(Long userId, BaseQuery baseQuery) {
PageHelper.startPage(baseQuery.getPageNum(), baseQuery.getPageSize());
List<OmcOrder> orderList = omcOrderMapper.selectByUserId(userId);
List<OrderVo> orderVoList = assembleOrderVoList(orderList, userId);
return new PageInfo<>(orderVoList);
}
@Override
public boolean queryOrderPayStatus(Long userId, String orderNo) {View on GitHub (pinned to 781281a950)