AdapayMerchantService.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. package com.izouma.nineth.service;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.alibaba.fastjson.serializer.SerializerFeature;
  5. import com.huifu.adapay.Adapay;
  6. import com.huifu.adapay.core.exception.BaseAdaPayException;
  7. import com.huifu.adapay.model.*;
  8. import com.izouma.nineth.config.AdapayProperties;
  9. import com.izouma.nineth.config.EventNames;
  10. import com.izouma.nineth.config.GeneralProperties;
  11. import com.izouma.nineth.domain.AdapayMerchant;
  12. import com.izouma.nineth.dto.PageQuery;
  13. import com.izouma.nineth.dto.adapay.MemberInfo;
  14. import com.izouma.nineth.dto.adapay.SettleAccountsItem;
  15. import com.izouma.nineth.exception.BusinessException;
  16. import com.izouma.nineth.repo.AdapayMerchantRepo;
  17. import com.izouma.nineth.utils.JpaUtils;
  18. import com.izouma.nineth.utils.ObjUtils;
  19. import com.izouma.nineth.utils.SnowflakeIdWorker;
  20. import lombok.AllArgsConstructor;
  21. import lombok.extern.slf4j.Slf4j;
  22. import org.apache.commons.collections.MapUtils;
  23. import org.apache.rocketmq.spring.core.RocketMQTemplate;
  24. import org.springframework.data.domain.Page;
  25. import org.springframework.stereotype.Service;
  26. import javax.annotation.PostConstruct;
  27. import java.util.HashMap;
  28. import java.util.List;
  29. import java.util.Map;
  30. import java.util.concurrent.atomic.AtomicReference;
  31. @Service
  32. @AllArgsConstructor
  33. @Slf4j
  34. public class AdapayMerchantService {
  35. private final AdapayMerchantRepo adapayMerchantRepo;
  36. private final AdapayProperties adapayProperties;
  37. private final RocketMQTemplate rocketMQTemplate;
  38. private final GeneralProperties generalProperties;
  39. @PostConstruct
  40. public void init() {
  41. log.info("init AdapayMerchantService");
  42. for (AdapayMerchant merchant : adapayMerchantRepo.findAll()) {
  43. addMerchant(merchant);
  44. if (merchant.isSelected()) {
  45. try {
  46. select(merchant.getId());
  47. log.info("select merchant success={}", merchant.getName());
  48. } catch (Exception e) {
  49. log.error("select merchant error", e);
  50. }
  51. }
  52. }
  53. }
  54. public Page<AdapayMerchant> all(PageQuery pageQuery) {
  55. return adapayMerchantRepo.findAll(JpaUtils.toSpecification(pageQuery, AdapayMerchant.class), JpaUtils.toPageRequest(pageQuery));
  56. }
  57. public AdapayMerchant save(AdapayMerchant record) {
  58. record = adapayMerchantRepo.save(record);
  59. addMerchant(record);
  60. return record;
  61. }
  62. public AdapayMerchant update(AdapayMerchant record) {
  63. if (record.getId() == null) {
  64. throw new BusinessException("id不能为空");
  65. }
  66. AdapayMerchant orig = adapayMerchantRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
  67. ObjUtils.merge(orig, record);
  68. record = adapayMerchantRepo.save(orig);
  69. addMerchant(record);
  70. return record;
  71. }
  72. public void sendSelectEvent(Long id) {
  73. JSONObject jsonObject = new JSONObject();
  74. jsonObject.put("name", EventNames.SWITCH_ACCOUNT);
  75. jsonObject.put("data", id);
  76. rocketMQTemplate.convertAndSend(generalProperties.getBroadcastEventTopic(), jsonObject);
  77. try {
  78. Thread.sleep(500);
  79. } catch (InterruptedException e) {
  80. e.printStackTrace();
  81. }
  82. }
  83. public void select(Long id) throws Exception {
  84. AdapayMerchant merchant = adapayMerchantRepo.findById(id).orElseThrow(new BusinessException("商户不存在"));
  85. MerConfig merConfig = new MerConfig();
  86. merConfig.setApiKey(merchant.getApiKey());
  87. merConfig.setApiMockKey(merchant.getMockKey());
  88. merConfig.setRSAPrivateKey(merchant.getPrivKey());
  89. merConfig.setRSAPublicKey(merchant.getPublicKey());
  90. Adapay.initWithMerConfig(merConfig);
  91. adapayProperties.setApiKey(merchant.getApiKey());
  92. adapayProperties.setMockKey(merchant.getMockKey());
  93. adapayProperties.setPrivKey(merchant.getPrivKey());
  94. adapayProperties.setPublicKey(merchant.getPublicKey());
  95. adapayProperties.setMerchant(merchant.getName());
  96. adapayProperties.setAppId(merchant.getAppId());
  97. List<AdapayMerchant> list = adapayMerchantRepo.findAll();
  98. list.forEach(m -> m.setSelected(m.getId().equals(id)));
  99. adapayMerchantRepo.saveAll(list);
  100. }
  101. public void addMerchant(AdapayMerchant merchant) {
  102. try {
  103. MerConfig merConfig = new MerConfig();
  104. merConfig.setApiKey(merchant.getApiKey());
  105. merConfig.setApiMockKey(merchant.getMockKey());
  106. merConfig.setRSAPrivateKey(merchant.getPrivKey());
  107. merConfig.setRSAPublicKey(merchant.getPublicKey());
  108. Adapay.addMerConfig(merConfig, merchant.getName());
  109. } catch (Exception e) {
  110. log.error("add Merchant Error", e);
  111. }
  112. }
  113. public void createMemberForAll(String memberId, String tel, String realName, String idno) throws BaseAdaPayException {
  114. AtomicReference<BaseAdaPayException> ex = new AtomicReference<>();
  115. adapayMerchantRepo.findAll().parallelStream().forEach(merchant -> {
  116. try {
  117. createMember(merchant.getName(), merchant.getAppId(), memberId, tel, realName, idno);
  118. } catch (BaseAdaPayException e) {
  119. log.error("createMemberForAll", e);
  120. ex.set(e);
  121. }
  122. });
  123. if (ex.get() != null) {
  124. throw ex.get();
  125. }
  126. }
  127. public void createMember(String merchant, String appId, String memberId, String tel, String realName, String idno) throws BaseAdaPayException {
  128. Map<String, Object> memberParams = new HashMap<>();
  129. memberParams.put("adapay_func_code", "members.realname");
  130. memberParams.put("member_id", memberId);
  131. memberParams.put("app_id", appId);
  132. memberParams.put("tel_no", tel);
  133. memberParams.put("user_name", realName);
  134. memberParams.put("cert_type", "00");
  135. memberParams.put("cert_id", idno);
  136. Map<String, Object> res = AdapayCommon.requestAdapay(memberParams, merchant);
  137. log.info("createMember merchant={} response={}", merchant, JSON.toJSONString(res, SerializerFeature.PrettyFormat));
  138. if (!("succeeded".equals(MapUtils.getString(res, "status"))
  139. || "member_id_exists".equals(MapUtils.getString(res, "error_code")))) {
  140. String errMsg = MapUtils.getString(res, "error_msg");
  141. String errCode = MapUtils.getString(res, "error_code");
  142. log.error("createMember error merchant={} memberId={}", merchant, memberId);
  143. throw new BusinessException(errMsg + "(" + errCode + ")");
  144. }
  145. }
  146. public String createSettleAccountForAll(String memberId, String realName, String idNo, String phone, String bankNo) throws BaseAdaPayException {
  147. String id = null;
  148. for (AdapayMerchant merchant : adapayMerchantRepo.findAll()) {
  149. id = createSettleAccount(merchant.getName(), merchant.getAppId(), memberId, realName, idNo, phone, bankNo);
  150. }
  151. return id;
  152. }
  153. public String createSettleAccount(String merchant, String appId, String memberId, String realName, String idNo, String phone, String bankNo) throws BaseAdaPayException {
  154. Map<String, Object> settleCountParams = new HashMap<>();
  155. Map<String, Object> accountInfo = new HashMap<>();
  156. accountInfo.put("card_id", bankNo);
  157. accountInfo.put("card_name", realName);
  158. accountInfo.put("cert_id", idNo);
  159. accountInfo.put("cert_type", "00");
  160. accountInfo.put("tel_no", phone);
  161. accountInfo.put("bank_acct_type", "2");
  162. settleCountParams.put("member_id", memberId);
  163. settleCountParams.put("app_id", appId);
  164. settleCountParams.put("channel", "bank_account");
  165. settleCountParams.put("account_info", accountInfo);
  166. Map<String, Object> res = SettleAccount.create(settleCountParams, merchant);
  167. log.info("createSettleAccount merchant={} response={}", merchant, JSON.toJSONString(res, SerializerFeature.PrettyFormat));
  168. if (!("succeeded".equals(MapUtils.getString(res, "status"))
  169. || "account_exists".equals(MapUtils.getString(res, "error_code")))) {
  170. String errMsg = MapUtils.getString(res, "error_msg");
  171. String errCode = MapUtils.getString(res, "error_code");
  172. log.error("createSettleAccount error merchant={} memberId={}", merchant, memberId);
  173. throw new BusinessException(errMsg + "(" + errCode + ")");
  174. }
  175. return MapUtils.getString(res, "id");
  176. }
  177. public void delSettleAccountForAll(String memberId) throws BaseAdaPayException {
  178. for (AdapayMerchant merchant : adapayMerchantRepo.findAll()) {
  179. delSettleAccount(merchant.getName(), merchant.getAppId(), memberId);
  180. }
  181. }
  182. public void delSettleAccount(String merchant, String appId, String memberId) throws BaseAdaPayException {
  183. Map<String, Object> memberParams = new HashMap<>();
  184. memberParams.put("member_id", memberId);
  185. memberParams.put("app_id", appId);
  186. Map<String, Object> member = Member.query(memberParams, merchant);
  187. log.info("query member, merchant={} member={} res={}",
  188. merchant, memberId, JSON.toJSONString(member, SerializerFeature.PrettyFormat));
  189. MemberInfo memberInfo = JSON.parseObject(JSON.toJSONString(member), MemberInfo.class);
  190. if ("succeeded".equals(memberInfo.getStatus())) {
  191. if (memberInfo.getSettleAccounts() != null && memberInfo.getSettleAccounts().size() > 0) {
  192. SettleAccountsItem settleAccountsItem = memberInfo.getSettleAccounts().get(0);
  193. Map<String, Object> settleCountParams = new HashMap<>();
  194. settleCountParams.put("settle_account_id", settleAccountsItem.getId());
  195. settleCountParams.put("member_id", memberId);
  196. settleCountParams.put("app_id", appId);
  197. Map<String, Object> settleCount = SettleAccount.delete(settleCountParams, merchant);
  198. log.info("delSettleAccount, merchant={} member={} res={}",
  199. merchant, memberId, JSON.toJSONString(settleCount, SerializerFeature.PrettyFormat));
  200. checkSuccess(settleCount);
  201. }
  202. } else if ("member_not_exists".equals(memberInfo.getErrorCode())) {
  203. log.info("delSettleAccount member_not_exists, merchant={} member={}", merchant, memberId);
  204. } else {
  205. throw new BusinessException(memberInfo.getErrorMsg() + memberInfo.getErrorCode());
  206. }
  207. }
  208. public void queryMembers(String merchant, String appId) {
  209. boolean hasMore = true;
  210. while (hasMore) {
  211. try {
  212. Map<String, Object> memberParams = new HashMap<>(2);
  213. memberParams.put("page_index", "1");
  214. memberParams.put("app_id", appId);
  215. memberParams.put("page_size", "20");
  216. memberParams.put("created_gte", String.valueOf(System.currentTimeMillis() - 5 * 60 * 1000));
  217. memberParams.put("created_lte", String.valueOf(System.currentTimeMillis()));
  218. Map<String, Object> member = Member.queryList(memberParams);
  219. MapUtils.getBoolean(member, "has_more", false);
  220. } catch (Exception e) {
  221. log.error("queryMembers error", e);
  222. hasMore = false;
  223. }
  224. }
  225. }
  226. public Object query(Long merchantId, String id) throws BaseAdaPayException {
  227. AdapayMerchant merchant = adapayMerchantRepo.findById(merchantId).orElseThrow(new BusinessException("商户不存在"));
  228. Map<String, Object> map = Payment.query(id, merchant.getName());
  229. log.info(JSON.toJSONString(map, SerializerFeature.PrettyFormat));
  230. return map;
  231. }
  232. public Object refund(Long merchantId, String id) throws BaseAdaPayException {
  233. AdapayMerchant merchant = adapayMerchantRepo.findById(merchantId).orElseThrow(new BusinessException("商户不存在"));
  234. Map<String, Object> map = Payment.query(id, merchant.getName());
  235. if (!"succeeded".equals(MapUtils.getString(map, "status"))) {
  236. return map;
  237. }
  238. String amt = MapUtils.getString(map, "pay_amt");
  239. Map<String, Object> refundParams = new HashMap<>();
  240. refundParams.put("refund_amt", amt);
  241. refundParams.put("refund_order_no", new SnowflakeIdWorker(0, 0).nextId() + "");
  242. Map<String, Object> response = Refund.create(id, refundParams, merchant.getName());
  243. log.info(JSON.toJSONString(response, SerializerFeature.PrettyFormat));
  244. return response;
  245. }
  246. public static void checkSuccess(Map<String, Object> map) {
  247. String status = MapUtils.getString(map, "status");
  248. if (!("succeeded".equals(status))) {
  249. String errMsg = MapUtils.getString(map, "error_msg");
  250. String errCode = MapUtils.getString(map, "error_code");
  251. if ("account_exists".equals(errCode)) {
  252. return;
  253. }
  254. throw new BusinessException(errMsg + "(" + errCode + ")");
  255. }
  256. }
  257. }