|
|
@@ -0,0 +1,295 @@
|
|
|
+package com.izouma.nineth.service;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+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.config.EventNames;
|
|
|
+import com.izouma.nineth.config.GeneralProperties;
|
|
|
+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.PaymentItem;
|
|
|
+import com.izouma.nineth.dto.adapay.PaymentList;
|
|
|
+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.apache.rocketmq.spring.core.RocketMQTemplate;
|
|
|
+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;
|
|
|
+ private final RocketMQTemplate rocketMQTemplate;
|
|
|
+ private final GeneralProperties generalProperties;
|
|
|
+
|
|
|
+ @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<AdapayMerchant> 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 sendSelectEvent(Long id) {
|
|
|
+ JSONObject jsonObject = new JSONObject();
|
|
|
+ jsonObject.put("name", EventNames.SWITCH_ACCOUNT);
|
|
|
+ jsonObject.put("data", id);
|
|
|
+ rocketMQTemplate.convertAndSend(generalProperties.getBroadcastEventTopic(), jsonObject);
|
|
|
+
|
|
|
+ try {
|
|
|
+ Thread.sleep(500);
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ 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<AdapayMerchant> 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<BaseAdaPayException> 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<String, Object> 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<String, Object> 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<String, Object> settleCountParams = new HashMap<>();
|
|
|
+ Map<String, Object> 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<String, Object> 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<String, Object> memberParams = new HashMap<>();
|
|
|
+ memberParams.put("member_id", memberId);
|
|
|
+ memberParams.put("app_id", appId);
|
|
|
+ Map<String, Object> 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<String, Object> settleCountParams = new HashMap<>();
|
|
|
+ settleCountParams.put("settle_account_id", settleAccountsItem.getId());
|
|
|
+ settleCountParams.put("member_id", memberId);
|
|
|
+ settleCountParams.put("app_id", appId);
|
|
|
+ Map<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> paymentParams = new HashMap<>();
|
|
|
+ paymentParams.put("app_id", merchant.getAppId());
|
|
|
+ paymentParams.put("payment_id", id);
|
|
|
+ Map<String, Object> paymentList = Payment.queryList(paymentParams, merchant.getName());
|
|
|
+ log.info(JSON.toJSONString(paymentList, SerializerFeature.PrettyFormat));
|
|
|
+ return paymentList;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Object refund(Long merchantId, String id) throws BaseAdaPayException {
|
|
|
+ AdapayMerchant merchant = adapayMerchantRepo.findById(merchantId).orElseThrow(new BusinessException("商户不存在"));
|
|
|
+
|
|
|
+ Map<String, Object> paymentParams = new HashMap<>();
|
|
|
+ paymentParams.put("app_id", merchant.getAppId());
|
|
|
+ paymentParams.put("payment_id", id);
|
|
|
+ Map<String, Object> res = Payment.queryList(paymentParams, merchant.getName());
|
|
|
+ log.info(JSON.toJSONString(res, SerializerFeature.PrettyFormat));
|
|
|
+ PaymentList paymentList = JSON.parseObject(JSON.toJSONString(res), PaymentList.class);
|
|
|
+
|
|
|
+ if (paymentList.getPayments() != null && paymentList.getPayments().size() == 1) {
|
|
|
+ PaymentItem paymentItem = paymentList.getPayments().get(0);
|
|
|
+ Map<String, Object> refundParams = new HashMap<>();
|
|
|
+ refundParams.put("refund_amt", paymentItem.getPayAmt());
|
|
|
+ refundParams.put("refund_order_no", new SnowflakeIdWorker(0, 0).nextId() + "");
|
|
|
+ Map<String, Object> response = Refund.create(id, refundParams, merchant.getName());
|
|
|
+ log.info(JSON.toJSONString(response, SerializerFeature.PrettyFormat));
|
|
|
+ return response;
|
|
|
+ }
|
|
|
+ return res;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void checkSuccess(Map<String, Object> map) {
|
|
|
+ String status = MapUtils.getString(map, "status");
|
|
|
+ if (!("succeeded".equals(status))) {
|
|
|
+ String errMsg = MapUtils.getString(map, "error_msg");
|
|
|
+ String errCode = MapUtils.getString(map, "error_code");
|
|
|
+ if ("account_exists".equals(errCode)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ throw new BusinessException(errMsg + "(" + errCode + ")");
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|