1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package com.talentcard.server.business.payment.huifu;
 
import static org.assertj.core.api.Assertions.assertThat;
 
import java.util.Map;
 
import com.alibaba.fastjson.JSON;
import org.junit.jupiter.api.Test;
 
/**
 * 个人(小微)商户进件请求里几条容易漏、且漏了就一定被通道驳回的字段。
 *
 * <p>三条规则都是与业务确认过的口径,不是猜的:
 *
 * <ul>
 *   <li>{@code store_header_pic}(F22)是**必填**:三种小微经营类型都要传,只是图片内容要求不同——
 *       线上商品/服务交易传店铺首页截图、流动经营/便民服务传经营现场照、门店场所传实体门头照。
 *       不能因为"线上没有实体店"就整项不传。</li>
 *   <li>证件「长期有效」({@code *_validity_type=1})时**不填**截止日期,非长期必填。</li>
 *   <li>{@code settle_config} 的 {@code fixed_ratio} / {@code constant_amt} 在 D1 下是条件必填,
 *       平台不收这笔钱,填 0.00;完全不传会被判缺参数。</li>
 * </ul>
 */
class HuifuIndividualOnboardingRequiredFieldsTests {
 
    @Test
    void theStorePhotoIsAlwaysCarriedEvenForOnlineOnlyMicroMerchants() {
        Map<String, Object> request = request(command("0", "20120110", "20320110"));
 
        assertThat(request).containsEntry("store_header_pic", "F22-STORE");
        assertThat(request).containsEntry("settle_card_front_pic", "F13-CARD");
    }
 
    @Test
    void aLongTermCertificateOmitsBothDeadlines() {
        Map<String, Object> request = request(command("1", "20120110", ""));
 
        assertThat(request).containsEntry("legal_cert_validity_type", "1");
        assertThat(request).doesNotContainKey("legal_cert_end_date");
        assertThat(cardInfo(request)).doesNotContainKey("cert_end_date");
    }
 
    @Test
    void aFixedTermCertificateCarriesBothDeadlines() {
        Map<String, Object> request = request(command("0", "20120110", "20320110"));
 
        assertThat(request).containsEntry("legal_cert_end_date", "20320110");
        assertThat(cardInfo(request)).containsEntry("cert_validity_type", "0").containsEntry("cert_end_date", "20320110");
    }
 
    /** 结算周期是 D1,节假日结算手续费两项必须下发;平台不收,填 0.00。 */
    @Test
    void theSettlementConfigCarriesTheD1HolidayFeeFields() {
        Map<String, Object> settle = JSON.parseObject(String.valueOf(request(command("0", "20120110", "20320110")).get("settle_config")), Map.class);
 
        assertThat(settle)
                .containsEntry("settle_cycle", "D1")
                .containsEntry("fixed_ratio", "0.00")
                .containsEntry("constant_amt", "0.00")
                .containsEntry("min_amt", "0.00")
                .containsEntry("remained_amt", "0.00");
    }
 
    /** 企业主体同一份 settle_config(个人进件复用它,见 HuifuIndividualOnboardingGateway)。 */
    @Test
    void theEnterpriseSettlementConfigCarriesTheSameHolidayFeeFields() {
        Map<String, Object> settle = HuifuEnterpriseOnboardingGateway.settleConfig();
 
        assertThat(settle).containsEntry("fixed_ratio", "0.00").containsEntry("constant_amt", "0.00");
    }
 
    private static HuifuPaymentProperties properties() {
        HuifuPaymentProperties properties = new HuifuPaymentProperties();
        properties.setEnabled(true);
        properties.setSystemId("6666000220591054");
        properties.setProductId("KAZX");
        properties.setPrivateKey("x");
        properties.setPlatformPublicKey("y");
        properties.setMerchantWechatFeeRate("0.70");
        properties.setMerchantOnlineBusinessType("H5311L");
        properties.setMerchantAgreementUrl("https://example.com/agreement.htm");
        properties.setOnboardingUpperHuifuId("6666000220591054");
        return properties;
    }
 
    private static Map<String, Object> request(HuifuIndividualOnboardingCommand command) {
        return HuifuIndividualOnboardingGateway.buildRequestForTest(properties(), command);
    }
 
    @SuppressWarnings("unchecked")
    private static Map<String, Object> cardInfo(Map<String, Object> request) {
        return JSON.parseObject(String.valueOf(request.get("card_info")), Map.class);
    }
 
    private static HuifuIndividualOnboardingCommand command(String validityType, String beginDate, String endDate) {
        return new HuifuIndividualOnboardingCommand(
                "MO-TEST-1", "阳野", "511602199803310019", validityType, beginDate, endDate, "15708261096",
                "四川省广安市广安区兴安中街227号3栋1单元6楼2号", "1347747024@qq.com", "5812",
                "510000", "510100", "510104", "F40-ID", "F41-ID",
                "6217003680002760924", "510000", "511600", "01050000", "F13-CARD", "F22-STORE");
    }
}