package com.tourguide.common.huifu.biz;
|
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import com.huifu.bspay.sdk.opps.core.net.BasePayRequest;
|
import com.tourguide.common.huifu.properties.HuiFuProperties;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Component;
|
|
import java.math.BigDecimal;
|
import java.util.HashMap;
|
import java.util.Map;
|
|
|
/**
|
* 斗拱进件业务。
|
*
|
* 备注:该类只负责把本项目导游开户资料提交给斗拱;导游账号、银行卡和审核状态应由上层业务服务落库。
|
*/
|
@Component
|
public class DouGongBasicDataBiz {
|
private static final Logger log = LoggerFactory.getLogger(DouGongBasicDataBiz.class);
|
|
@Autowired
|
private HuiFuProperties huiFuProperties;
|
|
/**
|
* 个人用户基本信息开户
|
*
|
* 备注:先创建斗拱个人基础资料,成功后才能继续调用业务入驻和结算卡配置。
|
*
|
* @return
|
* @throws Exception
|
*/
|
public Map<String, Object> userBasicDataIndv(DouGongUserWithdrawalProfile userWithdrawal) throws Exception {
|
// 1. 数据初始化,填入对应的商户配置
|
DouGongRequestSupport.initBasePay(huiFuProperties);
|
// 2.组装请求参数
|
Map<String, Object> paramsInfo = new HashMap<>();
|
// 请求流水号(动态生成,确保唯一性)
|
paramsInfo.put("req_seq_id", DouGongRequestSupport.generateForHuiFu());
|
// 请求日期
|
paramsInfo.put("req_date", DouGongRequestSupport.todayForHuiFu());
|
// 个人证件类型
|
paramsInfo.put("cert_type", "00");
|
String[] certificateExpireDateArr = userWithdrawal.getCertificateExpireTime().split(",");
|
String startDateStr = certificateExpireDateArr[0];
|
// 个人证件有效期开始日期2023-08-02,2043-08-02
|
paramsInfo.put("cert_begin_date", startDateStr.replace("-", ""));
|
// 个人证件有效期截止日期
|
String endDateStr = certificateExpireDateArr[1];
|
if (!"长期".equals(endDateStr)) {
|
String formatEndDate = endDateStr.replace("-", "");
|
paramsInfo.put("cert_end_date", formatEndDate);
|
// 个人证件有效期类型
|
paramsInfo.put("cert_validity_type", "0");
|
}else {
|
// 个人证件有效期类型
|
paramsInfo.put("cert_validity_type", "1");
|
}
|
// 手机号
|
paramsInfo.put("mobile_no", userWithdrawal.getPhone());
|
// 个人姓名
|
paramsInfo.put("name", userWithdrawal.getOpenAccountName());
|
// 个人证件号码
|
paramsInfo.put("cert_no", userWithdrawal.getCertificateCode());
|
// 管理员账号
|
// paramsInfo.put("login_name", userWithdrawal.getPhone());
|
// 是否发送短信标识
|
paramsInfo.put("sms_send_flag", "Y");
|
// 3. 发起API调用
|
log.info("个人用户基本信息开户请求参数:{}", paramsInfo);
|
Map<String, Object> response = BasePayRequest.requestBasePay("v2/user/basicdata/indv", paramsInfo, null, false);
|
log.info("个人用户基本信息开户返回参数:{}", response);
|
return response;
|
}
|
|
/** 企业用户基础资料进件。 */
|
public Map<String, Object> userBasicDataEnt(DouGongUserWithdrawalProfile userWithdrawal) throws Exception {
|
DouGongRequestSupport.initBasePay(huiFuProperties);
|
Map<String, Object> paramsInfo = enterpriseParams(userWithdrawal);
|
paramsInfo.put("req_seq_id", DouGongRequestSupport.generateForHuiFu());
|
paramsInfo.put("req_date", DouGongRequestSupport.todayForHuiFu());
|
log.info("企业用户基本信息开户请求参数:{}", paramsInfo);
|
Map<String, Object> response = BasePayRequest.requestBasePay(
|
"v2/user/basicdata/ent", paramsInfo, null, false);
|
log.info("企业用户基本信息开户返回参数:{}", response);
|
return response;
|
}
|
/**
|
* 个人用户基本信息修改
|
* @return
|
* @throws Exception
|
*/
|
public Map<String, Object> userBasicDataIndvModify(DouGongUserWithdrawalProfile userWithdrawal) throws Exception {
|
// 1. 数据初始化,填入对应的商户配置
|
DouGongRequestSupport.initBasePay(huiFuProperties);
|
// 2.组装请求参数
|
Map<String, Object> paramsInfo = new HashMap<>();
|
// 请求流水号
|
paramsInfo.put("req_seq_id", DouGongRequestSupport.generateForHuiFu());
|
// 请求日期
|
paramsInfo.put("req_date", DouGongRequestSupport.todayForHuiFu());
|
// 汇付客户Id
|
paramsInfo.put("huifu_id", userWithdrawal.getHuifuId());
|
String[] certificateExpireDateArr = userWithdrawal.getCertificateExpireTime().split(",");
|
String startDateStr = certificateExpireDateArr[0];
|
// 个人证件有效期开始日期
|
paramsInfo.put("cert_begin_date", startDateStr.replace("-", ""));
|
// 个人证件有效期截止日期
|
String endDateStr = certificateExpireDateArr[1];
|
if (!"长期".equals(endDateStr)) {
|
String formatEndDate = endDateStr.replace("-", "");
|
paramsInfo.put("cert_end_date", formatEndDate);
|
// 个人证件有效期类型
|
paramsInfo.put("cert_validity_type", "0");
|
}else {
|
// 个人证件有效期类型
|
paramsInfo.put("cert_validity_type", "1");
|
}
|
// 手机号
|
paramsInfo.put("mobile_no", userWithdrawal.getPhone());
|
log.info("个人用户基本信息修改返回参数:{}", paramsInfo);
|
// 3. 发起API调用
|
Map<String, Object> response = BasePayRequest.requestBasePay("v2/user/basicdata/indv/modify", paramsInfo, null, false);
|
log.info("个人用户基本信息修改返回参数:{}", response);
|
return response;
|
}
|
|
/** 企业用户基础资料修改,用于审核驳回后的重新提交。 */
|
public Map<String, Object> userBasicDataEntModify(DouGongUserWithdrawalProfile userWithdrawal) throws Exception {
|
DouGongRequestSupport.initBasePay(huiFuProperties);
|
Map<String, Object> paramsInfo = enterpriseParams(userWithdrawal);
|
paramsInfo.put("req_seq_id", DouGongRequestSupport.generateForHuiFu());
|
paramsInfo.put("req_date", DouGongRequestSupport.todayForHuiFu());
|
paramsInfo.put("huifu_id", userWithdrawal.getHuifuId());
|
log.info("企业用户基本信息修改请求参数:{}", paramsInfo);
|
Map<String, Object> response = BasePayRequest.requestBasePay(
|
"v2/user/basicdata/ent/modify", paramsInfo, null, false);
|
log.info("企业用户基本信息修改返回参数:{}", response);
|
return response;
|
}
|
|
/** 查询个人或企业用户的进件申请状态。 */
|
public Map<String, Object> userApplyQuery(DouGongUserWithdrawalProfile userWithdrawal,
|
String applyNo) throws Exception {
|
if (applyNo == null || applyNo.trim().isEmpty() || applyNo.trim().length() > 18) {
|
throw new IllegalArgumentException("斗拱进件状态查询申请单号不能为空且长度不能超过18个字符");
|
}
|
DouGongRequestSupport.initBasePay(huiFuProperties);
|
Map<String, Object> paramsInfo = new HashMap<>();
|
paramsInfo.put("huifu_id", userWithdrawal.getHuifuId());
|
paramsInfo.put("req_seq_id", DouGongRequestSupport.generateForHuiFu());
|
paramsInfo.put("req_date", DouGongRequestSupport.todayForHuiFu());
|
paramsInfo.put("apply_no", applyNo.trim());
|
log.info("用户进件申请状态查询请求参数:{}", paramsInfo);
|
Map<String, Object> response = BasePayRequest.requestBasePay(
|
"v2/user/apply/query", paramsInfo, null, false);
|
log.info("用户进件申请状态查询返回参数:{}", response);
|
return response;
|
}
|
/**
|
* 用户业务入驻
|
*
|
* 备注:业务入驻会绑定结算卡和提现规则,后续提现依赖这里返回的取现卡序列号。
|
*
|
* @return
|
* @throws Exception
|
*/
|
public Map<String, Object> userBusinessOpen(DouGongUserWithdrawalProfile userWithdrawal) throws Exception {
|
// 1. 数据初始化,填入对应的商户配置
|
DouGongRequestSupport.initBasePay(huiFuProperties);
|
// 2.组装请求参数
|
Map<String, Object> paramsInfo = new HashMap<>();
|
// 汇付ID
|
paramsInfo.put("huifu_id", userWithdrawal.getHuifuId());
|
// 请求流水号
|
paramsInfo.put("req_seq_id", DouGongRequestSupport.generateForHuiFu());
|
// 请求日期
|
paramsInfo.put("req_date", DouGongRequestSupport.todayForHuiFu());
|
// 渠道商/商户汇付Id
|
paramsInfo.put("upper_huifu_id", huiFuProperties.getUpperHuifuId());
|
//// 结算信息配置
|
//paramsInfo.put("settle_config", "{\"settle_cycle\":\"D1\",\"min_amt\":\"0.01\",\"remained_amt\":\"10.00\",\"settle_abstract\":\"结算摘要\",\"out_settle_flag\":\"2\",\"settle_batch_no\":\"300\",\"fixed_ratio\":\"2\"}");
|
// 结算卡信息
|
JSONObject cardInfo = new JSONObject();
|
cardInfo.put("card_type", "1");
|
cardInfo.put("card_name", userWithdrawal.getOpenAccountName());
|
cardInfo.put("card_no", userWithdrawal.getBankCardCode());
|
cardInfo.put("prov_id", userWithdrawal.getBankCardProvinceCode());
|
cardInfo.put("area_id", userWithdrawal.getBankCardCityCode());
|
cardInfo.put("cert_type", "00");
|
cardInfo.put("cert_no", userWithdrawal.getCertificateCode());
|
String[] certificateExpireDateArr = userWithdrawal.getCertificateExpireTime().split(",");
|
String startDateStr = certificateExpireDateArr[0];
|
// 个人证件有效期开始日期
|
cardInfo.put("cert_begin_date", startDateStr.replace("-", ""));
|
// 个人证件有效期截止日期
|
String endDateStr = certificateExpireDateArr[1];
|
if (!"长期".equals(endDateStr)) {
|
String formatEndDate = endDateStr.replace("-", "");
|
cardInfo.put("cert_end_date", formatEndDate);
|
// 个人证件有效期类型
|
cardInfo.put("cert_validity_type", "0");
|
}else {
|
// 个人证件有效期类型
|
cardInfo.put("cert_validity_type", "1");
|
}
|
paramsInfo.put("card_info", cardInfo.toJSONString());
|
// 结算卡信息
|
JSONArray cashConfigArr = new JSONArray();
|
JSONObject cashConfig = new JSONObject();
|
/**
|
* T1:下一工作日到银行账户;
|
* D1:下一自然日到银行账户;
|
* D0:当日到银行账户;默认D0;
|
* DM:当日到账;到账资金不包括当天的交易资金;
|
* 示例值:T1
|
*/
|
cashConfig.put("cash_type", "D1");
|
cashConfig.put("fix_amt", "0.00");
|
cashConfig.put("weekday_fix_amt", "0.00");
|
cashConfig.put("weekday_fee_rate", "0.00");
|
cashConfigArr.add(cashConfig);
|
paramsInfo.put("cash_config", cashConfigArr.toJSONString());
|
log.info("用户业务入驻返回参数:{}", paramsInfo);
|
// 3. 发起API调用
|
Map<String, Object> response = BasePayRequest.requestBasePay("v2/user/busi/open", paramsInfo, null, false);;
|
log.info("用户业务入驻返回参数:{}", response);
|
return response;
|
}
|
/**
|
* 用户业务入驻
|
* @return
|
* @throws Exception
|
*/
|
public Map<String, Object> userBusinessOpenModify(DouGongUserWithdrawalProfile userWithdrawal) throws Exception {
|
// 1. 数据初始化,填入对应的商户配置
|
DouGongRequestSupport.initBasePay(huiFuProperties);
|
// 2.组装请求参数
|
Map<String, Object> paramsInfo = new HashMap<>();
|
// 汇付ID
|
paramsInfo.put("huifu_id", userWithdrawal.getHuifuId());
|
// 请求流水号
|
paramsInfo.put("req_seq_id", DouGongRequestSupport.generateForHuiFu());
|
// 请求日期
|
paramsInfo.put("req_date", DouGongRequestSupport.todayForHuiFu());
|
// 结算卡信息
|
JSONObject cardInfo = new JSONObject();
|
cardInfo.put("card_type", "1");
|
cardInfo.put("card_name", userWithdrawal.getOpenAccountName());
|
cardInfo.put("card_no", userWithdrawal.getBankCardCode());
|
cardInfo.put("prov_id", userWithdrawal.getBankCardProvinceCode());
|
cardInfo.put("area_id", userWithdrawal.getBankCardCityCode());
|
cardInfo.put("cert_type", "00");
|
cardInfo.put("cert_no", userWithdrawal.getCertificateCode());
|
String[] certificateExpireDateArr = userWithdrawal.getCertificateExpireTime().split(",");
|
String startDateStr = certificateExpireDateArr[0];
|
// 个人证件有效期开始日期
|
cardInfo.put("cert_begin_date", startDateStr.replace("-", ""));
|
// 个人证件有效期截止日期
|
String endDateStr = certificateExpireDateArr[1];
|
if (!"长期".equals(endDateStr)) {
|
String formatEndDate = endDateStr.replace("-", "");
|
cardInfo.put("cert_end_date", formatEndDate);
|
// 个人证件有效期类型
|
cardInfo.put("cert_validity_type", "0");
|
}else {
|
// 个人证件有效期类型
|
cardInfo.put("cert_validity_type", "1");
|
}
|
paramsInfo.put("card_info", cardInfo.toJSONString());
|
// 结算卡信息
|
JSONArray cashConfigArr = new JSONArray();
|
JSONObject cashConfig = new JSONObject();
|
/**
|
* T1:下一工作日到银行账户;
|
* D1:下一自然日到银行账户;
|
* D0:当日到银行账户;默认D0;
|
* DM:当日到账;到账资金不包括当天的交易资金;
|
* 示例值:T1
|
*/
|
cashConfig.put("switch_state", "1");
|
cashConfig.put("cash_type", "D1");
|
cashConfig.put("fix_amt", "0.00");
|
cashConfig.put("weekday_fix_amt", "0.00");
|
cashConfig.put("weekday_fee_rate", "0.00");
|
cashConfigArr.add(cashConfig);
|
paramsInfo.put("cash_config", cashConfigArr.toJSONString());
|
log.info("用户业务入驻修改返回参数:{}", paramsInfo);
|
|
// 3. 发起API调用
|
Map<String, Object> response = BasePayRequest.requestBasePay("v2/user/busi/modify", paramsInfo, null, false);;
|
log.info("用户业务入驻修改返回参数:{}", response);
|
return response;
|
}
|
|
public BigDecimal balanceQuery(String huifuId) throws Exception {
|
// 1. 数据初始化,填入对应的商户配置
|
DouGongRequestSupport.initBasePay(huiFuProperties);
|
// 2.组装请求参数
|
Map<String, Object> paramsInfo = new HashMap<>();
|
// 汇付ID
|
paramsInfo.put("huifu_id", huifuId);
|
// 请求流水号
|
paramsInfo.put("req_seq_id", DouGongRequestSupport.generateForHuiFu());
|
// 请求日期
|
paramsInfo.put("req_date", DouGongRequestSupport.todayForHuiFu());
|
log.info("账户余额信息查询返回参数:{}", paramsInfo);
|
// 3. 发起API调用
|
Map<String, Object> response = BasePayRequest.requestBasePay("v2/trade/acctpayment/balance/query", paramsInfo, null, false);
|
log.info("账户余额信息查询返回参数:{}", response);
|
return availableBalance(response);
|
}
|
|
static BigDecimal availableBalance(Map<String, Object> response) {
|
if (response == null) return BigDecimal.ZERO;
|
Object accountData = response.get("acctInfo_list");
|
if (accountData == null) accountData = response.get("acct_info_list");
|
if (accountData == null) return BigDecimal.ZERO;
|
JSONArray accountList = accountData instanceof JSONArray
|
? (JSONArray) accountData
|
: JSONArray.parseArray(accountData instanceof String
|
? (String) accountData : JSONObject.toJSONString(accountData));
|
if (accountList == null || accountList.isEmpty()) return BigDecimal.ZERO;
|
JSONObject acctInfo = accountList.getJSONObject(0);
|
if (acctInfo == null || acctInfo.get("avail_bal") == null) return BigDecimal.ZERO;
|
BigDecimal balance = acctInfo.getBigDecimal("avail_bal");
|
return balance == null ? BigDecimal.ZERO : balance;
|
}
|
|
private Map<String, Object> enterpriseParams(DouGongUserWithdrawalProfile profile) {
|
Map<String, Object> params = new HashMap<>();
|
params.put("reg_name", profile.getEnterpriseName());
|
params.put("license_code", profile.getCreditCode());
|
params.put("license_validity_type", validityType(profile.getLicenseValidityType()));
|
params.put("license_begin_date", compactDate(profile.getLicenseBeginDate()));
|
putFixedEndDate(params, "license_end_date", profile.getLicenseValidityType(), profile.getLicenseEndDate());
|
params.put("reg_prov_id", profile.getRegisteredProvinceCode());
|
params.put("reg_area_id", profile.getRegisteredCityCode());
|
params.put("reg_district_id", profile.getRegisteredDistrictCode());
|
params.put("reg_detail", profile.getRegisteredAddress());
|
params.put("legal_name", profile.getCertificateName());
|
params.put("legal_cert_type", "00");
|
params.put("legal_cert_no", profile.getCertificateCode());
|
String[] certificateDates = certificateDates(profile.getCertificateExpireTime());
|
params.put("legal_cert_validity_type", "长期".equals(certificateDates[1]) ? "1" : "0");
|
params.put("legal_cert_begin_date", compactDate(certificateDates[0]));
|
if (!"长期".equals(certificateDates[1])) {
|
params.put("legal_cert_end_date", compactDate(certificateDates[1]));
|
}
|
params.put("legal_cert_nationality", "CHN");
|
params.put("contact_name", profile.getContactName());
|
params.put("contact_mobile", profile.getPhone());
|
return params;
|
}
|
|
private String validityType(String value) {
|
return "long_term".equals(value) ? "1" : "0";
|
}
|
|
private void putFixedEndDate(Map<String, Object> params, String key, String validityType, String value) {
|
if (!"long_term".equals(validityType) && value != null && !value.trim().isEmpty()) {
|
params.put(key, compactDate(value));
|
}
|
}
|
|
private String compactDate(String value) {
|
return value == null ? null : value.replace("-", "");
|
}
|
|
private String[] certificateDates(String value) {
|
String normalized = value == null ? "" : value.replace(",", ",");
|
String[] values = normalized.split(",", -1);
|
return values.length >= 2 ? values : new String[]{normalized, "长期"};
|
}
|
}
|