AdapayMerchantService.java 12 KB

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