package com.izouma.nineth.service; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.SerializerFeature; import com.huifu.adapay.Adapay; import com.huifu.adapay.core.exception.BaseAdaPayException; import com.huifu.adapay.model.*; import com.izouma.nineth.config.AdapayProperties; import com.izouma.nineth.domain.AdapayMerchant; import com.izouma.nineth.dto.PageQuery; import com.izouma.nineth.dto.adapay.MemberInfo; import com.izouma.nineth.dto.adapay.SettleAccountsItem; import com.izouma.nineth.exception.BusinessException; import com.izouma.nineth.repo.AdapayMerchantRepo; import com.izouma.nineth.utils.JpaUtils; import com.izouma.nineth.utils.ObjUtils; import com.izouma.nineth.utils.SnowflakeIdWorker; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.MapUtils; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; @Service @AllArgsConstructor @Slf4j public class AdapayMerchantService { private final AdapayMerchantRepo adapayMerchantRepo; private final AdapayProperties adapayProperties; @PostConstruct public void init() { log.info("init AdapayMerchantService"); for (AdapayMerchant merchant : adapayMerchantRepo.findAll()) { addMerchant(merchant); if (merchant.isSelected()) { try { select(merchant.getId()); log.info("select merchant success={}", merchant.getName()); } catch (Exception e) { log.error("select merchant error", e); } } } } public Page all(PageQuery pageQuery) { return adapayMerchantRepo.findAll(JpaUtils.toSpecification(pageQuery, AdapayMerchant.class), JpaUtils.toPageRequest(pageQuery)); } public AdapayMerchant save(AdapayMerchant record) { record = adapayMerchantRepo.save(record); addMerchant(record); return record; } public AdapayMerchant update(AdapayMerchant record) { if (record.getId() == null) { throw new BusinessException("id不能为空"); } AdapayMerchant orig = adapayMerchantRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录")); ObjUtils.merge(orig, record); record = adapayMerchantRepo.save(orig); addMerchant(record); return record; } public void select(Long id) throws Exception { AdapayMerchant merchant = adapayMerchantRepo.findById(id).orElseThrow(new BusinessException("商户不存在")); MerConfig merConfig = new MerConfig(); merConfig.setApiKey(merchant.getApiKey()); merConfig.setApiMockKey(merchant.getMockKey()); merConfig.setRSAPrivateKey(merchant.getPrivKey()); merConfig.setRSAPublicKey(merchant.getPublicKey()); Adapay.initWithMerConfig(merConfig); adapayProperties.setApiKey(merchant.getApiKey()); adapayProperties.setMockKey(merchant.getMockKey()); adapayProperties.setPrivKey(merchant.getPrivKey()); adapayProperties.setPublicKey(merchant.getPublicKey()); adapayProperties.setMerchant(merchant.getName()); adapayProperties.setAppId(merchant.getAppId()); List list = adapayMerchantRepo.findAll(); list.forEach(m -> m.setSelected(m.getId().equals(id))); adapayMerchantRepo.saveAll(list); } public void addMerchant(AdapayMerchant merchant) { try { MerConfig merConfig = new MerConfig(); merConfig.setApiKey(merchant.getApiKey()); merConfig.setApiMockKey(merchant.getMockKey()); merConfig.setRSAPrivateKey(merchant.getPrivKey()); merConfig.setRSAPublicKey(merchant.getPublicKey()); Adapay.addMerConfig(merConfig, merchant.getName()); } catch (Exception e) { log.error("add Merchant Error", e); } } public void createMemberForAll(String memberId, String tel, String realName, String idno) throws BaseAdaPayException { AtomicReference ex = new AtomicReference<>(); adapayMerchantRepo.findAll().parallelStream().forEach(merchant -> { try { createMember(merchant.getName(), merchant.getAppId(), memberId, tel, realName, idno); } catch (BaseAdaPayException e) { log.error("createMemberForAll", e); ex.set(e); } }); if (ex.get() != null) { throw ex.get(); } } public void createMember(String merchant, String appId, String memberId, String tel, String realName, String idno) throws BaseAdaPayException { Map memberParams = new HashMap<>(); memberParams.put("adapay_func_code", "members.realname"); memberParams.put("member_id", memberId); memberParams.put("app_id", appId); memberParams.put("tel_no", tel); memberParams.put("user_name", realName); memberParams.put("cert_type", "00"); memberParams.put("cert_id", idno); Map res = AdapayCommon.requestAdapay(memberParams, merchant); log.info("createMember merchant={} response={}", merchant, JSON.toJSONString(res, SerializerFeature.PrettyFormat)); if (!("succeeded".equals(MapUtils.getString(res, "status")) || "member_id_exists".equals(MapUtils.getString(res, "error_code")))) { String errMsg = MapUtils.getString(res, "error_msg"); String errCode = MapUtils.getString(res, "error_code"); log.error("createMember error merchant={} memberId={}", merchant, memberId); throw new BusinessException(errMsg + "(" + errCode + ")"); } } public String createSettleAccountForAll(String memberId, String realName, String idNo, String phone, String bankNo) throws BaseAdaPayException { String id = null; for (AdapayMerchant merchant : adapayMerchantRepo.findAll()) { id = createSettleAccount(merchant.getName(), merchant.getAppId(), memberId, realName, idNo, phone, bankNo); } return id; } public String createSettleAccount(String merchant, String appId, String memberId, String realName, String idNo, String phone, String bankNo) throws BaseAdaPayException { Map settleCountParams = new HashMap<>(); Map accountInfo = new HashMap<>(); accountInfo.put("card_id", bankNo); accountInfo.put("card_name", realName); accountInfo.put("cert_id", idNo); accountInfo.put("cert_type", "00"); accountInfo.put("tel_no", phone); accountInfo.put("bank_acct_type", "2"); settleCountParams.put("member_id", memberId); settleCountParams.put("app_id", appId); settleCountParams.put("channel", "bank_account"); settleCountParams.put("account_info", accountInfo); Map res = SettleAccount.create(settleCountParams, merchant); log.info("createSettleAccount merchant={} response={}", merchant, JSON.toJSONString(res, SerializerFeature.PrettyFormat)); if (!("succeeded".equals(MapUtils.getString(res, "status")) || "account_exists".equals(MapUtils.getString(res, "error_code")))) { String errMsg = MapUtils.getString(res, "error_msg"); String errCode = MapUtils.getString(res, "error_code"); log.error("createSettleAccount error merchant={} memberId={}", merchant, memberId); throw new BusinessException(errMsg + "(" + errCode + ")"); } return MapUtils.getString(res, "id"); } public void delSettleAccountForAll(String memberId) throws BaseAdaPayException { for (AdapayMerchant merchant : adapayMerchantRepo.findAll()) { delSettleAccount(merchant.getName(), merchant.getAppId(), memberId); } } public void delSettleAccount(String merchant, String appId, String memberId) throws BaseAdaPayException { Map memberParams = new HashMap<>(); memberParams.put("member_id", memberId); memberParams.put("app_id", appId); Map member = Member.query(memberParams, merchant); log.info("query member, merchant={} member={} res={}", merchant, memberId, JSON.toJSONString(member, SerializerFeature.PrettyFormat)); MemberInfo memberInfo = JSON.parseObject(JSON.toJSONString(member), MemberInfo.class); if ("succeeded".equals(memberInfo.getStatus())) { if (memberInfo.getSettleAccounts() != null && memberInfo.getSettleAccounts().size() > 0) { SettleAccountsItem settleAccountsItem = memberInfo.getSettleAccounts().get(0); Map settleCountParams = new HashMap<>(); settleCountParams.put("settle_account_id", settleAccountsItem.getId()); settleCountParams.put("member_id", memberId); settleCountParams.put("app_id", appId); Map settleCount = SettleAccount.delete(settleCountParams, merchant); log.info("delSettleAccount, merchant={} member={} res={}", merchant, memberId, JSON.toJSONString(settleCount, SerializerFeature.PrettyFormat)); checkSuccess(settleCount); } } else if ("member_not_exists".equals(memberInfo.getErrorCode())) { log.info("delSettleAccount member_not_exists, merchant={} member={}", merchant, memberId); } else { throw new BusinessException(memberInfo.getErrorMsg() + memberInfo.getErrorCode()); } } public void queryMembers(String merchant, String appId) { boolean hasMore = true; while (hasMore) { try { Map memberParams = new HashMap<>(2); memberParams.put("page_index", "1"); memberParams.put("app_id", appId); memberParams.put("page_size", "20"); memberParams.put("created_gte", String.valueOf(System.currentTimeMillis() - 5 * 60 * 1000)); memberParams.put("created_lte", String.valueOf(System.currentTimeMillis())); Map member = Member.queryList(memberParams); MapUtils.getBoolean(member, "has_more", false); } catch (Exception e) { log.error("queryMembers error", e); hasMore = false; } } } public Object query(Long merchantId, String id) throws BaseAdaPayException { AdapayMerchant merchant = adapayMerchantRepo.findById(merchantId).orElseThrow(new BusinessException("商户不存在")); Map map = Payment.query(id, merchant.getName()); log.info(JSON.toJSONString(map, SerializerFeature.PrettyFormat)); return map; } public Object refund(Long merchantId, String id) throws BaseAdaPayException { AdapayMerchant merchant = adapayMerchantRepo.findById(merchantId).orElseThrow(new BusinessException("商户不存在")); Map map = Payment.query(id, merchant.getName()); if (!"succeeded".equals(MapUtils.getString(map, "status"))) { return map; } String amt = MapUtils.getString(map, "pay_amt"); Map refundParams = new HashMap<>(); refundParams.put("refund_amt", amt); refundParams.put("refund_order_no", new SnowflakeIdWorker(0, 0).nextId() + ""); Map response = Refund.create(id, refundParams, merchant.getName()); log.info(JSON.toJSONString(response, SerializerFeature.PrettyFormat)); return response; } public static void checkSuccess(Map map) { if (!"succeeded".equals(MapUtils.getString(map, "status"))) { String errMsg = MapUtils.getString(map, "error_msg"); String errCode = MapUtils.getString(map, "error_code"); throw new BusinessException(errMsg + "(" + errCode + ")"); } } }