package com.stylefeng.guns.modular.huifu.biz; import cn.hutool.core.date.DateUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.huifu.bspay.sdk.opps.core.BasePay; import com.huifu.bspay.sdk.opps.core.config.MerConfig; import com.huifu.bspay.sdk.opps.core.exception.BasePayException; import com.huifu.bspay.sdk.opps.core.net.BasePayRequest; import com.stylefeng.guns.core.util.RequestSeqUtil; import com.stylefeng.guns.modular.huifu.properties.HuiFuProperties; import com.stylefeng.guns.modular.system.model.UserWithdrawal; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import java.math.BigDecimal; import java.math.RoundingMode; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.Signature; import java.security.spec.PKCS8EncodedKeySpec; import java.text.SimpleDateFormat; import java.util.Base64; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * 斗拱进件业务 * @author mitao * @date 2025/11/14 */ @Slf4j @Component public class DouGongBasicDataBiz { @Autowired private HuiFuProperties huiFuProperties; /** * 个人用户基本信息开户 * @return * @throws Exception */ public Map userBasicDataIndv(UserWithdrawal userWithdrawal) throws Exception { // 1. 数据初始化,填入对应的商户配置 MerConfig merConfig = new MerConfig(); merConfig.setProcutId(huiFuProperties.getProductId()); merConfig.setSysId(huiFuProperties.getSysId()); merConfig.setRsaPrivateKey(huiFuProperties.getRsaPrivateKey()); merConfig.setRsaPublicKey(huiFuProperties.getRsaPublicKey()); BasePay.initWithMerConfig(merConfig); // 2.组装请求参数 Map paramsInfo = new HashMap<>(); // 请求流水号(动态生成,确保唯一性) paramsInfo.put("req_seq_id", RequestSeqUtil.generateForHuiFu()); // 请求日期 paramsInfo.put("req_date", DateUtil.format(new Date(),"yyyyMMdd")); // 个人证件类型 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 response = BasePayRequest.requestBasePay("v2/user/basicdata/indv", paramsInfo, null, false); log.info("个人用户基本信息开户返回参数:{}", response); return response; } /** * 个人用户基本信息修改 * @return * @throws Exception */ public Map userBasicDataIndvModify(UserWithdrawal userWithdrawal) throws Exception { // 1. 数据初始化,填入对应的商户配置 MerConfig merConfig = new MerConfig(); merConfig.setProcutId(huiFuProperties.getProductId()); merConfig.setSysId(huiFuProperties.getSysId()); merConfig.setRsaPrivateKey(huiFuProperties.getRsaPrivateKey()); merConfig.setRsaPublicKey(huiFuProperties.getRsaPublicKey()); BasePay.initWithMerConfig(merConfig); // 2.组装请求参数 Map paramsInfo = new HashMap<>(); // 请求流水号 paramsInfo.put("req_seq_id", RequestSeqUtil.generateForHuiFu()); // 请求日期 paramsInfo.put("req_date", DateUtil.format(new Date(),"yyyyMMdd")); // 汇付客户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 response = BasePayRequest.requestBasePay("v2/user/basicdata/indv/modify", paramsInfo, null, false); log.info("个人用户基本信息修改返回参数:{}", response); return response; } /** * 用户业务入驻 * @return * @throws Exception */ public Map userBusinessOpen(UserWithdrawal userWithdrawal) throws Exception { // 1. 数据初始化,填入对应的商户配置 MerConfig merConfig = new MerConfig(); merConfig.setProcutId(huiFuProperties.getProductId()); merConfig.setSysId(huiFuProperties.getSysId()); merConfig.setRsaPrivateKey(huiFuProperties.getRsaPrivateKey()); merConfig.setRsaPublicKey(huiFuProperties.getRsaPublicKey()); BasePay.initWithMerConfig(merConfig); // 2.组装请求参数 Map paramsInfo = new HashMap<>(); // 汇付ID paramsInfo.put("huifu_id", userWithdrawal.getHuifuId()); // 请求流水号 paramsInfo.put("req_seq_id", RequestSeqUtil.generateForHuiFu()); // 请求日期 paramsInfo.put("req_date", DateUtil.format(new Date(),"yyyyMMdd")); // 渠道商/商户汇付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 response = BasePayRequest.requestBasePay("v2/user/busi/open", paramsInfo, null, false);; log.info("用户业务入驻返回参数:{}", response); return response; } /** * 用户业务入驻 * @return * @throws Exception */ public Map userBusinessOpenModify(UserWithdrawal userWithdrawal) throws Exception { // 1. 数据初始化,填入对应的商户配置 MerConfig merConfig = new MerConfig(); merConfig.setProcutId(huiFuProperties.getProductId()); merConfig.setSysId(huiFuProperties.getSysId()); merConfig.setRsaPrivateKey(huiFuProperties.getRsaPrivateKey()); merConfig.setRsaPublicKey(huiFuProperties.getRsaPublicKey()); BasePay.initWithMerConfig(merConfig); // 2.组装请求参数 Map paramsInfo = new HashMap<>(); // 汇付ID paramsInfo.put("huifu_id", userWithdrawal.getHuifuId()); // 请求流水号 paramsInfo.put("req_seq_id", RequestSeqUtil.generateForHuiFu()); // 请求日期 paramsInfo.put("req_date", DateUtil.format(new Date(),"yyyyMMdd")); // 结算卡信息 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 response = BasePayRequest.requestBasePay("v2/user/busi/modify", paramsInfo, null, false);; log.info("用户业务入驻修改返回参数:{}", response); return response; } public static void main(String[] args) throws Exception { // 1. 数据初始化,填入对应的商户配置 MerConfig merConfig = new MerConfig(); // merConfig.setProcutId(huiFuProperties.getProductId()); // merConfig.setSysId(huiFuProperties.getSysId()); // merConfig.setRsaPrivateKey(huiFuProperties.getRsaPrivateKey()); // merConfig.setRsaPublicKey(huiFuProperties.getRsaPublicKey()); merConfig.setProcutId("KAZX"); merConfig.setSysId("6666000182995771"); merConfig.setRsaPrivateKey("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCR6W3ynQJL7f2C8vFYMcQkcirpkif9ZhLq1374jIlV87nv0T9uIm6DoW8LyNEl9w2Yc5qoBv70tt/oVpemA6IZY6NXzE2USNi/sv2qUTtapcIRYxe4acCfY8K+x+p7W2e6wUWIpl9qgZA+UnFmHQ0HT6Ywzq2jJL92JdIs147Ud1aVi3aX8LYItj0z3ZKwZQkaJawZSWQk2+EdPfN059L2qFkPtnT7JIthAdUTJYZA13K4tzw6mXp/DbgwVmLhrlmwl/ccSv2Q0ABfEk7jIxF1nZmCmSy3HrEw9xWyrg1BC+DgXBdyF0OEtpNfv+UW080syUVBNN0irHVuDP81BaAjAgMBAAECggEAGlBZprZQErdxz6rWgYxADj6UpJjaI2XEJZwFZveZUOnqb2hyIv+MpKp5Z0upBErApey7SHAyjJlqWfE72hGvqxp/+7Z5izNz+2ZhPtT1ekyIajBPt89CkLwiA9vz2plKZLC0RIeUj5WcGNEvaDX3AomHtCehwtk+uiTp+XJKbOBtkkQszcdCGY1DVoQ0ppFoINnM9VLbEzaFaG7VS3eFkU4cf2CwcrnJB1RncyPFK+bGFvjkLM/eQbsh8YxkBqaGz/8UM1Na1SEidqdyUF71ltqnI0u8pLe0V+5jugVW+3lPL/p1C3i7mAbQOs4yqRWlFaGVTzOawoQUOPVwDpzeeQKBgQDs1P7F4wURqX1qZR0hSTqOigg48ychaOF66new3SuWk2CVBy8Q8b7odGSPyxJSGZvFLoznPYuSaXCtQ935WWfjB7Z5JpSWCi9BmJnkh41k/KvgMqAEGkZP6ul/zFnDWj94VwXEBz3TuRk574vK2coWoxjM6h1dlJjRBVVTs8dnrQKBgQCduKCjPDUuOHbcNn3VsaHEZX1XyiXN5gds08o61PjiHM42wYXxfUt59nBJmg2yAVRIrKYHfswJcxb5XUTDI5ZhCBnIPrdrQzj7FNadm/7mKDvSsvZdpfTiHY341XnvCq7OcNNj8g5fVsWF769strepQReSug7xgX7ojPvVcAZhDwKBgD57KwP2Er5IIuhQ6NCBS0uTqvurWqV70BDnjtBAaWF+XDq0/HvR63XUTzuIbbrvOqNY1p+jIxFrc+iiQQupxLimrkNkJEs5QKJjqiYahPkhmA68DG9Ip0gqR5QJy5y4UIplGwZOiscyzC72vcC0mJZETSSylzC7JV3vtEUy5ua5AoGAEwlDqjAMIyYBgpa5HV+xLKkrNbtaUL2gy8vMLsmhuHjNkuJMrlb3EyNhbiC/4moyqArehy0Qp1tSvIo7UGotLkzx/69CKBoW+IcNWDyJyXG1trqO7cKoCdqTViM98lIRwyzu9rMydONeN8o0HCT5id4nYDhAsXl1vc+2XY6F1pUCgYEA0dxGHBTKD/WzIvTYGYD6Xx224Y84mO6x2Mu16zFoq/NjuIdKi2O+92yrKDCMMCqaY77fXvWD3eI7QYYlbKAOqdLKVipTbhnBccDyNbtYHVg59t4xS+K6HyD+quVkL9n40UkxSZbKZBQhqt+vlQy0FUgONFii1ACZO0A8Sc/bvn4="); merConfig.setRsaPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsWrruP9JBxrUd8uEX5Z8y7pg/UIr5RNHSgDnHqNI1hbi2MfTzB5vZ275wSFFaLDD9BesgDWqsUepPS/opROlDCg9y6WYH8mkN23NmHL9F8kT48OMmH722am+Hp0XVMMwXqA0oNt4f7oW6kDemjZW8/RT4vIE7cyxoxSsVRvjqSpx9wDgFLPWh3o0pHQaoxLyeUsGBATHFrxEDlosBvsuXjMcgjPKXALrcemzKOhBmBkLgyxNVmh61ZK+FNXd+/X4PeZlnWf54NRQAUKe1308E6IIaszo+CjneKuhj1m/X4f7AIvxAqlhuCV5E/DfKRmGopxaWqdtE960Y/H4SmBh2wIDAQAB"); BasePay.initWithMerConfig(merConfig); // 2.组装请求参数 Map paramsInfo = new HashMap<>(); // 请求流水号 paramsInfo.put("req_seq_id", "rQ20252119164e1617715e"); // 请求日期 paramsInfo.put("req_date", "20251125"); // 出款方商户号 paramsInfo.put("out_huifu_id", "6666000182995771"); // 支付金额 paramsInfo.put("ord_amt", "0.01"); // 分账对象 paramsInfo.put("acct_split_bunch", "{\"acct_infos\":[{\"div_amt\":\"0.01\",\"huifu_id\":\"6666000183987699\"}]}"); // 安全信息 paramsInfo.put("risk_check_data", "{\"sub_product\":\"1\",\"transfer_type\":\"05\"}"); // 手续费承担方标识余额支付手续费承担方标识;商户余额支付扣收规则为接口指定承担方时必填!枚举值:<br/>OUT:出款方;<br/>IN:分账接受方。<br/><font color="green">示例值:IN</font> paramsInfo.put("trans_fee_take_flag", "OUT"); // 核验值verify_type不为空时必填。当verify_type=SMS时,填写用户收到的短信验证码 // paramsInfo.put("verify_value", "test"); System.out.println(paramsInfo); // 3. 发起API调用 Map response = BasePayRequest.requestBasePay("v2/trade/acctpayment/pay", paramsInfo, null, false);; System.out.println(response); } /** * 电子账户余额查询 * * @return * @throws Exception */ public BigDecimal balanceQuery(String huifuId) throws Exception { // 1. 数据初始化,填入对应的商户配置 MerConfig merConfig = new MerConfig(); merConfig.setProcutId(huiFuProperties.getProductId()); merConfig.setSysId(huiFuProperties.getSysId()); merConfig.setRsaPrivateKey(huiFuProperties.getRsaPrivateKey()); merConfig.setRsaPublicKey(huiFuProperties.getRsaPublicKey()); BasePay.initWithMerConfig(merConfig); // 2.组装请求参数 Map paramsInfo = new HashMap<>(); // 汇付ID paramsInfo.put("huifu_id", huifuId); // 请求流水号 paramsInfo.put("req_seq_id", RequestSeqUtil.generateForHuiFu()); // 请求日期 paramsInfo.put("req_date", DateUtil.format(new Date(), "yyyyMMdd")); log.info("账户余额信息查询返回参数:{}", paramsInfo); // 3. 发起API调用 Map response = BasePayRequest.requestBasePay("v2/trade/acctpayment/balance/query", paramsInfo, null, false); log.info("账户余额信息查询返回参数:{}", response); String string = response.get("acctInfo_list").toString(); JSONArray accountList = JSONArray.parseArray(string); if (accountList != null && !accountList.isEmpty()) { JSONObject acctInfo = accountList.getJSONObject(0); log.info("账户余额信息查询返回余额:{}", acctInfo.getString("avail_bal")); return acctInfo.getBigDecimal("avl_bal"); } return BigDecimal.ZERO; } }