package com.jsowell.adapay.service; import com.alibaba.fastjson2.JSON; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.huifu.adapay.core.exception.BaseAdaPayException; import com.huifu.adapay.model.CorpMember; import com.huifu.adapay.model.Drawcash; import com.huifu.adapay.model.Member; import com.huifu.adapay.model.SettleAccount; import com.jsowell.adapay.dto.CreateSettleAccountDTO; import com.jsowell.adapay.dto.UpdateAccountConfigDTO; import com.jsowell.adapay.dto.WithdrawDTO; import com.jsowell.adapay.response.QueryMemberResponse; import com.jsowell.adapay.vo.AdapayAccountBalanceVO; import com.jsowell.adapay.vo.AdapayMemberInfoVO; import com.jsowell.adapay.vo.AdapaySettleAccountVO; import com.jsowell.common.constant.Constants; import com.jsowell.common.exception.BusinessException; import com.jsowell.common.util.AdapayUtil; import com.jsowell.common.util.StringUtils; import com.jsowell.common.util.id.IdUtils; import com.jsowell.pile.domain.AdapayMemberAccount; import com.jsowell.pile.service.IAdapayMemberAccountService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import java.io.File; import java.io.IOException; import java.math.BigDecimal; import java.util.Map; @Slf4j @Service public class AdapayMemberService { @Value("${adapay.appId}") private String ADAPAY_APP_ID; @Autowired private IAdapayMemberAccountService adapayMemberAccountService; public void createSettleAccount(CreateSettleAccountDTO dto) throws Exception { String bankAcctType = dto.getBankAcctType(); if (StringUtils.equals(bankAcctType, Constants.ONE)) { createMember(dto); } else if (StringUtils.equals(bankAcctType, Constants.TWO)) { createCorpMember(dto); } } /** * 创建汇付会员 * * @param dto * @throws Exception */ @Transactional(readOnly = false, propagation = Propagation.REQUIRED) public void createMember(CreateSettleAccountDTO dto) throws Exception { AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(dto.getMerchantId()); if (adapayMemberAccount != null) { log.error("通过merchantId:{}, 没有查询到结算账户配置", dto.getMerchantId()); return; } log.info("=======execute CreateMember begin======="); Map memberParams = Maps.newHashMap(); String adapayMemberId = "AM" + IdUtils.getMemberId(); memberParams.put("member_id", adapayMemberId); memberParams.put("app_id", ADAPAY_APP_ID); 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 member = Member.create(memberParams); 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); } // 创建结算账户 Map accountInfo = Maps.newHashMap(); // 银行卡号 accountInfo.put("card_id", dto.getCardId()); // 银行卡对应的户名 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 settleCountParams = Maps.newHashMap(); settleCountParams.put("member_id", adapayMemberId); settleCountParams.put("app_id", ADAPAY_APP_ID); // channel String Y 目前仅支持:bank_account(银行卡) settleCountParams.put("channel", "bank_account"); settleCountParams.put("account_info", accountInfo); log.info("创建汇付结算账户param:{}", settleCountParams); Map settleCount = SettleAccount.create(settleCountParams); log.info("创建汇付结算账户result:{}", settleCount); 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 = new AdapayMemberAccount(); adapayMemberAccount.setMerchantId(dto.getMerchantId()); adapayMemberAccount.setAdapayMemberId(adapayMemberId); adapayMemberAccount.setSettleAccountId(settleAccountId); adapayMemberAccountService.insertAdapayMemberAccount(adapayMemberAccount); } /** * 查询汇付会员信息 * * @param merchantId * @return */ public Map selectAdapayMember(String merchantId) throws BaseAdaPayException { Map map = Maps.newHashMap(); AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(merchantId); if (adapayMemberAccount == null) { log.error("通过merchantId:{}, 没有查询到结算账户配置", merchantId); return null; } String adapayMemberId = adapayMemberAccount.getAdapayMemberId(); String settleAccountId = adapayMemberAccount.getSettleAccountId(); AdapayMemberInfoVO adapayMemberInfoVO = queryAdapayMemberInfo(adapayMemberId); if (adapayMemberInfoVO != null) { adapayMemberInfoVO.setMerchantId(merchantId); } AdapaySettleAccountVO adapaySettleAccountVO = queryAdapaySettleAccount(adapayMemberId, settleAccountId); if (adapaySettleAccountVO != null) { adapaySettleAccountVO.setMerchantId(merchantId); } map.put("adapayMember", adapayMemberInfoVO); map.put("settleAccountList", Lists.newArrayList(adapaySettleAccountVO)); return map; } /** * 查询汇付会员信息 */ public AdapayMemberInfoVO queryAdapayMemberInfo(String adapayMemberId) throws BaseAdaPayException { if (StringUtils.isBlank(adapayMemberId)) { return null; } Map memberParams = Maps.newHashMap(); memberParams.put("member_id", adapayMemberId); memberParams.put("app_id", ADAPAY_APP_ID); log.info("查询用户,请求参数:{}", JSON.toJSONString(memberParams)); Map member = Member.query(memberParams); log.info("查询用户,返回参数:{}", 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() .nickname(queryMemberResponse.getNickname()) .gender(queryMemberResponse.getGender()) .email(queryMemberResponse.getEmail()) .location(queryMemberResponse.getLocation()) .build(); return resultVO; } /** * 查询汇付结算账户信息 */ public AdapaySettleAccountVO queryAdapaySettleAccount(String adapayMemberId, String settleAccountId) throws BaseAdaPayException { if (StringUtils.isBlank(adapayMemberId) || StringUtils.isBlank(settleAccountId)) { return null; } Map settleCountParams = Maps.newHashMap(); settleCountParams.put("settle_account_id", settleAccountId); settleCountParams.put("member_id", adapayMemberId); settleCountParams.put("app_id", ADAPAY_APP_ID); log.info("查询汇付结算账户信息param:{}", JSON.toJSONString(settleCountParams)); Map settleAccount = SettleAccount.query(settleCountParams); log.info("查询汇付结算账户信息result:{}", 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 { AdapayAccountBalanceVO vo = AdapayAccountBalanceVO.builder().build(); // 通过merchantId 查询出汇付会员id 和 结算账户id,用来查询余额 AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(merchantId); if (adapayMemberAccount == null) { log.error("通过merchantId:{}, 没有查询到结算账户配置", merchantId); return vo; } String settle_account_id = adapayMemberAccount.getSettleAccountId(); String member_id = adapayMemberAccount.getAdapayMemberId(); Map queryParams = Maps.newHashMap(); queryParams.put("settle_account_id", settle_account_id); queryParams.put("member_id", member_id); queryParams.put("app_id", ADAPAY_APP_ID); Map settleCount = SettleAccount.balance(queryParams); 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"))); return vo; } /** * 更新结算账户设置 * * @param dto * @throws BaseAdaPayException */ public void updateSettleAccountConfig(UpdateAccountConfigDTO dto) throws BaseAdaPayException { // 通过merchantId 查询出汇付会员id 和 结算账户id,用来查询余额 AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(dto.getMerchantId()); if (adapayMemberAccount == null) { log.error("通过merchantId:{}, 没有查询到结算账户配置", dto.getMerchantId()); return; } // 修改账户配置 Map params = Maps.newHashMap(); params.put("app_id", ADAPAY_APP_ID); 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 settleCount = SettleAccount.update(params); } /** * 创建企业用户 */ public void createCorpMember(CreateSettleAccountDTO dto) throws BaseAdaPayException, IOException { Map memberParams = Maps.newHashMap(); String adapayMemberId = "ACM" + IdUtils.getMemberId(); memberParams.put("member_id", adapayMemberId); memberParams.put("app_id", ADAPAY_APP_ID); memberParams.put("order_no", "jsdk_order" + System.currentTimeMillis()); 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("bank_code", dto.getBankCode()); memberParams.put("bank_acct_type", dto.getBankAcctType()); memberParams.put("card_no", dto.getCardNo()); memberParams.put("card_name", dto.getCardName()); File file = dto.getAttachFile().getResource().getFile(); log.info("创建企业账户param:{}", memberParams); Map member = CorpMember.create(memberParams, file); log.info("创建企业账户result:{}", member); // 保存到数据库 AdapayMemberAccount adapayMemberAccount = new AdapayMemberAccount(); adapayMemberAccount.setMerchantId(dto.getMerchantId()); adapayMemberAccount.setAdapayMemberId(adapayMemberId); // adapayMemberAccount.setSettleAccountId(settleAccountId); adapayMemberAccountService.insertAdapayMemberAccount(adapayMemberAccount); } public void withdraw(WithdrawDTO dto) throws BaseAdaPayException { // 通过merchantId 查询出汇付会员id 和 结算账户id,用来查询余额 AdapayMemberAccount adapayMemberAccount = adapayMemberAccountService.selectByMerchantId(dto.getMerchantId()); if (adapayMemberAccount == null) { log.error("通过merchantId:{}, 没有查询到结算账户配置", dto.getMerchantId()); return; } Map settleCountParams = Maps.newHashMap(); settleCountParams.put("order_no", "jsdk_payment_" + System.currentTimeMillis()); settleCountParams.put("cash_amt", AdapayUtil.formatAmount(dto.getCashAmt())); settleCountParams.put("member_id", adapayMemberAccount.getAdapayMemberId()); settleCountParams.put("app_id", ADAPAY_APP_ID); settleCountParams.put("settle_account_id", adapayMemberAccount.getSettleAccountId()); settleCountParams.put("cash_type", "T1"); settleCountParams.put("notify_url", ""); log.info("取现接口,请求参数:" + JSON.toJSONString(settleCountParams)); Map settleCount = Drawcash.create(settleCountParams); log.info("取现接口返回参数" + JSON.toJSONString(settleCount)); } }