Files
jsowell-charger-web/jsowell-pile/src/main/java/com/jsowell/adapay/service/AdapayService.java
2026-03-25 16:19:15 +08:00

2058 lines
100 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.jsowell.adapay.service;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.TypeReference;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.huifu.adapay.core.exception.BaseAdaPayException;
import com.huifu.adapay.model.*;
import com.huifu.adapay.model.CorpMember;
import com.huifu.adapay.model.SettleAccount;
import com.jsowell.adapay.common.*;
import com.jsowell.adapay.config.AbstractAdapayConfig;
import com.jsowell.adapay.dto.*;
import com.jsowell.adapay.factory.AdapayConfigFactory;
import com.jsowell.adapay.operation.PaymentReverseOperation;
import com.jsowell.adapay.response.*;
import com.jsowell.adapay.vo.*;
import com.jsowell.common.constant.CacheConstants;
import com.jsowell.common.constant.Constants;
import com.jsowell.common.core.redis.RedisCache;
import com.jsowell.common.enums.DelFlagEnum;
import com.jsowell.common.enums.adapay.AdapayPayChannelEnum;
import com.jsowell.common.enums.adapay.AdapayStatusEnum;
import com.jsowell.common.enums.adapay.MerchantDelayModeEnum;
import com.jsowell.common.enums.ykc.ReturnCodeEnum;
import com.jsowell.common.exception.BusinessException;
import com.jsowell.common.util.AdapayUtil;
import com.jsowell.common.util.DateUtils;
import com.jsowell.common.util.StringUtils;
import com.jsowell.common.util.ZipUtil;
import com.jsowell.common.util.id.IdUtils;
import com.jsowell.pile.domain.AdapayMemberAccount;
import com.jsowell.pile.domain.ClearingBillInfo;
import com.jsowell.pile.domain.ClearingWithdrawInfo;
import com.jsowell.pile.domain.MemberBasicInfo;
import com.jsowell.pile.dto.PayOrderDTO;
import com.jsowell.pile.service.*;
import com.jsowell.pile.vo.base.MerchantInfoVO;
import com.jsowell.pile.vo.web.WithdrawInfoVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.io.File;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
@Slf4j
@Service
public class AdapayService {
@Autowired
private RedisCache redisCache;
@Value("${adapay.callback}")
private String ADAPAY_CALLBACK_URL;
String wechatAppId1 = "wxbb3e0d474569481d"; // 万车充
@Autowired
private AdapayMemberAccountService adapayMemberAccountService;
@Autowired
private ClearingWithdrawInfoService clearingWithdrawInfoService;
@Autowired
private ClearingBillInfoService clearingBillInfoService;
@Autowired
private PileMerchantInfoService pileMerchantInfoService;
@Autowired
private MemberBasicInfoService memberBasicInfoService;
/**
* 获取支付参数-微信支付
*/
public Map<String, Object> createPaymentForWechat(PayOrderDTO dto) {
// log.info("===============使用汇付支付-获取支付参数");
// 相同参数重复请求,返回同一个支付对象
String redisKey = CacheConstants.ADAPAY_ORDER_PARAM + dto.getOrderCode();
Map<String, Object> resultMap = redisCache.getCacheObject(redisKey);
if (resultMap != null) {
// 表示已经获取到支付参数了,后续再有支付请求就拒绝
return resultMap;
}
// 获取支付配置
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(dto.getWechatAppId());
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
// 获取openId
MemberBasicInfo memberBasicInfo = memberBasicInfoService.selectInfoByMemberId(dto.getMemberId());
if (memberBasicInfo == null) {
throw new BusinessException(ReturnCodeEnum.CODE_GET_OPEN_ID_BY_CODE_ERROR);
}
// 支付场景
String type = dto.getType();
// 封装对象
String amount = AdapayUtil.formatAmount(dto.getPayAmount()); // 用户支付金额
String delayMode = pileMerchantInfoService.getDelayModeByWechatAppId(dto.getWechatAppId());
String payMode = MerchantDelayModeEnum.getAdapayPayMode(delayMode);
CreateAdaPaymentParam createAdaPaymentParam = new CreateAdaPaymentParam();
// 请求订单号, 防止请求订单号重复,结尾拼接时间
String orderNo = dto.getOrderCode() + "_" + DateUtils.dateTimeNow();
createAdaPaymentParam.setOrder_no(orderNo);
createAdaPaymentParam.setPay_amt(amount);
createAdaPaymentParam.setApp_id(config.getAdapayAppId());
// todo 如果以后有支付宝等别的渠道,这里需要做修改,判断是什么渠道的请求
// 2024年6月13日11点55分需要兼容支付宝小程序首先判断请求来源如为空默认微信小程序
String payChannel = StringUtils.isNotBlank(dto.getRequestSource())
? dto.getRequestSource()
: AdapayPayChannelEnum.WX_LITE.getValue();
createAdaPaymentParam.setPay_channel(payChannel);
createAdaPaymentParam.setGoods_title(dto.getGoodsTitle());
createAdaPaymentParam.setGoods_desc(dto.getGoodsDesc()); // 这个字段是微信支付凭证的商品名
Map<String, String> map = Maps.newHashMap();
map.put("type", type);
map.put("orderCode", dto.getOrderCode());
map.put("payMode", payMode);
map.put("memberId", dto.getMemberId());
createAdaPaymentParam.setDescription(JSON.toJSONString(map));
// 异步通知地址url为http/https路径服务器POST回调URL 上请勿附带参数
createAdaPaymentParam.setNotify_url(ADAPAY_CALLBACK_URL);
createAdaPaymentParam.setExpend(JSON.toJSONString(ImmutableMap.of("open_id", memberBasicInfo.getOpenId())));
// 延时分账
if (StringUtils.isNotBlank(payMode)) {
createAdaPaymentParam.setPay_mode(payMode);
}
try {
Map<String, Object> response = Payment.create(BeanMap.create(createAdaPaymentParam), config.getWechatAppId());
log.info("创建汇付支付参数:{}, response:{}", JSON.toJSONString(createAdaPaymentParam), JSON.toJSONString(response));
if (response != null && !response.isEmpty()) {
String status = (String) response.get("status");
if (!StringUtils.equals(status, AdapayStatusEnum.SUCCEEDED.getValue())) {
String error_msg = (String) response.get("error_msg");
throw new BusinessException(ReturnCodeEnum.CODE_GET_WECHAT_PAY_PARAMETER_ERROR.getValue(), error_msg);
}
JSONObject expend = JSONObject.parseObject(response.get("expend").toString());
JSONObject pay_info = expend.getJSONObject("pay_info");
resultMap = JSONObject.parseObject(pay_info.toJSONString(), new TypeReference<Map<String, Object>>() {});
}
} catch (BaseAdaPayException e) {
log.error("汇付-获取支付对象发生异常, orderCode:{}", dto.getOrderCode(), e);
}
// 放缓存
if (resultMap != null) {
// 请求参数放入缓存15分钟以内返回同一个支付参数
redisCache.setCacheObject(redisKey, resultMap, 15, TimeUnit.MINUTES);
// 请求订单号放redis
redisCache.setCacheObject(CacheConstants.ORDER_WECHAT_PAY_PARAMETERS + dto.getOrderCode(), orderNo, CacheConstants.cache_expire_time_10d);
}
return resultMap;
}
/**
* 获取支付参数-支付宝支付
*/
public Map<String, Object> createPaymentForAlipay(PayOrderDTO dto) {
// log.info("===============使用汇付支付-获取支付参数");
// 相同参数重复请求,返回同一个支付对象
String redisKey = CacheConstants.ADAPAY_ORDER_PARAM + dto.getOrderCode();
Map<String, Object> resultMap = redisCache.getCacheObject(redisKey);
if (resultMap != null) {
// 表示已经获取到支付参数了,后续再有支付请求就拒绝
return resultMap;
}
// 获取支付配置
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(dto.getAlipayAppId());
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
// 获取openId
MemberBasicInfo memberBasicInfo = memberBasicInfoService.selectInfoByMemberId(dto.getMemberId());
if (memberBasicInfo == null) {
throw new BusinessException(ReturnCodeEnum.CODE_GET_OPEN_ID_BY_CODE_ERROR);
}
// 支付场景
String type = dto.getType();
// 封装对象
String amount = AdapayUtil.formatAmount(dto.getPayAmount()); // 用户支付金额
String delayMode = dto.getDelayMode();
if (StringUtils.isBlank(delayMode)) {
delayMode = pileMerchantInfoService.getDelayModeByAlipayAppId(dto.getAlipayAppId());
}
String payMode = MerchantDelayModeEnum.getAdapayPayMode(delayMode);
CreateAdaPaymentParam createAdaPaymentParam = new CreateAdaPaymentParam();
// 请求订单号, 防止请求订单号重复,结尾拼接时间
String orderNo = dto.getOrderCode() + "_" + DateUtils.dateTimeNow();
createAdaPaymentParam.setOrder_no(orderNo);
createAdaPaymentParam.setPay_amt(amount);
createAdaPaymentParam.setApp_id(config.getAdapayAppId());
// 2024年6月13日11点55分需要兼容支付宝小程序首先判断请求来源如为空默认微信小程序
String payChannel = StringUtils.isNotBlank(dto.getRequestSource())
? dto.getRequestSource()
: AdapayPayChannelEnum.WX_LITE.getValue();
createAdaPaymentParam.setPay_channel(payChannel);
createAdaPaymentParam.setGoods_title(dto.getGoodsTitle());
createAdaPaymentParam.setGoods_desc(dto.getGoodsDesc()); // 这个字段是微信支付凭证的商品名
Map<String, String> map = Maps.newHashMap();
map.put("type", type);
map.put("orderCode", dto.getOrderCode());
map.put("payMode", payMode);
map.put("memberId", dto.getMemberId());
createAdaPaymentParam.setDescription(JSON.toJSONString(map));
// 异步通知地址url为http/https路径服务器POST回调URL 上请勿附带参数
createAdaPaymentParam.setNotify_url(ADAPAY_CALLBACK_URL);
// alipay_lite参数 buyer_id String(100) Y 买家的支付宝用户 id
createAdaPaymentParam.setExpend(JSON.toJSONString(ImmutableMap.of("buyer_id", memberBasicInfo.getBuyerId())));
// 延时分账
if (StringUtils.isNotBlank(payMode)) {
createAdaPaymentParam.setPay_mode(payMode);
}
try {
Map<String, Object> response = Payment.create(BeanMap.create(createAdaPaymentParam), config.getWechatAppId());
log.info("创建汇付支付参数:{}, response:{}", JSON.toJSONString(createAdaPaymentParam), JSON.toJSONString(response));
if (response != null && !response.isEmpty()) {
String status = (String) response.get("status");
if (!StringUtils.equals(status, AdapayStatusEnum.SUCCEEDED.getValue())) {
String error_msg = (String) response.get("error_msg");
throw new BusinessException(ReturnCodeEnum.CODE_GET_WECHAT_PAY_PARAMETER_ERROR.getValue(), error_msg);
}
JSONObject expend = JSONObject.parseObject(response.get("expend").toString());
JSONObject pay_info = expend.getJSONObject("pay_info");
resultMap = JSONObject.parseObject(pay_info.toJSONString(), new TypeReference<Map<String, Object>>() {});
}
} catch (BaseAdaPayException e) {
log.error("汇付-获取支付对象发生异常, orderCode:{}", dto.getOrderCode(), e);
}
// 放缓存
if (resultMap != null) {
// 请求参数放入缓存15分钟以内返回同一个支付参数
redisCache.setCacheObject(redisKey, resultMap, 15, TimeUnit.MINUTES);
// 请求订单号放redis
redisCache.setCacheObject(CacheConstants.ORDER_WECHAT_PAY_PARAMETERS + dto.getOrderCode(), orderNo, CacheConstants.cache_expire_time_10d);
}
return resultMap;
}
/**
* 创建个人用户
*/
public void createAdapayMember(CreatePersonalMemberDTO dto) throws BaseAdaPayException, BusinessException {
SettleAccountDTO request = SettleAccountDTO.builder()
.merchantId(dto.getMerchantId())
.location(dto.getLocation())
.email(dto.getEmail())
.gender(dto.getGender())
.nickname(dto.getNickname())
.wechatAppId(pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId()))
.build();
createMember(request);
}
/**
* 创建企业用户
*/
public void createCorpMember(CreateCorpMemberDTO dto) throws BaseAdaPayException, BusinessException {
SettleAccountDTO request = SettleAccountDTO.builder()
.merchantId(dto.getMerchantId())
.wechatAppId(pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId()))
.businessName(dto.getName())
.provCode(dto.getProvCode())
.areaCode(dto.getAreaCode())
.socialCreditCode(dto.getSocialCreditCode())
.socialCreditCodeExpires(dto.getSocialCreditCodeExpires())
.businessScope(dto.getBusinessScope())
.legalPerson(dto.getLegalPerson())
.legalCertId(dto.getLegalCertId())
.legalCertIdExpires(dto.getLegalCertIdExpires())
.legalMp(dto.getLegalMp())
.address(dto.getAddress())
.zipCode(dto.getZipCode())
.telphone(dto.getTelphone())
.email(dto.getEmail())
.imgList(dto.getImgList())
.build();
createCorpMember(request);
}
/**
* 创建结算账户
*/
public void createSettleAccount(CreateSettleAccountDTO dto) throws BaseAdaPayException, BusinessException {
AdapayMemberAccount adapayMemberAccount = requireCurrentMemberAccount(dto.getMerchantId());
if (CollectionUtils.isNotEmpty(selectSettleAccount(dto.getMerchantId()))) {
throw new BusinessException("", "当前商户已存在结算账户");
}
String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId());
SettleAccountDTO request = buildSettleAccountDTO(dto);
Map<String, Object> settleCount = createSettleAccountRequest(request, adapayMemberAccount.getAdapayMemberId(), wechatAppId);
if (settleCount == null || StringUtils.equals((String) settleCount.get("status"), "failed")) {
String errorMsg = settleCount == null ? "创建汇付结算账户失败" : (String) settleCount.get("error_msg");
throw new BusinessException("00500001", errorMsg);
}
AdapayMemberAccount updateRecord = new AdapayMemberAccount();
updateRecord.setAdapayMemberId(adapayMemberAccount.getAdapayMemberId());
updateRecord.setSettleAccountId((String) settleCount.get("id"));
adapayMemberAccountService.updateAdapayMemberAccountByMemberId(updateRecord);
}
/**
* 查询当前商户的结算账户
*/
public List<AdapaySettleAccountVO> selectSettleAccount(String merchantId) throws BaseAdaPayException {
AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(merchantId);
if (adapayMemberAccount == null) {
return Lists.newArrayList();
}
String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(merchantId);
String settleAccountId = adapayMemberAccount.getSettleAccountId();
if (StringUtils.isBlank(settleAccountId) && isCorpMember(adapayMemberAccount.getAdapayMemberId())) {
AdapayCorpMemberVO corpMemberVO = queryCorpAdapayMemberInfo(adapayMemberAccount.getAdapayMemberId(), wechatAppId);
if (corpMemberVO != null) {
settleAccountId = corpMemberVO.getSettleAccountId();
}
}
AdapaySettleAccountVO adapaySettleAccountVO = queryAdapaySettleAccount(adapayMemberAccount.getAdapayMemberId(), settleAccountId, wechatAppId);
if (adapaySettleAccountVO == null) {
return Lists.newArrayList();
}
adapaySettleAccountVO.setMerchantId(merchantId);
return Lists.newArrayList(adapaySettleAccountVO);
}
/**
* 创建汇付会员
*
* @param dto
* @throws Exception
*/
@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public void createMember(SettleAccountDTO dto) throws BaseAdaPayException, BusinessException {
// 获取汇付支付配置
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(dto.getWechatAppId());
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
// 逻辑删除原来审核不通过的记录
adapayMemberAccountService.deleteAuditFailed(dto.getMerchantId());
// 查询汇付会员关系
AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(dto.getMerchantId());
if (adapayMemberAccount != null) {
throw new BusinessException("", "当前商户已绑定汇付用户");
}
log.info("=======execute CreateMember begin=======");
Map<String, Object> memberParams = Maps.newHashMap();
String adapayMemberId = Constants.ADAPAY_MEMBER_PREFIX + IdUtils.getMemberId();
memberParams.put("member_id", adapayMemberId);
memberParams.put("app_id", config.getAdapayAppId());
memberParams.put("location", dto.getLocation());
memberParams.put("email", dto.getEmail());
memberParams.put("gender", dto.getGender());
memberParams.put("nickname", dto.getNickname());
log.info("创建用户,请求参数:" + JSON.toJSONString(memberParams));
Map<String, Object> member = Member.create(memberParams, config.getWechatAppId());
log.info("创建用户,返回参数:" + JSON.toJSONString(member));
log.info("=======execute CreateMember end=======");
if (member == null || StringUtils.equals((String) member.get("status"), "failed")) {
String errorMsg = member == null ? "创建汇付用户失败" : (String) member.get("error_msg");
throw new BusinessException("00500001", errorMsg);
}
// 保存到数据库
adapayMemberAccount = new AdapayMemberAccount();
adapayMemberAccount.setMerchantId(dto.getMerchantId());
adapayMemberAccount.setAdapayMemberId(adapayMemberId);
adapayMemberAccount.setStatus(Constants.ONE);
adapayMemberAccountService.insertAdapayMemberAccount(adapayMemberAccount);
}
/**
* 查询汇付会员信息
*
* @param merchantId
* @return
*/
public AdapayMemberAggregateVO selectAdapayMember(String merchantId) throws BaseAdaPayException {
AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(merchantId);
if (adapayMemberAccount == null) {
log.error("通过merchantId:{}, 没有查询到结算账户配置", merchantId);
return null;
}
AdapayMemberAggregateVO.AdapayMemberAggregateVOBuilder builder = AdapayMemberAggregateVO.builder()
.adapayMemberId(adapayMemberAccount.getAdapayMemberId());
// 审核失败
if (Constants.TWO.equals(adapayMemberAccount.getStatus())) {
AdapayCorpMemberVO adapayCorpMemberVO = new AdapayCorpMemberVO();
MerchantInfoVO merchantInfoVO = pileMerchantInfoService.getMerchantInfoVO(adapayMemberAccount.getMerchantId());
if (merchantInfoVO != null) {
adapayCorpMemberVO.setName(merchantInfoVO.getMerchantName());
}
adapayCorpMemberVO.setAuditState("B");
adapayCorpMemberVO.setAuditDesc(adapayMemberAccount.getRemark());
return builder
.memberType("CORP")
.bankAcctType(Constants.ONE)
.adapayCorpMember(adapayCorpMemberVO)
.settleAccountList(Lists.newArrayList())
.canDeleteUser(true)
.build();
}
// 通过merchantId获取appId
String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(merchantId);
String adapayMemberId = adapayMemberAccount.getAdapayMemberId();
List<AdapaySettleAccountVO> settleAccountList = selectSettleAccount(merchantId);
boolean canDeleteUser = CollectionUtils.isEmpty(settleAccountList);
builder
.settleAccountList(settleAccountList)
.canDeleteUser(canDeleteUser)
.deleteBlockReason(canDeleteUser ? "" : "请先删除结算账户");
if (StringUtils.startsWith(adapayMemberId, Constants.ADAPAY_MEMBER_PREFIX)) {
// 查询个人用户
AdapayMemberInfoVO adapayMemberInfoVO = queryAdapayMemberInfo(adapayMemberId, wechatAppId);
return builder
.memberType("PERSONAL")
.bankAcctType(Constants.TWO)
.adapayMember(adapayMemberInfoVO)
.build();
}
// 查询企业用户
AdapayCorpMemberVO adapayCorpMemberVO = queryCorpAdapayMemberInfo(adapayMemberId, wechatAppId);
return builder
.memberType("CORP")
.bankAcctType(Constants.ONE)
.adapayCorpMember(adapayCorpMemberVO)
.build();
}
/**
* 查询汇付会员信息
*/
public AdapayMemberInfoVO queryAdapayMemberInfo(String adapayMemberId, String wechatAppId) throws BaseAdaPayException {
// 获取汇付支付配置
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId);
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
if (StringUtils.isBlank(adapayMemberId)) {
return null;
}
Map<String, Object> memberParams = Maps.newHashMap();
memberParams.put("member_id", adapayMemberId);
memberParams.put("app_id", config.getAdapayAppId());
Map<String, Object> member = Member.query(memberParams, config.getWechatAppId());
log.info("==查询个人用户,请求参数:{},返回参数:{}", JSON.toJSONString(memberParams), JSON.toJSONString(member));
if (member == null || member.isEmpty() || !"succeeded".equals(member.get("status"))) {
return null;
}
QueryMemberResponse queryMemberResponse = JSON.parseObject(JSON.toJSONString(member), QueryMemberResponse.class);
AdapayMemberInfoVO resultVO = AdapayMemberInfoVO.builder()
.memberId(adapayMemberId)
.nickname(queryMemberResponse.getNickname())
.gender(queryMemberResponse.getGender())
.email(queryMemberResponse.getEmail())
.location(queryMemberResponse.getLocation())
.build();
return resultVO;
}
/**
* 查询企业用户信息
*/
public AdapayCorpMemberVO queryCorpAdapayMemberInfo(String adapayMemberId, String wechatAppId) throws BaseAdaPayException {
// 获取汇付支付配置
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId);
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
Map<String, Object> memberParams = Maps.newHashMap();
memberParams.put("member_id", adapayMemberId);
memberParams.put("app_id", config.getAdapayAppId());
Map<String, Object> member = CorpMember.query(memberParams, config.getWechatAppId());
log.info("==查询企业用户信息 param:{}, result:{}", JSON.toJSONString(memberParams), JSON.toJSONString(member));
if (member == null || member.isEmpty() || !"succeeded".equals(member.get("status"))) {
return null;
}
QueryCorpMemberResponse response = JSONObject.parseObject(JSON.toJSONString(member), QueryCorpMemberResponse.class);
AdapayCorpMemberVO corpMemberVO = AdapayCorpMemberVO.builder()
.memberId(adapayMemberId)
.address(response.getAddress())
.name(response.getName())
.areaCode(response.getArea_code())
.provCode(response.getProv_code())
.auditDesc(response.getAudit_desc())
.auditState(response.getAudit_state())
.legalCertIdExpires(response.getLegal_cert_id_expires())
.businessScope(response.getBusiness_scope())
.legalMp(response.getLegal_mp())
.legalPerson(response.getLegal_person())
.legalCertId(response.getLegal_cert_id())
.telphone(response.getTelphone())
.zipCode(response.getZip_code())
.email(response.getEmail())
.socialCreditCode(response.getSocial_credit_code())
.socialCreditCodeExpires(response.getSocial_credit_code_expires())
.build();
if (StringUtils.isNotBlank(response.getSettle_accounts())) {
JSONObject jsonObject = JSON.parseObject(response.getSettle_accounts());
JSONObject recipient = jsonObject.getJSONObject("recipient");
if (recipient != null) {
corpMemberVO.setCardName(recipient.getString("cardName"));
corpMemberVO.setCardNo(recipient.getString("cardNo"));
}
String settleAccountId = jsonObject.getString("id");
if (StringUtils.isNotEmpty(settleAccountId)) {
corpMemberVO.setSettleAccountId(settleAccountId);
AdapaySettleAccountVO adapaySettleAccountVO = queryAdapaySettleAccount(adapayMemberId, settleAccountId, config.getWechatAppId());
if (adapaySettleAccountVO != null) {
corpMemberVO.setBankCode(adapaySettleAccountVO.getBankCode());
}
}
}
return corpMemberVO;
}
/**
* 创建结算账户请求
*/
public Map<String, Object> createSettleAccountRequest(SettleAccountDTO dto, String adapayMemberId, String wechatAppId) throws BaseAdaPayException {
// 获取汇付支付配置
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId);
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
// 创建结算账户
Map<String, Object> accountInfo = Maps.newHashMap();
// 银行卡号
accountInfo.put("card_id", dto.getCardId());
accountInfo.put("card_no", dto.getCardNo());
// 银行卡对应的户名
accountInfo.put("card_name", dto.getCardName());
// 证件号,银行账户类型为对私时,必填
if (StringUtils.isNotBlank(dto.getCertId())) {
accountInfo.put("cert_id", dto.getCertId());
}
// 证件类型仅支持00-身份证,银行账户类型为对私时,必填
accountInfo.put("cert_type", "00");
// 手机号
accountInfo.put("tel_no", dto.getTelNo());
// 银行编码,详见附录 银行代码,银行账户类型对公时,必填
if (StringUtils.isNotBlank(dto.getBankCode())) {
accountInfo.put("bank_code", dto.getBankCode());
}
// 银行账户类型1-对公2-对私
accountInfo.put("bank_acct_type", dto.getBankAcctType());
// 银行账户开户银行所在省份编码 (省市编码),银行账户类型为对公时,必填
if (StringUtils.isNotBlank(dto.getProvCode())) {
accountInfo.put("prov_code", dto.getProvCode());
}
// 银行账户开户银行所在地区编码(省市编码),银行账户类型为对公时,必填
if (StringUtils.isNotBlank(dto.getAreaCode())) {
accountInfo.put("area_code", dto.getAreaCode());
}
Map<String, Object> settleCountParams = Maps.newHashMap();
settleCountParams.put("member_id", adapayMemberId);
settleCountParams.put("app_id", config.getAdapayAppId());
// channel String Y 目前仅支持bank_account银行卡
settleCountParams.put("channel", "bank_account");
settleCountParams.put("account_info", accountInfo);
Map<String, Object> settleCount = SettleAccount.create(settleCountParams, config.getWechatAppId());
log.info("创建汇付结算账户param:{}, result:{}", JSON.toJSONString(settleCountParams), JSON.toJSONString(settleCount));
return settleCount;
}
/**
* 删除结算账户对象/创建删除结算账户请求
* 企业用户更新银行卡信息时调用,先删除后新建
*/
public void createDeleteSettleAccountRequest(String adapayMemberId, String settleAccountId, String wechatAppId) throws BaseAdaPayException {
// 获取汇付支付配置
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId);
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
Map<String, Object> settleCountParams = Maps.newHashMap();
settleCountParams.put("settle_account_id", settleAccountId);
settleCountParams.put("member_id", adapayMemberId);
settleCountParams.put("app_id", config.getAdapayAppId());
Map<String, Object> settleCount = SettleAccount.delete(settleCountParams, wechatAppId);
log.info("创建删除结算账户请求param:{}, result:{}", JSON.toJSONString(settleCountParams), JSON.toJSONString(settleCount));
}
/**
* 查询汇付结算账户信息
*/
public AdapaySettleAccountVO queryAdapaySettleAccount(String adapayMemberId, String settleAccountId, String wechatAppId) throws BaseAdaPayException {
// 获取汇付支付配置
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId);
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
if (StringUtils.isBlank(adapayMemberId) || StringUtils.isBlank(settleAccountId)) {
return null;
}
Map<String, Object> settleCountParams = Maps.newHashMap();
settleCountParams.put("settle_account_id", settleAccountId);
settleCountParams.put("member_id", adapayMemberId);
settleCountParams.put("app_id", config.getAdapayAppId());
Map<String, Object> settleAccount = SettleAccount.query(settleCountParams, config.getWechatAppId());
log.info("==查询汇付结算账户信息param:{}, result:{}", JSON.toJSONString(settleCountParams), JSON.toJSONString(settleAccount));
if (settleAccount == null || settleAccount.isEmpty() || !"succeeded".equals(settleAccount.get("status"))) {
return null;
}
QueryMemberResponse.SettleAccount settleAccountInfo = JSON.parseObject(JSON.toJSONString(settleAccount), QueryMemberResponse.SettleAccount.class);
QueryMemberResponse.AccountInfo accountInfo = settleAccountInfo.getAccount_info();
AdapaySettleAccountVO resultVO = AdapaySettleAccountVO.builder()
.adapayMemberId(settleAccountInfo.getMember_id())
.settleAccountId(settleAccountInfo.getId())
.cardId(accountInfo.getCard_id())
.cardName(accountInfo.getCard_name())
.certId(accountInfo.getCert_id())
.certType(accountInfo.getCert_type())
.telNo(accountInfo.getTel_no())
.bankName(accountInfo.getBank_name())
.bankCode(accountInfo.getBank_code())
.bankAcctType(accountInfo.getBank_acct_type())
.provCode(accountInfo.getProv_code())
.areaCode(accountInfo.getArea_code())
.build();
return resultVO;
}
/**
* 查询汇付会员账户余额
*/
public AdapayAccountBalanceVO queryAdapayAccountBalance(String merchantId) throws BaseAdaPayException {
String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(merchantId);
// 获取汇付支付配置
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId);
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
AdapayAccountBalanceVO vo = AdapayAccountBalanceVO.builder().build();
// 通过merchantId 查询出汇付会员id 和 结算账户id用来查询余额
AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(merchantId);
if (adapayMemberAccount == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_MEMBER_IS_NULL_ERROR);
}
String settle_account_id = adapayMemberAccount.getSettleAccountId();
String member_id = adapayMemberAccount.getAdapayMemberId();
Map<String, Object> queryParams = Maps.newHashMap();
queryParams.put("settle_account_id", settle_account_id);
queryParams.put("member_id", member_id);
queryParams.put("app_id", config.getAdapayAppId());
Map<String, Object> settleCount = SettleAccount.balance(queryParams, config.getWechatAppId());
if (settleCount == null || settleCount.isEmpty() || !"succeeded".equals(settleCount.get("status"))) {
return vo;
}
vo.setFrzBalance(new BigDecimal((String) settleCount.get("frz_balance")));
vo.setAcctBalance(new BigDecimal((String) settleCount.get("acct_balance")));
vo.setAvlBalance(new BigDecimal((String) settleCount.get("avl_balance")));
vo.setLastAvlBalance(new BigDecimal((String) settleCount.get("last_avl_balance")));
vo.setAdapayMemberId(adapayMemberAccount.getAdapayMemberId());
vo.setSettleAccountId(adapayMemberAccount.getSettleAccountId());
// 昨日收入
BigDecimal yesterdayRevenue = BigDecimal.ZERO;
ClearingBillInfo clearingBillInfo = clearingBillInfoService.selectByMerchantIdAndTradeDate(merchantId, DateUtils.getYesterdayStr());
if (clearingBillInfo != null) {
yesterdayRevenue = clearingBillInfo.getActualClearingAmount();
}
vo.setYesterdayRevenue(yesterdayRevenue);
// 累计提现金额
// BigDecimal totalWithdraw = BigDecimal.ZERO;
// List<WithdrawInfoVO> withdrawInfoVOS = clearingWithdrawInfoService.selectByMerchantId(merchantId);
// if (CollectionUtils.isNotEmpty(withdrawInfoVOS)) {
// totalWithdraw = withdrawInfoVOS.stream().map(WithdrawInfoVO::getCashAmt).reduce(BigDecimal.ZERO, BigDecimal::add);
// }
// BigDecimal totalWithdraw = clearingWithdrawInfoService.queryTotalWithdraw(merchantId);
vo.setTotalWithdraw(clearingWithdrawInfoService.queryTotalWithdraw(merchantId));
// 在途金额
BigDecimal pendingAmount = BigDecimal.ZERO;
BigDecimal todayWithdrawalAmount = BigDecimal.ZERO;
List<WithdrawInfoVO> withdrawInfoVOS = clearingWithdrawInfoService.selectByMerchantId(merchantId);
// log.info("==查询提现在途金额param:{}, result:{}", JSON.toJSONString(withdrawInfoVOS), JSON.toJSONString(pendingAmount));
if (CollectionUtils.isNotEmpty(withdrawInfoVOS)) {
pendingAmount = withdrawInfoVOS.stream()
.filter(item -> Constants.ZERO.equals(item.getStatusDesc()))
.map(WithdrawInfoVO::getCashAmt)
.reduce(BigDecimal.ZERO, BigDecimal::add);
// 查询今天的提现金额
for (WithdrawInfoVO withdrawInfoVO : withdrawInfoVOS) {
// 如果applicationTime在当天则加到todayWithdrawalAmount中
if (DateUtils.isToday(withdrawInfoVO.getApplicationTime())) {
todayWithdrawalAmount = todayWithdrawalAmount.add(withdrawInfoVO.getCashAmt());
}
}
}
vo.setPendingAmount(pendingAmount);
// BigDecimal todayWithdrawalAmount = clearingWithdrawInfoService.queryTodayWithdrawalAmount(merchantId);
// 如果大于0则重新更新LastAvlBalance
if (todayWithdrawalAmount.compareTo(BigDecimal.ZERO) > 0) {
vo.setLastAvlBalance(BigDecimal.ZERO.max(vo.getLastAvlBalance().subtract(todayWithdrawalAmount)));
}
return vo;
}
/**
* 更新结算账户设置
*
* @param dto
* @throws BaseAdaPayException
*/
public void updateSettleAccountConfig(UpdateAccountConfigDTO dto) throws BaseAdaPayException {
String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId());
// 获取汇付支付配置
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId);
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
// 通过merchantId 查询出汇付会员id 和 结算账户id用来查询余额
AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(dto.getMerchantId());
if (adapayMemberAccount == null) {
log.error("通过merchantId:{}, 没有查询到结算账户配置", dto.getMerchantId());
return;
}
// 修改账户配置
Map<String, Object> params = Maps.newHashMap();
params.put("app_id", config.getAdapayAppId());
params.put("member_id", adapayMemberAccount.getAdapayMemberId());
params.put("settle_account_id", adapayMemberAccount.getSettleAccountId());
if (StringUtils.isNotBlank(dto.getMinAmt())) {
params.put("min_amt", dto.getMinAmt());
}
if (StringUtils.isNotBlank(dto.getRemainedAmt())) {
params.put("remained_amt", dto.getRemainedAmt());
}
if (StringUtils.isNotBlank(dto.getChannelRemark())) {
params.put("channel_remark", dto.getChannelRemark());
}
Map<String, Object> settleCount = SettleAccount.update(params);
log.info("更新结算账户设置 param:{}, result:{}", JSON.toJSONString(params), JSON.toJSONString(settleCount));
}
/**
* 创建企业用户
*/
public void createCorpMember(SettleAccountDTO dto) throws BaseAdaPayException, BusinessException {
// 获取汇付支付配置
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(dto.getWechatAppId());
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
// 逻辑删除原来审核不通过的记录
adapayMemberAccountService.deleteAuditFailed(dto.getMerchantId());
AdapayMemberAccount currentAccount = adapayMemberAccountService.selectByMerchantId(dto.getMerchantId());
if (currentAccount != null) {
throw new BusinessException("", "当前商户已绑定汇付用户");
}
// 创建企业用户参数
Map<String, Object> memberParams = Maps.newHashMap();
String adapayMemberId = Constants.ADAPAY_CORP_MEMBER_PREFIX + IdUtils.getMemberId();
// 先保存一条记录
AdapayMemberAccount adapayMemberAccount = new AdapayMemberAccount();
adapayMemberAccount.setMerchantId(dto.getMerchantId());
adapayMemberAccount.setAdapayMemberId(adapayMemberId);
adapayMemberAccount.setStatus(Constants.ZERO);
adapayMemberAccountService.insertAdapayMemberAccount(adapayMemberAccount);
memberParams.put("member_id", adapayMemberId);
memberParams.put("app_id", config.getAdapayAppId());
// memberParams.put("order_no", "jsdk_order" + System.currentTimeMillis());
memberParams.put("order_no", IdUtils.get16UUID("jsdk_order"));
memberParams.put("social_credit_code_expires", dto.getSocialCreditCodeExpires());
memberParams.put("business_scope", dto.getBusinessScope());
memberParams.put("name", dto.getBusinessName());
memberParams.put("prov_code", dto.getProvCode());
memberParams.put("area_code", dto.getAreaCode());
memberParams.put("social_credit_code", dto.getSocialCreditCode());
memberParams.put("legal_person", dto.getLegalPerson());
memberParams.put("legal_cert_id", dto.getLegalCertId());
memberParams.put("legal_cert_id_expires", dto.getLegalCertIdExpires());
memberParams.put("legal_mp", dto.getLegalMp());
memberParams.put("address", dto.getAddress());
memberParams.put("zip_code", dto.getZipCode());
memberParams.put("telphone", dto.getTelphone());
memberParams.put("email", dto.getEmail());
memberParams.put("notify_url", ADAPAY_CALLBACK_URL);
File file = ZipUtil.createZipFileFromImages(dto.getImgList());
Map<String, Object> member = CorpMember.create(memberParams, file, config.getWechatAppId());
log.info("创建企业账户param:{}, result:{}", JSON.toJSONString(memberParams), JSON.toJSONString(member));
if (StringUtils.equals((String) member.get("status"), "failed")) {
String error_msg = (String) member.get("error_msg");
adapayMemberAccount.setStatus(Constants.TWO); // 创建失败,改状态
adapayMemberAccount.setRemark(error_msg);
adapayMemberAccountService.updateAdapayMemberAccount(adapayMemberAccount);
throw new BusinessException("", error_msg);
}
// 取消自动创建结算账户,手动创建结算账户
// Map<String, Object> settleCount = createSettleAccountRequest(dto, adapayMemberId, dto.getWechatAppId());
//
// if (settleCount == null || StringUtils.equals((String) settleCount.get("status"), "failed")) {
// String errorMsg = settleCount == null ? "创建汇付结算账户失败" : (String) settleCount.get("error_msg");
// throw new BusinessException("00500001", errorMsg);
// }
// String settleAccountId = (String) settleCount.get("id");
// // 更新数据库
// adapayMemberAccount.setSettleAccountId(settleAccountId);
// adapayMemberAccountService.updateAdapayMemberAccount(adapayMemberAccount);
}
/**
* 提现逻辑/创建取现对象
*
* @param dto
* @throws BaseAdaPayException
*/
public void drawCash(WithdrawDTO dto) throws BaseAdaPayException {
String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId());
// 获取汇付支付配置
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId);
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
// 查询余额
AdapayAccountBalanceVO adapayAccountBalanceVO = queryAdapayAccountBalance(dto.getMerchantId());
if (adapayAccountBalanceVO == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_MEMBER_IS_NULL_ERROR);
}
// 提现金额为昨日金额 withdrawalAmount
BigDecimal withdrawalAmount = adapayAccountBalanceVO.getLastAvlBalance();
// 提现手续费 每笔固定5元 2025年2月13日11点47分手续费改为参数传入
// BigDecimal feeAmt = new BigDecimal("5");
BigDecimal feeAmt = new BigDecimal(dto.getFeeAmt());
// 实际提现到账金额
BigDecimal cashAmt = withdrawalAmount.subtract(feeAmt);
// 可提现金额减去手续费后需大于0
if (cashAmt.compareTo(BigDecimal.ZERO) <= 0) {
throw new BusinessException(ReturnCodeEnum.CODE_INSUFFICIENT_BALANCE_ERROR);
}
// 发送提现申请
// Map<String, Object> settleCountParams = Maps.newHashMap();
String orderNo = "drawcash_" + dto.getMerchantId() + "_" + System.currentTimeMillis();
// settleCountParams.put("order_no", orderNo);
// settleCountParams.put("cash_amt", AdapayUtil.formatAmount(cashAmt));
// settleCountParams.put("member_id", adapayAccountBalanceVO.getAdapayMemberId());
// settleCountParams.put("app_id", config.getAdapayAppId());
// settleCountParams.put("settle_account_id", adapayAccountBalanceVO.getSettleAccountId());
// settleCountParams.put("cash_type", "T1");
// settleCountParams.put("notify_url", ADAPAY_CALLBACK_URL);
Map<String, Object> settleCount = createDrawcashRequest(orderNo, cashAmt, adapayAccountBalanceVO.getAdapayMemberId(), config.getAdapayAppId(), adapayAccountBalanceVO.getSettleAccountId(), config.getWechatAppId());
// log.info("申请取现接口,请求参数:{}, 返回参数:{}", JSON.toJSONString(settleCountParams), JSON.toJSONString(settleCount));
if (settleCount == null) {
throw new BusinessException("", "申请取现接口发生异常");
}
if (AdapayStatusEnum.FAILED.getValue().equals(settleCount.get("status"))) {
throw new BusinessException((String) settleCount.get("error_code"), (String) settleCount.get("error_msg"));
}
String id = (String) settleCount.get("id");
// 发起支付手续费请求 inMemberId为0表示本商户
if (BigDecimal.ZERO.compareTo(feeAmt) > 0) {
createBalancePaymentRequest(adapayAccountBalanceVO.getAdapayMemberId(), Constants.ZERO, feeAmt.toString(), "提现手续费", "提现单号:" + id, config.getWechatAppId());
}
// 保存提现记录
ClearingWithdrawInfo record = new ClearingWithdrawInfo();
record.setMerchantId(dto.getMerchantId());
record.setWithdrawCode(id);
record.setOrderNo(orderNo);
record.setWithdrawStatus(Constants.ZERO);
record.setWithdrawAmt(withdrawalAmount); // 申请提现金额
record.setFeeAmt(feeAmt); // 提现手续费
record.setCreditedAmt(cashAmt); // 到账金额
Date now = new Date();
record.setApplicationTime(now);
record.setCreateTime(now);
record.setDelFlag(DelFlagEnum.NORMAL.getValue());
clearingWithdrawInfoService.insertSelective(record);
// 修改清分账单为提现中
List<ClearingBillInfo> list = clearingBillInfoService.selectByMerchantId(dto.getMerchantId(), "2");
List<Integer> clearingBillIds = list.stream().map(ClearingBillInfo::getId).collect(Collectors.toList());
String billStatus = "3";
clearingBillInfoService.updateStatus(clearingBillIds, billStatus, id);
}
/**
* 创建提现请求
*/
public Map<String, Object> createDrawcashRequest(String orderNo, BigDecimal cashAmt, String adapayMemberId, String adapayAppId, String settleAccountId, String wechatAppId) throws BaseAdaPayException {
Map<String, Object> settleCountParams = Maps.newHashMap();
settleCountParams.put("order_no", orderNo);
settleCountParams.put("cash_amt", AdapayUtil.formatAmount(cashAmt));
settleCountParams.put("member_id", adapayMemberId);
settleCountParams.put("app_id", adapayAppId);
settleCountParams.put("settle_account_id", settleAccountId);
settleCountParams.put("cash_type", "T1");
settleCountParams.put("notify_url", ADAPAY_CALLBACK_URL);
Map<String, Object> settleCount = Drawcash.create(settleCountParams, wechatAppId);
log.info("申请取现接口,请求参数:{}, 返回参数:{}", JSON.toJSONString(settleCountParams), JSON.toJSONString(settleCount));
return settleCount;
}
/**
* 查询取现对象
*
* @param orderNo 请求订单号
*/
public DrawCashDetailVO queryDrawCashDetail(String orderNo, String wechatAppId) throws BaseAdaPayException {
Map<String, Object> queryCashParam = Maps.newHashMap();
queryCashParam.put("order_no", orderNo);
Map<String, Object> response = Drawcash.query(queryCashParam, wechatAppId);
log.info("查询取现对象param:{}, result:{}", JSON.toJSONString(queryCashParam), JSON.toJSONString(response));
if (response != null) {
QueryDrawCashResponse queryDrawCashResponse = JSON.parseObject(JSON.toJSONString(response), QueryDrawCashResponse.class);
if (queryDrawCashResponse == null || queryDrawCashResponse.isNotSuccess()) {
return null;
}
QueryDrawCashResponse.Cash cash = queryDrawCashResponse.getCashList().get(0);
DrawCashDetailVO vo = new DrawCashDetailVO();
vo.setCashId(cash.getCashId());
vo.setCashAmt(cash.getCashAmt());
vo.setTransStat(cash.getTransStat());
vo.setStatusDesc(cash.getTransStatusDesc());
return vo;
}
return null;
}
/**
* 更新汇付会员信息
*
* @param dto
* @return
* @throws BaseAdaPayException
*/
public void updateAdapayMember(Map<String, Object> payload) throws BaseAdaPayException {
String merchantId = (String) payload.get("merchantId");
AdapayMemberAccount adapayMemberAccount = requireCurrentMemberAccount(merchantId);
if (isPersonalMember(adapayMemberAccount.getAdapayMemberId())) {
UpdatePersonalMemberDTO dto = JSON.parseObject(JSON.toJSONString(payload), UpdatePersonalMemberDTO.class);
updatePersonalMember(dto);
return;
}
UpdateCorpMemberDTO dto = JSON.parseObject(JSON.toJSONString(payload), UpdateCorpMemberDTO.class);
updateCorpMember(dto);
}
public void updateCorpMember(UpdateCorpMemberDTO dto) throws BaseAdaPayException {
SettleAccountDTO request = SettleAccountDTO.builder()
.merchantId(dto.getMerchantId())
.businessName(dto.getName())
.provCode(dto.getProvCode())
.areaCode(dto.getAreaCode())
.socialCreditCodeExpires(dto.getSocialCreditCodeExpires())
.businessScope(dto.getBusinessScope())
.legalPerson(dto.getLegalPerson())
.legalCertId(dto.getLegalCertId())
.legalCertIdExpires(dto.getLegalCertIdExpires())
.legalMp(dto.getLegalMp())
.address(dto.getAddress())
.zipCode(dto.getZipCode())
.telphone(dto.getTelphone())
.email(dto.getEmail())
.imgList(dto.getImgList())
.build();
updateAdapayMember(request);
}
public void updatePersonalMember(UpdatePersonalMemberDTO dto) throws BaseAdaPayException {
String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId());
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId);
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
AdapayMemberAccount adapayMemberAccount = requireCurrentMemberAccount(dto.getMerchantId());
Map<String, Object> memberParams = Maps.newHashMap();
memberParams.put("member_id", adapayMemberAccount.getAdapayMemberId());
memberParams.put("app_id", config.getAdapayAppId());
memberParams.put("location", dto.getLocation());
memberParams.put("email", dto.getEmail());
memberParams.put("gender", dto.getGender());
memberParams.put("nickname", dto.getNickname());
Map<String, Object> member = Member.update(memberParams, config.getWechatAppId());
log.info("更新个人账户param:{}, result:{}", JSON.toJSONString(memberParams), JSON.toJSONString(member));
if (member == null || AdapayStatusEnum.FAILED.getValue().equals((String) member.get("status"))) {
String errorMsg = member == null ? "更新汇付个人用户失败" : (String) member.get("error_msg");
throw new BusinessException("", errorMsg);
}
}
public Map<String, Object> updateAdapayMember(SettleAccountDTO dto) throws BaseAdaPayException {
String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId());
// 获取汇付支付配置
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId);
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(dto.getMerchantId());
if (adapayMemberAccount == null) {
log.error("通过merchantId:{}, 没有查询到结算账户配置", dto.getMerchantId());
return null;
}
Map<String, Object> memberParams = Maps.newHashMap();
memberParams.put("adapay_func_code", "corp_members.update");
memberParams.put("member_id", adapayMemberAccount.getAdapayMemberId());
memberParams.put("app_id", config.getAdapayAppId());
// memberParams.put("order_no", "jsdk_order_" + System.currentTimeMillis());
memberParams.put("order_no", IdUtils.get16UUID("jsdk_order_"));
memberParams.put("social_credit_code_expires", dto.getSocialCreditCodeExpires());
memberParams.put("business_scope", dto.getBusinessScope());
String name = dto.getBusinessName();
if (StringUtils.isBlank(name)) {
name = dto.getNickname();
}
memberParams.put("name", name);
memberParams.put("prov_code", dto.getProvCode());
memberParams.put("area_code", dto.getAreaCode());
memberParams.put("legal_person", dto.getLegalPerson());
memberParams.put("legal_cert_id", dto.getLegalCertId());
memberParams.put("legal_cert_id_expires", dto.getLegalCertIdExpires());
memberParams.put("legal_mp", dto.getLegalMp());
memberParams.put("address", dto.getAddress());
memberParams.put("zip_code", dto.getZipCode());
memberParams.put("telphone", dto.getTelphone());
memberParams.put("email", dto.getEmail());
File file = ZipUtil.createZipFileFromImages(dto.getImgList());
Map<String, Object> member = AdapayCommon.requestAdapayFile(memberParams, file, config.getWechatAppId());
log.info("更新企业账户param:{}, result:{}", JSON.toJSONString(memberParams), JSON.toJSONString(member));
if (AdapayStatusEnum.FAILED.getValue().equals((String) member.get("status"))) {
throw new BusinessException("", (String) member.get("error_msg"));
}
return null;
}
/**
* 创建交易确认请求/创建分账请求
* 这个方法只适用于给一个用户分账
*
* @param paymentId 支付对象id
* @param adapayMemberAccount 收到该账的汇付会员信息
* @param confirmAmt 确认的金额
* @param orderCode 订单编号
*/
public PaymentConfirmResponse createPaymentConfirmRequest(String paymentId, AdapayMemberAccount adapayMemberAccount, BigDecimal confirmAmt, String orderCode, String wechatAppId) {
DivMember divMember = new DivMember();
divMember.setMemberId(adapayMemberAccount.getAdapayMemberId());
divMember.setAmount(AdapayUtil.formatAmount(confirmAmt));
divMember.setFeeFlag(Constants.Y);
PaymentConfirmParam param = PaymentConfirmParam.builder()
.paymentId(paymentId)
.divMemberList(Lists.newArrayList(divMember))
.confirmAmt(confirmAmt)
.orderCode(orderCode)
.wechatAppId(wechatAppId)
.build();
return createPaymentConfirmRequest(param);
}
/**
* 创建交易确认请求/创建分账请求/分账主逻辑
* 这个方法支持多用户分账
*/
public PaymentConfirmResponse createPaymentConfirmRequest(PaymentConfirmParam param) {
List<DivMember> adapayMemberAccounts = param.getDivMemberList(); // 收到该账的汇付会员信息
// 排除adapayMemberAccounts中amount为0的元素
if (CollectionUtils.isNotEmpty(adapayMemberAccounts)) {
adapayMemberAccounts = adapayMemberAccounts.stream().filter(item -> new BigDecimal(item.getAmount()).compareTo(BigDecimal.ZERO) > 0).collect(Collectors.toList());
}
// 分账对象信息 一次最多7个
if (adapayMemberAccounts.size() > 7) {
throw new BusinessException("", "分账人数不能超过7人");
}
String paymentId = param.getPaymentId(); // 支付对象id
BigDecimal confirmAmt = param.getConfirmAmt(); // 确认的金额
String orderCode = param.getOrderCode(); // 订单编号
String wechatAppId = param.getWechatAppId(); // appId
// 调汇付的分账接口 确认交易
Map<String, Object> confirmParams = Maps.newHashMap();
// Adapay生成的支付对象id
confirmParams.put("payment_id", paymentId);
// 请求订单号只能为英文、数字或者下划线的一种或多种组合保证在app_id下唯一
confirmParams.put("order_no", IdUtils.get16UUID("PC"));
// 确认金额必须大于0保留两位小数点如0.10、100.05等。必须小于等于原支付金额-已确认金额-已撤销金额。
confirmParams.put("confirm_amt", AdapayUtil.formatAmount(confirmAmt));
// 参与分账的会员列表
List<String> adapayMemberIdList = adapayMemberAccounts.stream().map(DivMember::getMemberId).collect(Collectors.toList());
// TODO 附加说明, 记录每个账户分账金额
JSONObject jsonObject = new JSONObject();
jsonObject.put("orderCode", orderCode);
jsonObject.put("adapayMemberIds", StringUtils.join(adapayMemberIdList, ","));
confirmParams.put("description", jsonObject.toJSONString());
confirmParams.put("div_members", adapayMemberAccounts);
// 创建交易确认请求
Map<String, Object> paymentConfirm = null;
try {
paymentConfirm = PaymentConfirm.create(confirmParams, wechatAppId);
} catch (BaseAdaPayException e) {
log.error("创建交易确认请求error", e);
}
String jsonString = JSON.toJSONString(paymentConfirm);
log.info("调分账接口param:{}, result:{}", JSON.toJSONString(confirmParams), jsonString);
// 删除支付确认信息缓存
redisCache.deleteObject(CacheConstants.PAYMENT_CONFIRM_LIST + paymentId);
return JSONObject.parseObject(jsonString, PaymentConfirmResponse.class);
}
/**
* 创建余额支付请求
* 汇付余额转账
* @param outMemberId 出账用户的member_id 若为商户本身时请传入0
* @param inMemberId 入账用户的member_id 若为商户本身时请传入0
* @param transAmt 交易金额, 必须大于0保留两位小数点如0.10、100.05等
* @param title 标题
* @param desc 描述信息
*/
public BalancePaymentResponse createBalancePaymentRequest(String outMemberId, String inMemberId, String transAmt, String title, String desc, String wechatAppId) {
// 获取汇付支付配置
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId);
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
Map<String, Object> balanceParam = Maps.newHashMap();
balanceParam.put("app_id", config.getAdapayAppId());
balanceParam.put("adapay_func_code", "settle_accounts.balancePay");
balanceParam.put("order_no", IdUtils.fastSimpleUUID());
balanceParam.put("out_member_id", outMemberId);
balanceParam.put("in_member_id", inMemberId);
balanceParam.put("trans_amt", AdapayUtil.formatAmount(transAmt));
balanceParam.put("goods_title", title);
balanceParam.put("goods_desc", desc);
Map<String, Object> paymentResult = null;
try {
paymentResult = AdapayCommon.requestAdapay(balanceParam, config.getWechatAppId());
} catch (BaseAdaPayException e) {
log.error("创建余额支付请求error", e);
}
String jsonString = JSON.toJSONString(paymentResult);
log.info("创建余额支付param:{}, result:{}", JSON.toJSONString(balanceParam), jsonString);
return JSONObject.parseObject(jsonString, BalancePaymentResponse.class);
}
/**
* 创建支付确认撤销
*/
public void createConfirmReverse(String paymentConfirmId, String wechatAppId) throws BaseAdaPayException {
Map<String, Object> confirmReverseParams = Maps.newHashMap();
confirmReverseParams.put("adapay_func_code", "payments.confirm.reverse");
confirmReverseParams.put("payment_confirm_id", paymentConfirmId);
confirmReverseParams.put("reason", "支付确认撤销");
confirmReverseParams.put("order_no", IdUtils.fastSimpleUUID());
Map<String, Object> confirmReverseResult = AdapayCommon.requestAdapay(confirmReverseParams, wechatAppId);
log.info("创建支付确认撤销param:{}, result:{}", JSON.toJSONString(confirmReverseParams), JSON.toJSONString(confirmReverseResult));
}
/**
* 实时分账的调退款接口
* 创建退款请求
*/
public RefundResponse createRefundRequest(String paymentId, BigDecimal refundAmt, String wechatAppId, String memberId, String scenarioType, String orderCode) {
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId);
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
// 实时分账的调退款接口
Map<String, Object> refundParams = Maps.newHashMap();
refundParams.put("refund_amt", AdapayUtil.formatAmount(refundAmt));
refundParams.put("refund_order_no", IdUtils.fastSimpleUUID());
// expand 为扩展域
Map<String, String> expendMap = Maps.newHashMap();
expendMap.put("memberId", memberId);
expendMap.put("scenarioType", scenarioType);
if (StringUtils.isNotBlank(orderCode)) {
expendMap.put("orderCode", orderCode);
}
refundParams.put("expand", expendMap);
refundParams.put("reason", expendMap);
refundParams.put("notify_url", ADAPAY_CALLBACK_URL);
Map<String, Object> resultResponse = null;
try {
resultResponse = Refund.create(paymentId, refundParams, config.getWechatAppId());
} catch (BaseAdaPayException e) {
log.error("汇付支付创建退款对象error", e);
}
String jsonString = JSON.toJSONString(resultResponse);
log.info("汇付支付创建退款对象param:{}, result:{}", JSON.toJSONString(refundParams), JSON.toJSONString(jsonString));
return JSONObject.parseObject(jsonString, RefundResponse.class);
}
/**
* 创建交易撤销请求
* 延迟分账未确认, 调交易撤销接口退款
* delay模式的商户使用
*/
public PaymentReverseResponse createPaymentReverseRequest(PaymentReverseOperation paymentReverseOperation) {
String wechatAppId = paymentReverseOperation.getMerchantKey();
String paymentId = paymentReverseOperation.getPaymentId();
BigDecimal reverseAmt = paymentReverseOperation.getReverseAmt();
String memberId = paymentReverseOperation.getMemberId();
String scenarioType = paymentReverseOperation.getScenarioType();
String orderCode = paymentReverseOperation.getOrderCode();
return createPaymentReverseRequest(paymentId, reverseAmt, wechatAppId, memberId, scenarioType, orderCode);
}
/**
* 创建交易撤销请求
* 延迟分账未确认, 调交易撤销接口退款
* delay模式的商户使用
* @param wechatAppId 微信小程序appId
*/
public PaymentReverseResponse createPaymentReverseRequest(String paymentId, BigDecimal reverseAmt,
String wechatAppId, String memberId, String scenarioType,
String orderCode) {
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId);
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
// 延迟分账未确认调撤销调撤销接口退款
Map<String, Object> reverseParams = Maps.newHashMap();
reverseParams.put("app_id", config.getAdapayAppId());
reverseParams.put("payment_id", paymentId);
reverseParams.put("reverse_amt", AdapayUtil.formatAmount(reverseAmt));
reverseParams.put("order_no", IdUtils.fastSimpleUUID());
reverseParams.put("notify_url", ADAPAY_CALLBACK_URL);
// expand 为扩展域
Map<String, String> expendMap = Maps.newHashMap();
expendMap.put("memberId", memberId);
expendMap.put("scenarioType", scenarioType);
if (StringUtils.isNotBlank(orderCode)) {
expendMap.put("orderCode", orderCode);
}
reverseParams.put("expand", expendMap);
reverseParams.put("reason", expendMap);
Map<String, Object> paymentReverse = null;
try {
paymentReverse = PaymentReverse.create(reverseParams, config.getWechatAppId());
} catch (BaseAdaPayException e) {
log.error("汇付支付创建交易撤销对象error", e);
}
String jsonString = JSON.toJSONString(paymentReverse);
log.info("汇付支付创建交易撤销对象param:{}, result:{}", JSON.toJSONString(reverseParams), jsonString);
return JSONObject.parseObject(jsonString, PaymentReverseResponse.class);
}
/**
* 查询支付撤销对象
*
* @return
*/
public List<PaymentReverseResponse> queryPaymentReverse(String paymentId, String wechatAppId) throws BaseAdaPayException {
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId);
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
Map<String, Object> reverse = Maps.newHashMap();
reverse.put("payment_id", paymentId);
reverse.put("app_id", config.getAdapayAppId());
Map<String, Object> response = PaymentReverse.queryList(reverse, config.getWechatAppId());
JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(response));
List<PaymentReverseResponse> payment_reverses = jsonObject.getList("payment_reverses", PaymentReverseResponse.class);
return payment_reverses;
}
/**
* 查询支付退款对象
*/
public List<RefundInfo> queryPaymentRefund(String paymentId, String wechatAppId) throws BaseAdaPayException {
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId);
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
Map<String, Object> refundParams = Maps.newHashMap();
refundParams.put("payment_id", paymentId);
refundParams.put("app_id", config.getAdapayAppId());
Map<String, Object> response = Refund.query(refundParams, config.getWechatAppId());
PaymentRefundResponse paymentRefundResponse = JSON.parseObject(JSON.toJSONString(response), PaymentRefundResponse.class);
List<RefundInfo> refunds = paymentRefundResponse.getRefunds();
return refunds;
}
/**
* 查询支付确认对象列表
* paymentId 必传
* wechatAppId 必传
*/
public QueryPaymentConfirmDetailResponse queryPaymentConfirmList(QueryPaymentConfirmDTO dto) {
QueryPaymentConfirmDetailResponse response = null;
// 查缓存
String redisKey = CacheConstants.PAYMENT_CONFIRM_LIST + dto.getPaymentId();
// String redisResult = redisCache.getCacheObject(redisKey);
// if (StringUtils.isNotBlank(redisResult)) {
// response = JSONObject.parseObject(redisResult, QueryPaymentConfirmDetailResponse.class);
// return response;
// }
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(dto.getWechatAppId());
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
Map<String, Object> param = Maps.newHashMap();
param.put("payment_id", dto.getPaymentId());
param.put("app_id", config.getAdapayAppId());
try {
Map<String, Object> map = PaymentConfirm.queryList(param, config.getWechatAppId());
response = JSON.parseObject(JSON.toJSONString(map), QueryPaymentConfirmDetailResponse.class);
// log.info("queryPaymentConfirmDetailResponse:{}", JSON.toJSONString(queryPaymentConfirmDetailResponse));
redisCache.setCacheObject(redisKey, JSON.toJSONString(response), CacheConstants.cache_expire_time_10m);
} catch (BaseAdaPayException e) {
log.error("查询支付确认对象列表error", e);
}
return response;
}
/**
* 查询支付确认对象详情
*/
public PaymentConfirmInfo queryPaymentConfirmDetail(QueryPaymentConfirmDTO dto) {
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(dto.getWechatAppId());
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
Map<String, Object> confirmParams = Maps.newHashMap();
confirmParams.put("payment_confirm_id", dto.getPaymentConfirmId());
PaymentConfirmInfo result = null;
try {
Map<String, Object> paymentConfirm = PaymentConfirm.query(confirmParams, config.getWechatAppId());
log.info("查询支付确认对象详情:{}", JSON.toJSONString(paymentConfirm));
result = JSON.parseObject(JSON.toJSONString(paymentConfirm), PaymentConfirmInfo.class);
} catch (BaseAdaPayException e) {
throw new RuntimeException(e);
}
return result;
}
/**
* 查询账务流水
*/
public void queryAcctFlowList(QueryAcctFlowDTO dto) throws BaseAdaPayException {
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(dto.getWechatAppId());
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
Map<String, Object> acctFlowParams = Maps.newHashMap();
acctFlowParams.put("adapay_func_code", "acct.flow.list");
acctFlowParams.put("app_id", config.getAdapayAppId());
acctFlowParams.put("member_id", dto.getAdapayMemberId());
acctFlowParams.put("acct_type", dto.getAcctType());
acctFlowParams.put("page_index", dto.getPageNo());
acctFlowParams.put("page_size", dto.getPageSize());
acctFlowParams.put("begin_date", dto.getBeginDate());
acctFlowParams.put("end_date", dto.getEndDate());
Map<String, Object> acctFlowList = AdapayCommon.queryAdapay(acctFlowParams, config.getWechatAppId());
log.info("查询账务流水param:{}, result:{}", JSON.toJSONString(dto), JSON.toJSONString(acctFlowList));
}
/**
* 查询支付列表
*/
public List<AdaPayment> queryPaymentList(String startTime, String endTime) throws BaseAdaPayException {
List<AdaPayment> resultList = Lists.newArrayList();
String wechatAppId = "wxbb3e0d474569481d";
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId);
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
String appId = config.getAdapayAppId();
long begin = DateUtils.dateStrToTimestamp(startTime); // 13位时间戳
long end = DateUtils.dateStrToTimestamp(endTime); // 13位时间戳
int pageNum = 0; // 页面容量,取值范围 1~20默认值为 10
int pageSize = 20; // 页面容量,取值范围 1~20默认值为 10
boolean hasMore;
do {
pageNum += 1;
// 根据时间段查询支付对象列表
Map<String, Object> queryListParam = Maps.newHashMap();
queryListParam.put("app_id", appId);
queryListParam.put("page_index", pageNum);
queryListParam.put("page_size", pageSize);
queryListParam.put("created_gte", begin);
queryListParam.put("created_lte", end);
System.out.println("查询支付对象列表请求参数:" + JSON.toJSONString(queryListParam));
Map<String, Object> paymentListResult = Payment.queryList(queryListParam, wechatAppId);
if (paymentListResult == null) {
break;
}
String jsonString = JSON.toJSONString(paymentListResult);
System.out.println("查询支付对象列表result" + jsonString);
JSONObject jsonObject = JSON.parseObject(jsonString);
List<AdaPayment> list = jsonObject.getList("payments", AdaPayment.class, JSONReader.Feature.FieldBased);
resultList.addAll(list);
hasMore = jsonObject.getBoolean("has_more");
} while (hasMore);
return resultList;
}
/**
* 根据请求号,查询支付信息列表
*/
public List<PaymentInfo> queryPaymentInfosByOrderNo(String orderNo, String wechatAppId) throws BaseAdaPayException {
List<PaymentInfo> resultList = Lists.newArrayList();
List<AdaPayment> adaPayments = queryPaymentsByOrderNo(orderNo, wechatAppId);
if (CollectionUtils.isNotEmpty(adaPayments)) {
for (AdaPayment adaPayment : adaPayments) {
PaymentInfo paymentInfo = PaymentInfo.builder()
.paymentId(adaPayment.getId())
.amount(adaPayment.getPay_amt())
.build();
resultList.add(paymentInfo);
}
}
log.info("根据请求号:{}, wechatAppId:{}, 查询支付信息列表:{}", orderNo, wechatAppId, JSON.toJSONString(resultList));
return resultList;
}
/**
* 查询支付列表
*/
public List<AdaPayment> queryPaymentsByOrderNo(String orderNo, String wechatAppId) throws BaseAdaPayException {
List<AdaPayment> resultList = Lists.newArrayList();
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(wechatAppId);
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
String appId = config.getAdapayAppId();
int pageNum = 0; // 页面容量,取值范围 1~20默认值为 10
int pageSize = 20; // 页面容量,取值范围 1~20默认值为 10
boolean hasMore;
do {
pageNum += 1;
// 根据时间段查询支付对象列表
Map<String, Object> queryListParam = Maps.newHashMap();
queryListParam.put("app_id", appId);
queryListParam.put("page_index", pageNum);
queryListParam.put("page_size", pageSize);
queryListParam.put("order_no", orderNo);
// System.out.println("查询支付对象列表请求参数:" + JSON.toJSONString(queryListParam));
Map<String, Object> paymentListResult = Payment.queryList(queryListParam, wechatAppId);
if (paymentListResult == null) {
break;
}
String jsonString = JSON.toJSONString(paymentListResult);
// System.out.println("查询支付对象列表result" + jsonString);
JSONObject jsonObject = JSON.parseObject(jsonString);
List<AdaPayment> list = jsonObject.getList("payments", AdaPayment.class, JSONReader.Feature.FieldBased);
resultList.addAll(list);
hasMore = jsonObject.getBoolean("has_more");
} while (hasMore);
return resultList;
}
/**
* 查询支付确认撤销对象
*/
public ConfirmReverseResponse queryConfirmReverse(QueryConfirmReverseDTO dto) throws BaseAdaPayException {
AbstractAdapayConfig config = AdapayConfigFactory.getConfig(dto.getWechatAppId());
if (config == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_CONFIG_IS_NULL_ERROR);
}
Map<String, Object> confirmReverseQueryParams = new HashMap<>();
confirmReverseQueryParams.put("adapay_func_code", "payments.confirm.reverse.details");
confirmReverseQueryParams.put("payment_confirm_id", dto.getPaymentConfirmId());
Map<String, Object> confirmReverseQueryResult = AdapayCommon.queryAdapay(confirmReverseQueryParams, config.getWechatAppId());
ConfirmReverseResponse confirmReverseResponse = JSON.parseObject(JSON.toJSONString(confirmReverseQueryResult), ConfirmReverseResponse.class);
log.debug("confirmReverseQueryResult:{}", JSON.toJSONString(confirmReverseResponse));
return confirmReverseResponse;
}
/**
* 换绑银行卡
* 用户需要换绑银行卡 1-删除结算账户信息2-使用新账户信息创建结算账户】
*/
public void changeBankCard(ChangeBankCardDTO dto) throws BaseAdaPayException {
String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId());
// 获取汇付支会员信息
AdapayMemberAccount account = adapayMemberAccountService.selectByMerchantId(dto.getMerchantId());
if (account == null) {
return;
}
// 1-删除结算账户信息
String adapayMemberId = account.getAdapayMemberId();
String settleAccountId = null;
AdapayCorpMemberVO adapayCorpMemberVO = this.queryCorpAdapayMemberInfo(adapayMemberId, wechatAppId);
if (adapayCorpMemberVO != null) {
settleAccountId = adapayCorpMemberVO.getSettleAccountId();
}
this.createDeleteSettleAccountRequest(adapayMemberId, settleAccountId, wechatAppId);
// 2-使用新账户信息创建结算账户
SettleAccountDTO settleAccountDTO = new SettleAccountDTO();
settleAccountDTO.setCardId(dto.getCardId());
settleAccountDTO.setCardName(dto.getCardName());
settleAccountDTO.setTelNo(dto.getTelNo());
settleAccountDTO.setBankCode(dto.getBankCode());
settleAccountDTO.setBankAcctType(dto.getBankAcctType());
settleAccountDTO.setProvCode(dto.getProvCode());
settleAccountDTO.setAreaCode(dto.getAreaCode());
Map<String, Object> settleAccount = this.createSettleAccountRequest(settleAccountDTO, adapayMemberId, wechatAppId);
if (settleAccount != null && !StringUtils.equals((String) settleAccount.get("status"), "failed")) {
AdapayMemberAccount updateRecord = new AdapayMemberAccount();
updateRecord.setAdapayMemberId(adapayMemberId);
updateRecord.setSettleAccountId((String) settleAccount.get("id"));
adapayMemberAccountService.updateAdapayMemberAccountByMemberId(updateRecord);
}
}
/**
* 查询支付撤销状态
* @param confirm
* @return
* @throws BaseAdaPayException
*/
public boolean queryConfirmReverseStatus(PaymentConfirmInfo confirm) throws BaseAdaPayException {
boolean result = false;
QueryConfirmReverseDTO dto = QueryConfirmReverseDTO.builder()
.paymentConfirmId(confirm.getId())
.wechatAppId(wechatAppId1)
.build();
ConfirmReverseResponse confirmReverseResponse = this.queryConfirmReverse(dto);
if (confirmReverseResponse.isSuccess()) {
result = true;
}
return result;
}
/**
* 根据paymentId查询总分账金额
* 万车充专用
* @param paymentId
* @return
* @throws BaseAdaPayException
*/
public BigDecimal getTotalSplitAmountByPaymentId(String paymentId) throws BaseAdaPayException {
BigDecimal totalSplitAmount = BigDecimal.ZERO;
// 查询支付确认id
QueryPaymentConfirmDTO dto = new QueryPaymentConfirmDTO();
dto.setPaymentId(paymentId);
dto.setWechatAppId(wechatAppId1);
// 查询分账信息
QueryPaymentConfirmDetailResponse response = this.queryPaymentConfirmList(dto);
if (response == null) {
return totalSplitAmount;
}
List<PaymentConfirmInfo> confirms = response.getPaymentConfirms();
if (CollectionUtils.isEmpty(confirms)) {
return totalSplitAmount;
}
for (PaymentConfirmInfo confirm : confirms) {
if (queryConfirmReverseStatus(confirm)) {
log.info("支付确认id:{}撤销了。。。", confirm.getId());
continue;
}
BigDecimal confirmedAmt = new BigDecimal(confirm.getConfirmedAmt()); // 已确认金额
// 汇总已确认金额
totalSplitAmount = totalSplitAmount.add(confirmedAmt);
}
return totalSplitAmount;
}
/**
* 创建结算账户
* @param dto
* @throws BaseAdaPayException
*/
public void createBankAccount(SettleAccountDTO dto) throws BaseAdaPayException {
CreateSettleAccountDTO request = CreateSettleAccountDTO.builder()
.merchantId(dto.getMerchantId())
.bankAcctType(dto.getBankAcctType())
.cardId(dto.getCardId())
.cardNo(dto.getCardNo())
.cardName(dto.getCardName())
.certId(dto.getCertId())
.certType(dto.getCertType())
.telNo(dto.getTelNo())
.bankCode(dto.getBankCode())
.bankName(dto.getBankName())
.provCode(dto.getProvCode())
.areaCode(dto.getAreaCode())
.build();
createSettleAccount(request);
}
/**
* 删除结算账户(先删除汇付的结算账户,再逻辑删除数据库)
* @param dto
* @throws BaseAdaPayException
*/
public void deleteSettleAccount(AdapayMemberInfoDTO dto) throws BaseAdaPayException {
AdapayMemberAccount adapayMemberAccount = requireCurrentMemberAccount(dto.getMerchantId());
String wechatAppId = pileMerchantInfoService.queryAppIdByMerchantId(dto.getMerchantId());
String adapayMemberId = StringUtils.isNotBlank(dto.getAdapayMemberId()) ? dto.getAdapayMemberId() : adapayMemberAccount.getAdapayMemberId();
String settleAccountId = StringUtils.isNotBlank(dto.getSettleAccountId()) ? dto.getSettleAccountId() : adapayMemberAccount.getSettleAccountId();
if (StringUtils.isBlank(settleAccountId) && isCorpMember(adapayMemberId)) {
AdapayCorpMemberVO corpMemberVO = queryCorpAdapayMemberInfo(adapayMemberId, wechatAppId);
if (corpMemberVO != null) {
settleAccountId = corpMemberVO.getSettleAccountId();
}
}
if (StringUtils.isBlank(settleAccountId)) {
throw new BusinessException("", "未查询到结算账户");
}
this.createDeleteSettleAccountRequest(adapayMemberId, settleAccountId, wechatAppId);
adapayMemberAccountService.clearSettleAccountByMerchantId(dto.getMerchantId());
}
public void deleteAdapayMember(DeleteAdapayMemberDTO dto) throws BaseAdaPayException {
AdapayMemberAccount adapayMemberAccount = requireCurrentMemberAccount(dto.getMerchantId());
if (StringUtils.isNotBlank(dto.getAdapayMemberId())
&& !StringUtils.equals(dto.getAdapayMemberId(), adapayMemberAccount.getAdapayMemberId())) {
throw new BusinessException("", "汇付用户信息不匹配");
}
if (CollectionUtils.isNotEmpty(selectSettleAccount(dto.getMerchantId()))) {
throw new BusinessException("", "请先删除结算账户");
}
adapayMemberAccountService.deleteAccountByMerchantId(dto.getMerchantId());
}
private AdapayMemberAccount requireCurrentMemberAccount(String merchantId) {
AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(merchantId);
if (adapayMemberAccount == null) {
throw new BusinessException(ReturnCodeEnum.CODE_ADAPAY_MEMBER_IS_NULL_ERROR);
}
return adapayMemberAccount;
}
private boolean isPersonalMember(String adapayMemberId) {
return StringUtils.startsWith(adapayMemberId, Constants.ADAPAY_MEMBER_PREFIX);
}
private boolean isCorpMember(String adapayMemberId) {
return StringUtils.startsWith(adapayMemberId, Constants.ADAPAY_CORP_MEMBER_PREFIX);
}
private SettleAccountDTO buildSettleAccountDTO(CreateSettleAccountDTO dto) {
SettleAccountDTO request = SettleAccountDTO.builder()
.merchantId(dto.getMerchantId())
.bankAcctType(dto.getBankAcctType())
.cardId(dto.getCardId())
.cardNo(dto.getCardNo())
.cardName(dto.getCardName())
.certId(dto.getCertId())
.certType(dto.getCertType())
.telNo(dto.getTelNo())
.bankCode(dto.getBankCode())
.bankName(dto.getBankName())
.provCode(dto.getProvCode())
.areaCode(dto.getAreaCode())
.build();
String cardId = request.getCardId();
String cardNo = request.getCardNo();
if (StringUtils.isBlank(cardId) && StringUtils.isNotBlank(cardNo)) {
request.setCardId(cardNo);
}
if (StringUtils.isBlank(cardNo) && StringUtils.isNotBlank(cardId)) {
request.setCardNo(cardId);
}
return request;
}
/**
* 根据paymentIdList查询分账信息
* @param paymentIdList
* @return 未分帐paymentIdList
*/
public List<String> getSplitInfoByPaymentIdList(List<String> paymentIdList) throws BaseAdaPayException {
if (CollectionUtils.isEmpty(paymentIdList)) {
return new ArrayList<>();
}
List<String> unSplitList = Lists.newArrayList(); // 未分帐
List<String> splitList = Lists.newArrayList(); // 已分帐
BigDecimal total = BigDecimal.ZERO; // 总分账金额
BigDecimal totalWithdrawalAmt = BigDecimal.ZERO; // 实际到账金额汇总
BigDecimal totalFeeAmt = BigDecimal.ZERO; // 手续费金额汇总
List<String> selfList = Lists.newArrayList();
Map<String, BigDecimal> map = Maps.newHashMap();
for (String paymentId : paymentIdList) {
if (StringUtils.isBlank(paymentId)) {
continue;
}
// 查询支付确认id
QueryPaymentConfirmDTO dto = new QueryPaymentConfirmDTO();
dto.setPaymentId(paymentId);
dto.setWechatAppId(wechatAppId1);
// 查询分账信息
QueryPaymentConfirmDetailResponse response = this.queryPaymentConfirmList(dto);
if (response != null) {
List<PaymentConfirmInfo> confirms = response.getPaymentConfirms();
if (CollectionUtils.isEmpty(confirms)) {
unSplitList.add(paymentId);
} else {
splitList.add(paymentId);
for (PaymentConfirmInfo confirm : confirms) {
if (this.queryConfirmReverseStatus(confirm)) {
log.info("支付确认id:" + confirm.getId() + "撤销了。。。");
continue;
}
JSONObject jsonObject = JSON.parseObject(confirm.getDescription());
String adapayMemberId = jsonObject.getString("adapayMemberId");
if (StringUtils.isBlank(adapayMemberId)) {
adapayMemberId = jsonObject.getString("adapayMemberIds");
}
BigDecimal confirmAmt = new BigDecimal(confirm.getConfirmAmt()); // 本次确认金额
BigDecimal confirmedAmt = new BigDecimal(confirm.getConfirmedAmt()); // 已确认金额
BigDecimal feeAmt = new BigDecimal(confirm.getFeeAmt()); // 手续费
// 汇总已确认金额
total = total.add(confirmedAmt);
// 汇总手续费金额
totalFeeAmt = totalFeeAmt.add(feeAmt);
// 汇总可提现金额
totalWithdrawalAmt = totalWithdrawalAmt.add(confirmAmt).subtract(feeAmt);
// confirm
List<DivMember> divMembers = confirm.getDivMembers();
// System.out.println("confirm:" + JSON.toJSONString(divMembers));
for (DivMember divMember : divMembers) {
// 放map
map.merge(divMember.getMemberId(), new BigDecimal(divMember.getAmount()), BigDecimal::add);
}
if (StringUtils.equals(adapayMemberId, "0")
|| StringUtils.equals(adapayMemberId, "AM29102732")) {
// 0为默认平台id, AM29102732为罗总账户
selfList.add(paymentId);
}
}
}
} else {
unSplitList.add(paymentId);
}
}
log.info("\n入参paymentId数量:{}, 已分帐数量:{}, 未分帐数量:{}, 未分帐id:{} " +
"\n已分帐:{}, 总分账:{}, 数量:{}" +
"\n金额明细:[总到账金额:{}, 总手续费:{}] " +
"\n自己:{}, 数量:{}",
paymentIdList.size(), splitList.size(), unSplitList.size(), unSplitList,
JSON.toJSONString(map), total, splitList.size(),
totalWithdrawalAmt, totalFeeAmt,
selfList, selfList.size());
return unSplitList;
}
/**
* 根据paymentIdList查询分账信息
*/
// public Map<String, List<String>> getSplitInfoMapByPaymentIdList(List<String> paymentIdList) throws BaseAdaPayException {
// Map<String, List<String>> resultMap = Maps.newHashMap();
// if (CollectionUtils.isEmpty(paymentIdList)) {
// return resultMap;
// }
// List<String> unSplitList = Lists.newArrayList(); // 未分帐
// List<String> splitList = Lists.newArrayList(); // 已分帐
// List<String> selfList = Lists.newArrayList(); // 自己分帐
//
// BigDecimal total = BigDecimal.ZERO; // 总分账金额
// BigDecimal totalWithdrawalAmt = BigDecimal.ZERO; // 实际到账金额汇总
// BigDecimal totalFeeAmt = BigDecimal.ZERO; // 手续费金额汇总
//
// Map<String, BigDecimal> amountDetailMap = Maps.newHashMap();
// for (String paymentId : paymentIdList) {
// if (StringUtils.isBlank(paymentId)) {
// continue;
// }
//
// // 根据paymentId查询支付确认情况
// QueryPaymentConfirmDTO dto = new QueryPaymentConfirmDTO();
// dto.setPaymentId(paymentId);
// dto.setWechatAppId(wechatAppId1);
// QueryPaymentConfirmDetailResponse response = this.queryPaymentConfirmList(dto);
//
// if (response == null) {
// // 未查询到分账信息add to unSplitList
// unSplitList.add(paymentId);
// continue;
// }
//
// List<PaymentConfirmInfo> confirms = response.getPaymentConfirms();
// if (CollectionUtils.isEmpty(confirms)) {
// // confirms为空add to unSplitList
// unSplitList.add(paymentId);
// continue;
// }
//
// // 添加到已分帐list
// splitList.add(paymentId);
// for (PaymentConfirmInfo confirm : confirms) {
// if (this.queryConfirmReverseStatus(confirm)) {
// log.info("支付确认id:" + confirm.getId() + "撤销了。。。");
// continue;
// }
// JSONObject jsonObject = JSON.parseObject(confirm.getDescription());
// String adapayMemberId = jsonObject.getString("adapayMemberId");
// if (StringUtils.isBlank(adapayMemberId)) {
// adapayMemberId = jsonObject.getString("adapayMemberIds");
// }
//
// BigDecimal confirmAmt = new BigDecimal(confirm.getConfirmAmt()); // 本次确认金额
// BigDecimal confirmedAmt = new BigDecimal(confirm.getConfirmedAmt()); // 已确认金额
// BigDecimal feeAmt = new BigDecimal(confirm.getFeeAmt()); // 手续费
//
// // 汇总已确认金额
// total = total.add(confirmedAmt);
//
// // 汇总手续费金额
// totalFeeAmt = totalFeeAmt.add(feeAmt);
//
// // 汇总可提现金额
// totalWithdrawalAmt = totalWithdrawalAmt.add(confirmAmt).subtract(feeAmt);
//
// // confirm
// List<DivMember> divMembers = confirm.getDivMembers();
// // System.out.println("confirm:" + JSON.toJSONString(divMembers));
// for (DivMember divMember : divMembers) {
// // 放map
// amountDetailMap.merge(divMember.getMemberId(), new BigDecimal(divMember.getAmount()), BigDecimal::add);
// }
//
// if (StringUtils.equals(adapayMemberId, "0")
// || StringUtils.equals(adapayMemberId, "AM29102732")) {
// // 0为默认平台id, AM29102732为罗总账户
// selfList.add(paymentId);
// }
// }
// }
// log.info("\n入参paymentId数量:{}, 已分帐数量:{}, 未分帐数量:{}, 未分帐id:{} " +
// "\n已分帐:{}, 总分账:{}, 数量:{}" +
// "\n金额明细:[总到账金额:{}, 总手续费:{}] " +
// "\n自己:{}, 数量:{}",
// paymentIdList.size(), splitList.size(), unSplitList.size(), unSplitList,
// JSON.toJSONString(amountDetailMap), total, splitList.size(),
// totalWithdrawalAmt, totalFeeAmt,
// selfList, selfList.size());
//
// resultMap.put("unSplitList", unSplitList);
// resultMap.put("splitList", splitList);
// return resultMap;
// }
public Map<String, List<String>> getSplitInfoMapByPaymentIdList(List<String> paymentIdList) throws BaseAdaPayException {
Map<String, List<String>> resultMap = Maps.newHashMap();
if (CollectionUtils.isEmpty(paymentIdList)) {
return resultMap;
}
List<String> unSplitList = Lists.newArrayList(); // 未分帐
List<String> splitList = Lists.newArrayList(); // 已分帐
List<String> selfList = Lists.newArrayList(); // 自己分帐
// 使用原子引用包装可变对象
AtomicReference<BigDecimal> total = new AtomicReference<>(BigDecimal.ZERO);
AtomicReference<BigDecimal> totalWithdrawalAmt = new AtomicReference<>(BigDecimal.ZERO);
AtomicReference<BigDecimal> totalFeeAmt = new AtomicReference<>(BigDecimal.ZERO);
Map<String, BigDecimal> amountDetailMap = Maps.newHashMap();
paymentIdList.parallelStream()
.filter(StringUtils::isNotBlank)
.forEach(paymentId -> {
// 根据paymentId查询支付确认情况
QueryPaymentConfirmDTO dto = new QueryPaymentConfirmDTO();
dto.setPaymentId(paymentId);
dto.setWechatAppId(wechatAppId1);
QueryPaymentConfirmDetailResponse response = this.queryPaymentConfirmList(dto);
if (response == null) {
// 未查询到分账信息add to unSplitList
synchronized (unSplitList) {
unSplitList.add(paymentId);
}
return;
}
List<PaymentConfirmInfo> confirms = response.getPaymentConfirms();
if (CollectionUtils.isEmpty(confirms)) {
// confirms为空add to unSplitList
synchronized (unSplitList) {
unSplitList.add(paymentId);
}
return;
}
for (PaymentConfirmInfo confirm : confirms) {
try {
if (queryConfirmReverseStatus(confirm)) {
log.info("支付确认id:" + confirm.getId() + "撤销了。。。");
// confirms为空add to unSplitList
synchronized (unSplitList) {
unSplitList.add(paymentId);
}
continue;
}
} catch (BaseAdaPayException e) {
throw new RuntimeException(e);
}
// 添加到已分帐list
synchronized (splitList) {
splitList.add(paymentId);
}
JSONObject jsonObject = JSON.parseObject(confirm.getDescription());
String adapayMemberId = jsonObject.getString("adapayMemberId");
if (StringUtils.isBlank(adapayMemberId)) {
adapayMemberId = jsonObject.getString("adapayMemberIds");
}
BigDecimal confirmAmt = new BigDecimal(confirm.getConfirmAmt()); // 本次确认金额
BigDecimal confirmedAmt = new BigDecimal(confirm.getConfirmedAmt()); // 已确认金额
BigDecimal feeAmt = new BigDecimal(confirm.getFeeAmt()); // 手续费
// 汇总已确认金额
total.getAndUpdate(current -> current.add(confirmedAmt));
// 汇总手续费金额
totalFeeAmt.getAndUpdate(current -> current.add(feeAmt));
// 汇总可提现金额
totalWithdrawalAmt.getAndUpdate(current -> current.add(confirmAmt).subtract(feeAmt));
// confirm
List<DivMember> divMembers = confirm.getDivMembers();
// System.out.println("confirm:" + JSON.toJSONString(divMembers));
for (DivMember divMember : divMembers) {
synchronized (amountDetailMap) {
// 放map
amountDetailMap.merge(divMember.getMemberId(), new BigDecimal(divMember.getAmount()), BigDecimal::add);
}
}
if (StringUtils.equals(adapayMemberId, "0")
|| StringUtils.equals(adapayMemberId, "AM29102732")) {
// 0为默认平台id, AM29102732为罗总账户
synchronized (selfList) {
selfList.add(paymentId);
}
}
}
}
);
log.info("\n入参paymentId数量:{}, 已分帐数量:{}, 未分帐数量:{}, 未分帐id:{} " +
"\n已分帐:{}, 总分账:{}, 数量:{}" +
"\n金额明细:[总到账金额:{}, 总手续费:{}] " +
"\n自己:{}, 数量:{}",
paymentIdList.size(), splitList.size(), unSplitList.size(), unSplitList,
JSON.toJSONString(amountDetailMap), total, splitList.size(),
totalWithdrawalAmt, totalFeeAmt,
selfList, selfList.size());
resultMap.put("unSplitList", unSplitList);
resultMap.put("splitList", splitList);
return resultMap;
}
}