{"record":{"id":"129f789cc862b7d0","repo":"binarywang/WxJava","slug":"paymode-pay-mode-store-null-wxstoreid","errorCode":null,"errorMessage":"payMode是PAY_MODE_STORE或null时，必须传递wxStoreId","messagePattern":"payMode是PAY_MODE_STORE或null时，必须传递wxStoreId","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"warning","filePath":"weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaIntracityServiceImpl.java","lineNumber":174,"sourceCode":"      getFlowInstanceByType(int flowType) {\n    WxMaStoreFlowResponse<? extends WxMaStoreFlowResponse.BasicFlowRecord> inst;\n    if (flowType == 1) {\n      inst = new WxMaStoreFlowResponse<WxMaStoreFlowResponse.ChargeFlowRecord>();\n    } else if (flowType == 2) {\n      inst = new WxMaStoreFlowResponse<WxMaStoreFlowResponse.RefundFlowRecord>();\n    } else if (flowType == 3) {\n      inst = new WxMaStoreFlowResponse<WxMaStoreFlowResponse.ConsumeFlowRecord>();\n    } else {\n      return null;\n    }\n    return inst;\n  }\n\n  @Override\n  public WxMaStoreBalance balanceQuery(String wxStoreId, String serviceTransId, PayMode payMode)\n      throws WxErrorException {\n    if (wxStoreId == null && (payMode == null || payMode == PayMode.STORE)) {\n      throw new IllegalArgumentException(\"payMode是PAY_MODE_STORE或null时，必须传递wxStoreId\");\n    }\n    Map<String, Object> request = new HashMap<>();\n    if (wxStoreId != null) {\n      request.put(\"wx_store_id\", wxStoreId);\n    }\n    if (serviceTransId != null) {\n      request.put(\"service_trans_id\", serviceTransId);\n    }\n    if (payMode != null) {\n      request.put(\"pay_mode\", payMode);\n    }\n    String response = this.wxMaService.postWithSignature(Intracity.BALANCE_QUERY, request);\n    WxMaStoreBalance balance = gson.fromJson(response, WxMaStoreBalance.class);\n    logger.debug(\"balance: {}\", balance);\n    return balance;\n  }\n\n  public void setPayMode(PayMode payMode) throws WxErrorException {","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/binarywang/WxJava/blob/1c43293a3c2c9d7e91304b6d037fb017f680d0c6/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaIntracityServiceImpl.java#L156-L192","documentation":"Unchecked IllegalArgumentException from balanceQuery(wxStoreId, serviceTransId, payMode) when wxStoreId == null AND (payMode == null OR payMode == PayMode.STORE). In STORE mode (PAY_MODE_STORE), and in the unspecified/default case, balance is held per-store so the store must be identified. In APP (PAY_MODE_APP) or COMPONENT (PAY_MODE_COMPONENT) mode the balance sits at the mini-program/service-provider level, so wxStoreId may be null.","triggerScenarios":"Calling balanceQuery(null, serviceTransId, PayMode.STORE) or balanceQuery(null, anything, null).","commonSituations":"Defaulting payMode to null in a 'query my balance' flow without realizing null is treated as STORE; querying app/component balance but forgetting to pass PayMode.APP or PayMode.COMPONENT explicitly.","solutions":["Pass wxStoreId whenever querying in STORE mode or when leaving payMode null.","For app/component-level balance, pass PayMode.APP or PayMode.COMPONENT explicitly."],"exampleFix":"// before\nintracityService.balanceQuery(null, null, null);\n\n// after\nintracityService.balanceQuery(wxStoreId, null, PayMode.STORE);","handlingStrategy":"validation","validationCode":"if (wxStoreId == null && (payMode == null || payMode == PayMode.STORE)) {\n  throw new IllegalArgumentException(\"wxStoreId required for STORE/null pay mode\");\n}","typeGuard":"// Resolve effective pay mode before calling\nPayMode effective = (payMode == null) ? PayMode.STORE : payMode;\nboolean storeBalanceNeedsId = (effective == PayMode.STORE);","tryCatchPattern":"try {\n  balance = intracityService.balanceQuery(wxStoreId, svcId, payMode);\n} catch (IllegalArgumentException e) {\n  throw e;\n}","preventionTips":["Never leave payMode implicit when wxStoreId is null — pass APP or COMPONENT explicitly.","Resolve a default payMode at the config layer so callers cannot accidentally fall into the STORE branch."],"tags":["validation","intracity","balance","pay-mode","illegal-argument","null-check"],"backgroundTag":null,"analyzedSha":"1c43293a3c2c9d7e91304b6d037fb017f680d0c6","analyzedAt":"2026-08-14T02:29:11.060Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}