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 ""; }
|
}
|
}
|