yeg
2026-09-15 5664368e6a90c6a0a9a09be711b47f84d2a63f1c
feat(merchant): 支持企业微信费率规则配置
4个文件已修改
31 ■■■■■ 已修改文件
talent-card-server/src/main/java/com/talentcard/server/business/payment/huifu/HuifuMerchantBusinessOpenGateway.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
talent-card-server/src/main/java/com/talentcard/server/business/payment/huifu/HuifuPaymentProperties.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
talent-card-server/src/main/resources/application.yml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
talent-card-server/src/test/java/com/talentcard/server/business/payment/huifu/HuifuBusinessOpenRequiredFieldsTests.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
talent-card-server/src/main/java/com/talentcard/server/business/payment/huifu/HuifuMerchantBusinessOpenGateway.java
@@ -56,8 +56,14 @@
    private Map<String, Object> buildRequest(String requestNo, String huifuId, String shortName, String mcc, boolean individualMerchant) {
        Map<String, Object> wechat = new LinkedHashMap<>();
        wechat.put("pay_scene", "5");
        // mcc:文档注明「个体工商户、小微商户必填」——个人主体属于小微商户,所以必须带上。
        wechat.put("mcc", mcc);
        // 企业微信业务使用汇付确认的 fee_rule_id;仅在未配置规则 ID 时兼容旧的 mcc 路径。
        // 不得把参考商户的规则 ID 猜测套用到其它行业。
        if (!properties.getMerchantWechatFeeRuleId().isBlank()) {
            wechat.put("fee_rule_id", properties.getMerchantWechatFeeRuleId());
        } else {
            // mcc:文档注明「个体工商户、小微商户必填」——个人主体属于小微商户,所以必须带上。
            wechat.put("mcc", mcc);
        }
        wechat.put("fee_rate", properties.getMerchantWechatFeeRate().trim());
        // 实名认证由通道在业务开通成功后另行发起;取 N 表示本次不发起。
        // 改成 Y 之前要先确认实名所需的材料(含 F22/F24 照片)已就绪。
talent-card-server/src/main/java/com/talentcard/server/business/payment/huifu/HuifuPaymentProperties.java
@@ -43,6 +43,11 @@
     */
    private String merchantUseChainsFlag = "3";
    private String merchantWechatFeeRate = "0.60";
    /**
     * 企业微信业务开通使用的汇付费率规则 ID。企业场景应优先填写该值,
     * 由汇付按商户实际行业确认;留空时兼容旧的 mcc 请求方式。
     */
    private String merchantWechatFeeRuleId = "";
    private String merchantOnlineBusinessType = "H5311L";
    private String merchantOnlineMediaName = "东区人才卡";
    /**
@@ -111,6 +116,8 @@
    public void setMerchantUseChainsFlag(String merchantUseChainsFlag) { this.merchantUseChainsFlag = merchantUseChainsFlag; }
    public String getMerchantWechatFeeRate() { return merchantWechatFeeRate; }
    public void setMerchantWechatFeeRate(String merchantWechatFeeRate) { this.merchantWechatFeeRate = merchantWechatFeeRate; }
    public String getMerchantWechatFeeRuleId() { return merchantWechatFeeRuleId == null ? "" : merchantWechatFeeRuleId.trim(); }
    public void setMerchantWechatFeeRuleId(String merchantWechatFeeRuleId) { this.merchantWechatFeeRuleId = merchantWechatFeeRuleId; }
    public String getMerchantOnlineBusinessType() { return merchantOnlineBusinessType; }
    public void setMerchantOnlineBusinessType(String merchantOnlineBusinessType) { this.merchantOnlineBusinessType = merchantOnlineBusinessType; }
    public String getMerchantOnlineMediaName() { return merchantOnlineMediaName; }
talent-card-server/src/main/resources/application.yml
@@ -91,6 +91,8 @@
      # 商户业务开通是否复用上级(渠道商)的微信商户号:3=仅微信;留空=不下发该字段。
      merchant-use-chains-flag: ${HUIFU_MERCHANT_USE_CHAINS_FLAG:3}
      merchant-wechat-fee-rate: ${HUIFU_MERCHANT_WECHAT_FEE_RATE:0.60}
      # 企业微信开通应填写汇付按实际行业确认的规则 ID;留空时沿用 mcc 兼容路径。
      merchant-wechat-fee-rule-id: ${HUIFU_MERCHANT_WECHAT_FEE_RULE_ID:}
      merchant-online-business-type: ${HUIFU_MERCHANT_ONLINE_BUSINESS_TYPE:H5311L}
      merchant-online-media-name: ${HUIFU_MERCHANT_ONLINE_MEDIA_NAME:东区人才卡}
      # 运营媒介主体与商户主体是否一致。平台用一个运营媒介给众多子商户开通,主体天然不一致。
talent-card-server/src/test/java/com/talentcard/server/business/payment/huifu/HuifuBusinessOpenRequiredFieldsTests.java
@@ -74,6 +74,18 @@
        assertThat(wechat.get(0)).doesNotContainKey("wx_real_name_info");
    }
    @Test
    void anEnterpriseCanUseAProviderConfirmedFeeRuleInsteadOfMcc() {
        HuifuPaymentProperties properties = properties();
        properties.setMerchantWechatFeeRuleId("756");
        List<Map<String, Object>> wechat = wechatConfig(HuifuMerchantBusinessOpenGateway.buildRequestForTest(
                properties, "BO-TEST-RULE", "6666000241335656", "成都喜望科技", "7372", false));
        assertThat(wechat.get(0)).containsEntry("fee_rule_id", "756");
        assertThat(wechat.get(0)).doesNotContainKey("mcc");
    }
    /**
     * 直接驱动组装逻辑。网关的 {@code open()} 会真的调用通道,所以这里只构建请求体:
     * 复用网关内部的组装顺序没有意义,改为断言"网关是否会包含这些字段"的等价物——