shinnosuke
2026-08-05 25729fa1ae7b630cbd4a9547a5693acd03c09c2a
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
package com.talentcard.server.business.payment.huifu;
 
import com.alibaba.fastjson.JSON;
import com.huifu.bspay.sdk.opps.client.BasePayClient;
import com.huifu.bspay.sdk.opps.core.BasePay;
import com.huifu.bspay.sdk.opps.core.config.MerConfig;
import com.huifu.bspay.sdk.opps.core.request.V2UserBasicdataIndvRequest;
import com.talentcard.server.common.BusinessException;
import com.talentcard.server.common.ErrorCode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import org.springframework.stereotype.Service;
 
@Service
public class HuifuIndividualOnboardingGateway {
    private static final Object SDK_LOCK = new Object();
    private final HuifuPaymentProperties properties;
 
    public HuifuIndividualOnboardingGateway(HuifuPaymentProperties properties) { this.properties = properties; }
 
    public Result create(HuifuIndividualOnboardingCommand command) {
        ensureConfigured();
        V2UserBasicdataIndvRequest request = new V2UserBasicdataIndvRequest();
        request.setReqSeqId(command.applicationNo());
        request.setReqDate(LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE));
        request.setName(command.name());
        request.setCertType("00");
        request.setCertNo(command.idCardNo());
        request.setCertValidityType(command.certificateValidityType());
        request.setCertBeginDate(command.certificateBeginDate());
        request.setCertNationality("CHN");
        request.setMobileNo(command.mobileNo());
        if (!blank(command.address())) request.setAddress(command.address());
        try {
            Map<String, Object> response;
            synchronized (SDK_LOCK) {
                initializeSdk();
                response = BasePayClient.request(request, false);
            }
            return Result.from(response);
        } catch (BusinessException exception) {
            throw exception;
        } catch (Exception exception) {
            throw new HuifuPaymentGatewayException("Huifu individual onboarding request failed", outcomeUnknown(exception), exception);
        }
    }
 
    private void ensureConfigured() {
        if (!properties.isEnabled()) throw new BusinessException(ErrorCode.CONFLICT, "Huifu payment is disabled");
        if (blank(properties.getSystemId()) || blank(properties.getProductId()) || blank(properties.getPrivateKey()) || blank(properties.getPlatformPublicKey())) throw new BusinessException(ErrorCode.CONFLICT, "Huifu onboarding configuration is incomplete");
    }
 
    private void initializeSdk() throws Exception {
        BasePay.debug = false;
        BasePay.prodMode = "prod".equalsIgnoreCase(properties.getEnvironment()) ? BasePay.MODE_PROD : BasePay.MODE_TEST;
        MerConfig config = new MerConfig();
        config.setSysId(properties.getSystemId().trim());
        config.setProductId(properties.getProductId().trim());
        config.setRsaPrivateKey(properties.getPrivateKey().trim());
        config.setRsaPublicKey(properties.getPlatformPublicKey().trim());
        BasePay.initWithMerConfig(config);
    }
 
    private boolean blank(String value) { return value == null || value.isBlank(); }
    private boolean outcomeUnknown(Exception exception) { String message = exception.getMessage() == null ? "" : exception.getMessage().toLowerCase(); return message.contains("timeout") || message.contains("timed out") || message.contains("no response"); }
 
    @SuppressWarnings("unchecked")
    public record Result(boolean accepted, String huifuId, String code, String message) {
        static Result from(Map<String, Object> response) {
            Object raw = response.get("data");
            Map<String, Object> data = raw instanceof Map<?, ?> value ? (Map<String, Object>) value : raw instanceof String json && !json.isBlank() ? JSON.parseObject(json, Map.class) : response;
            String code = value(data, "sub_resp_code", "resp_code", "code");
            String message = value(data, "sub_resp_desc", "resp_desc", "message");
            String huifuId = value(data, "huifu_id", "huifuId");
            return new Result("00000000".equals(code) || "10000".equals(code) || "0".equals(code) || "SUCCESS".equalsIgnoreCase(code), huifuId, code, message);
        }
 
        private static String value(Map<String, Object> data, String... keys) { for (String key : keys) if (data.get(key) != null) return String.valueOf(data.get(key)).trim(); return ""; }
    }
}