binarywang/WxJava · warning · IllegalArgumentException

payMode是PAY_MODE_STORE或null时,必须传递wxStoreId

Error message

payMode是PAY_MODE_STORE或null时,必须传递wxStoreId

What it means

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.

Source

Thrown at weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaIntracityServiceImpl.java:174

      getFlowInstanceByType(int flowType) {
    WxMaStoreFlowResponse<? extends WxMaStoreFlowResponse.BasicFlowRecord> inst;
    if (flowType == 1) {
      inst = new WxMaStoreFlowResponse<WxMaStoreFlowResponse.ChargeFlowRecord>();
    } else if (flowType == 2) {
      inst = new WxMaStoreFlowResponse<WxMaStoreFlowResponse.RefundFlowRecord>();
    } else if (flowType == 3) {
      inst = new WxMaStoreFlowResponse<WxMaStoreFlowResponse.ConsumeFlowRecord>();
    } else {
      return null;
    }
    return inst;
  }

  @Override
  public WxMaStoreBalance balanceQuery(String wxStoreId, String serviceTransId, PayMode payMode)
      throws WxErrorException {
    if (wxStoreId == null && (payMode == null || payMode == PayMode.STORE)) {
      throw new IllegalArgumentException("payMode是PAY_MODE_STORE或null时,必须传递wxStoreId");
    }
    Map<String, Object> request = new HashMap<>();
    if (wxStoreId != null) {
      request.put("wx_store_id", wxStoreId);
    }
    if (serviceTransId != null) {
      request.put("service_trans_id", serviceTransId);
    }
    if (payMode != null) {
      request.put("pay_mode", payMode);
    }
    String response = this.wxMaService.postWithSignature(Intracity.BALANCE_QUERY, request);
    WxMaStoreBalance balance = gson.fromJson(response, WxMaStoreBalance.class);
    logger.debug("balance: {}", balance);
    return balance;
  }

  public void setPayMode(PayMode payMode) throws WxErrorException {

View on GitHub (pinned to 1c43293a3c)

Solutions

  1. Pass wxStoreId whenever querying in STORE mode or when leaving payMode null.
  2. For app/component-level balance, pass PayMode.APP or PayMode.COMPONENT explicitly.

Example fix

// before
intracityService.balanceQuery(null, null, null);

// after
intracityService.balanceQuery(wxStoreId, null, PayMode.STORE);
Defensive patterns

Strategy: validation

Validate before calling

if (wxStoreId == null && (payMode == null || payMode == PayMode.STORE)) {
  throw new IllegalArgumentException("wxStoreId required for STORE/null pay mode");
}

Type guard

// Resolve effective pay mode before calling
PayMode effective = (payMode == null) ? PayMode.STORE : payMode;
boolean storeBalanceNeedsId = (effective == PayMode.STORE);

Try / catch

try {
  balance = intracityService.balanceQuery(wxStoreId, svcId, payMode);
} catch (IllegalArgumentException e) {
  throw e;
}

Prevention

When it happens

Trigger: Calling balanceQuery(null, serviceTransId, PayMode.STORE) or balanceQuery(null, anything, null).

Common situations: 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.

Related errors


AI-assisted analysis of binarywang/WxJava@1c43293a3c (2026-08-14). Data as JSON: /api/errors/129f789cc862b7d0. Report an issue: GitHub.