talent-card-server/src/test/java/com/talentcard/server/business/payment/huifu/HuifuBusinessOpenRequiredFieldsTests.java
@@ -19,7 +19,8 @@
 *       是否一致。平台用一个运营媒介给众多子商户开通,主体天然不一致,取 N。它属于媒介**元素**而不是顶层参数,
 *       放顶层会被拒:「【media_merCommon_flag-媒介主体与商户主体是否一致】不能为空,或格式非法」。</li>
 *   <li>{@code micro_biz_type}(wx_conf_list 元素内的 wx_real_name_info):个人商户开通微信业务必填,
 *       且三种取值都要求 F22 店铺门头照 + F24 店铺内景照。</li>
 *       且线下经营的经营场所材料是一组三张——F22 店铺门头照、F24 店铺内景、F105 店铺收银台,企业与
 *       个人主体都要交(见下文的材料用例)。</li>
 * </ul>
 *
 * <p>层级依据:文档里 {@code wx_real_name_info} 既是父字段列、又有同名子表,按本接口的写法约定
@@ -99,20 +100,22 @@
    }
    /**
     * 个人(小微)商户填了 {@code micro_biz_type},就欠这两张门店照片:官方在 micro_biz_type
     * 的说明里写明「需要提供 F22:店铺门头照图片;F24:店铺内景图片,补充资料填写在
     * extended_material_list 对象中」。原先只有 micro_biz_type、没有材料,开通是缺材料提交。
     * 门店材料是线下经营的一组**三张**:门头照(F22)、内景照(F24)、收银台(F105)。官方在
     * micro_biz_type 的说明里点名前两张要填进 {@code extended_material_list};第三张(F105)是
     * 通道材料校验报错里给出的(「缺失图片:F22-店铺门头照图片;F24-店铺内景图片;F105-店铺收银台」,
     * 2026-09-29 实测)。原先只发两张、且只有个人主体发。
     */
    @Test
    void anIndividualMerchantCarriesTheStorePhotosAsExtendedMaterial() {
        Map<String, Object> request = HuifuMerchantBusinessOpenGateway.buildRequestForTest(
                properties(), "BO-TEST-MATERIAL", "6666000241390821", "阳野", "5812", true, true, "file-f22", "file-f24");
                properties(), "BO-TEST-MATERIAL", "6666000241390821", "阳野", "5812", true, true, "file-f22", "file-f24", "file-f105");
        List<Map<String, Object>> materials =
                JSON.parseObject(String.valueOf(request.get("extended_material_list")), List.class);
        assertThat(materials).hasSize(2);
        assertThat(materials).hasSize(3);
        assertThat(materials.get(0)).containsEntry("file_type", "F22").containsEntry("file_id", "file-f22");
        assertThat(materials.get(1)).containsEntry("file_type", "F24").containsEntry("file_id", "file-f24");
        assertThat(materials.get(2)).containsEntry("file_type", "F105").containsEntry("file_id", "file-f105");
    }
    /** 门店照片缺一张就只发一张:宁可让通道明确报缺哪一项,也不要塞占位图顶上。 */
@@ -127,11 +130,27 @@
        assertThat(materials.get(0)).containsEntry("file_type", "F22");
    }
    /** 企业主体没有这项材料要求,不要凭空给企业商户加附件。 */
    /**
     * 企业主体同样交这三张。线下报备按「有实体经营场所」口径索要材料,通道不分主体类型;原先
     * {@code extended_material_list} 只在 {@code individualMerchant} 为真时下发,企业进件的门店材料
     * 一张都到不了通道(2026-09-29 企业主体进件被材料校验整笔驳回的直接原因)。
     */
    @Test
    void anEnterpriseMerchantCarriesNoExtendedMaterial() {
    void anEnterpriseMerchantCarriesTheSameStoreMaterialGroup() {
        Map<String, Object> request = HuifuMerchantBusinessOpenGateway.buildRequestForTest(
                properties(), "BO-TEST-MATERIAL-2", "6666000241390821", "成都喜望科技", "5812", false, false, "file-f22", "file-f24");
                properties(), "BO-TEST-MATERIAL-2", "6666000241390821", "成都喜望科技", "5812", false, false, "file-f22", "file-f24", "file-f105");
        List<Map<String, Object>> materials =
                JSON.parseObject(String.valueOf(request.get("extended_material_list")), List.class);
        assertThat(materials).hasSize(3);
        assertThat(materials.get(2)).containsEntry("file_type", "F105").containsEntry("file_id", "file-f105");
    }
    /** 三张图都没有时整个字段不下发,而不是发一个空数组。 */
    @Test
    void noStorePhotoMeansNoExtendedMaterialField() {
        Map<String, Object> request = HuifuMerchantBusinessOpenGateway.buildRequestForTest(
                properties(), "BO-TEST-MATERIAL-3", "6666000241390821", "成都喜望科技", "5812", false, false, "", "", "");
        assertThat(request).doesNotContainKey("extended_material_list");
    }