Payment.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. package com.ym.mec.thirdparty.adapay;
  2. import java.math.BigDecimal;
  3. import java.util.*;
  4. import com.alibaba.fastjson.JSON;
  5. import com.alibaba.fastjson.JSONObject;
  6. import com.google.common.collect.Lists;
  7. import com.huifu.adapay.core.exception.BaseAdaPayException;
  8. import com.huifu.adapay.core.util.StringUtil;
  9. import com.huifu.adapay.model.PaymentReverse;
  10. import com.huifu.adapay.model.Refund;
  11. import com.ym.mec.thirdparty.adapay.entity.BaseResult;
  12. import com.ym.mec.thirdparty.adapay.entity.HfMerchantConfig;
  13. import com.ym.mec.thirdparty.exception.ThirdpartyException;
  14. import org.apache.commons.lang3.StringUtils;
  15. import org.joda.time.DateTime;
  16. import org.slf4j.Logger;
  17. import org.slf4j.LoggerFactory;
  18. import org.springframework.util.CollectionUtils;
  19. import org.springframework.util.DigestUtils;
  20. public class Payment {
  21. private final static Logger LOGGER = LoggerFactory.getLogger(Payment.class);
  22. /**
  23. * 执行一个支付交易
  24. *
  25. * @return 创建的支付对象
  26. * @throws Exception 异常
  27. */
  28. public static Map<String, Object> executePayment(String appId, String merchantKey, Map<String, Object> paymentParams) throws Exception {
  29. paymentParams.put("app_id", appId);
  30. LOGGER.info("汇付[创建支付对象] Req:{}", paymentParams);
  31. //调用sdk方法,创建支付,得到支付对象
  32. Map<String, Object> payment = new HashMap<>();
  33. payment = com.huifu.adapay.model.Payment.create(paymentParams, merchantKey);
  34. LOGGER.info("汇付[创建支付对象] Resp:{}", payment);
  35. String errorCode = (String) payment.get("error_code");
  36. if (null != errorCode) {
  37. String errorMsg = (String) payment.get("error_msg");
  38. throw new ThirdpartyException(errorMsg);
  39. }
  40. return payment;
  41. }
  42. /**
  43. * 创建确认对象
  44. *
  45. * @return 查询的支付对象
  46. * @throws Exception 异常
  47. */
  48. public static Map<String, Object> createConfirm(Map<String, Object> confirm, String merchantKey) throws Exception {
  49. confirm = com.huifu.adapay.model.Payment.createConfirm(confirm, merchantKey);
  50. String error_code = (String) confirm.get("error_code");
  51. if (null != error_code) {
  52. String errorMsg = (String) confirm.get("error_msg");
  53. throw new ThirdpartyException(errorMsg);
  54. }
  55. return confirm;
  56. }
  57. /**
  58. * 查询一个支付交易
  59. *
  60. * @param paymentId 要查询的支付id
  61. * @return 查询的支付对象
  62. * @throws Exception 异常
  63. */
  64. public static Map<String, Object> queryPayment(String paymentId, String merchantKey) throws Exception {
  65. LOGGER.info("=======query payment begin=======");
  66. //查询支付对象的参数,全部参数请参考 https://docs.adapay.tech/api/04-trade.html#id7
  67. //调用sdk方法,查询支付交易,得到支付对象
  68. Map<String, Object> payment = new HashMap<>();
  69. try {
  70. LOGGER.info("queryPayment >>> 支付查询请求参数:{}", paymentId);
  71. payment = com.huifu.adapay.model.Payment.query(paymentId, merchantKey);
  72. } catch (ThirdpartyException e) {
  73. LOGGER.error("queryPayment >>> 支付查询异常", e.getCause());
  74. }
  75. LOGGER.info("queryPayment >>> 支付查询返回参数:{}", JSON.toJSONString(payment));
  76. String error_code = (String) payment.get("error_code");
  77. if (null != error_code) {
  78. String error_msg = (String) payment.get("error_msg");
  79. LOGGER.error("queryPayment >>> error_code:" + error_code + "............." + error_msg);
  80. }
  81. LOGGER.info("queryPayment >>> =======query payment end=======");
  82. return payment;
  83. }
  84. public static Map<String, Object> queryList(String appId, String merchantKey, Integer pageIndex, Long createdGte, Long createdLte) throws Exception {
  85. Map<java.lang.String, java.lang.Object> paymentParams = new HashMap<>();
  86. paymentParams.put("app_id", appId);
  87. paymentParams.put("page_index", pageIndex);
  88. paymentParams.put("page_size", "20");
  89. paymentParams.put("created_gte", createdGte);
  90. paymentParams.put("created_lte", createdLte);
  91. Map<String, Object> payment = com.huifu.adapay.model.Payment.queryList(paymentParams, merchantKey);
  92. String error_code = (String) payment.get("error_code");
  93. if (null != error_code) {
  94. String errorMsg = (String) payment.get("error_msg");
  95. throw new ThirdpartyException(errorMsg);
  96. }
  97. return payment;
  98. }
  99. public static Map<String, Object> queryConfirmList(String appId, String merchantKey, String paymentId) throws Exception {
  100. Map<String, Object> paymentParams = new HashMap<>();
  101. paymentParams.put("app_id", appId);
  102. paymentParams.put("payment_id", paymentId);
  103. Map<String, Object> payment = com.huifu.adapay.model.Payment.queryConfirmList(paymentParams, merchantKey);
  104. String error_code = (String) payment.get("error_code");
  105. if (null != error_code) {
  106. String errorMsg = (String) payment.get("error_msg");
  107. throw new ThirdpartyException(errorMsg);
  108. }
  109. return payment;
  110. }
  111. public static Map<String, Object> getPayMap(HfMerchantConfig hfMerchantConfig, BigDecimal amount, String orderNo, String returnUrl, String orderSubject, String orderBody) throws Exception {
  112. Map<String, Object> paymentParams = new LinkedHashMap<>();
  113. paymentParams.put("appId", hfMerchantConfig.getAppId());
  114. paymentParams.put("amount", amount.setScale(2, BigDecimal.ROUND_HALF_UP));
  115. paymentParams.put("orderNo", orderNo);
  116. // paymentParams.put("notifyUrl", notifyUrl);
  117. paymentParams.put("returnUrl", returnUrl);
  118. paymentParams.put("orderSubject", orderSubject);
  119. paymentParams.put("orderBody", orderBody);
  120. paymentParams.put("wxAppId", hfMerchantConfig.getWxAppId());
  121. paymentParams.put("alipayAppId", hfMerchantConfig.getAlipayAppId());
  122. String originalStr = JSONObject.toJSONString(paymentParams);
  123. String sign = DigestUtils.md5DigestAsHex(originalStr.getBytes());
  124. paymentParams.put("sign", sign);
  125. paymentParams.put("tenantId", hfMerchantConfig.getTenantId());
  126. paymentParams.remove("appId");
  127. return paymentParams;
  128. }
  129. public static BaseResult<Map<String ,Object>> refundPayment(Map<String, Object> refundParams) {
  130. LOGGER.info("退款对象信息:{}",refundParams);
  131. String transNo = refundParams.get("transNo").toString();
  132. refundParams.remove("transNo");
  133. Map<String, Object> res;
  134. try {
  135. res = Refund.create(transNo, refundParams);
  136. } catch (BaseAdaPayException e) {
  137. return BaseResult.failed(e.getMessage());
  138. }
  139. if (CollectionUtils.isEmpty(res)) {
  140. return BaseResult.failed("请求失败");
  141. }
  142. LOGGER.info("汇付[支付退款] Resp:{}", res);
  143. String errorCode = (String) res.get("error_code");
  144. if (null != errorCode) {
  145. String errorMsg = (String) res.get("error_msg");
  146. return BaseResult.failed(errorMsg);
  147. }
  148. return BaseResult.succeed(res);
  149. }
  150. // 撤销支付
  151. public static BaseResult<Map<String ,Object>> reversePayment(String paymentId,String appId,String reverseOrderNo,String reverseAmt,String notifyUrl) {
  152. LOGGER.info("撤销对象信息:paymentId:{},appId:{},reverseOrderNo:{},reverseAmt:{}",paymentId,appId,reverseOrderNo,reverseAmt);
  153. Map<String, Object> res;
  154. Map<String,Object> param = new HashMap<>();
  155. param.put("app_id",appId);
  156. param.put("payment_id",paymentId);
  157. param.put("reverse_amt",reverseAmt);
  158. param.put("order_no",reverseOrderNo);
  159. param.put("notify_url",notifyUrl);
  160. try {
  161. res = PaymentReverse.create(param);
  162. } catch (BaseAdaPayException e) {
  163. return BaseResult.failed(e.getMessage());
  164. }
  165. if (CollectionUtils.isEmpty(res)) {
  166. return BaseResult.failed("请求失败");
  167. }
  168. LOGGER.info("汇付[支付退款] Resp:{}", res);
  169. String errorCode = (String) res.get("error_code");
  170. if (null != errorCode) {
  171. String errorMsg = (String) res.get("error_msg");
  172. return BaseResult.failed(errorMsg);
  173. }
  174. return BaseResult.succeed(res);
  175. }
  176. /**
  177. *
  178. 针对已经创建的 支付对象,您可以调用关单接口进行交易的关闭。调用此接口后,该用户订单将不再能支付成功。 对于关单功能的使用有如下规则:
  179. 1.存在关单记录,不能再次关单
  180. 2.交易时间 1分钟 内无法关单成功
  181. 3.正扫交易时间超过 2小时 无法关单成功
  182. 4.支付宝正扫接口,如果用户没有扫码,订单不能关闭成功(二维码给用户展示,如果用户没有用手机去扫码,那这笔就不能关单; 如果用户扫过了的话(无需支付成功)就可以关单了)—-微信正扫无此条限制
  183. 5.网银和快捷类交易都不支持关单操作
  184. 对于已经成功付款的订单,请使用 退款对象 接口进行退款处理。我们建议您只有针对未支付的订单调用关单接口。
  185. * @param transNo 交易流水号
  186. * @param reason 原因
  187. * @param merchantKey 商户Key
  188. * @return Map<String, Object>
  189. */
  190. public static Map<String ,String> closeWithKey(String transNo, String reason, String merchantKey) {
  191. Map<String, String> result = new HashMap<>();
  192. Map<String, Object> params = new HashMap<>();
  193. params.put("payment_id", transNo);
  194. params.put("reason", reason);
  195. //params.put("notify_url", adapayPaymentConfig.getPayNotifyUrl());
  196. Map<String, Object> paymentClose = new HashMap<>();
  197. try {
  198. paymentClose = com.huifu.adapay.model.Payment.close(params, merchantKey);
  199. } catch (BaseAdaPayException e) {
  200. LOGGER.info("请求汇付[关单]接口失败:{}", e.getMessage());
  201. result.put("status", "failed");
  202. result.put ("msg",e.getMessage());
  203. return result;
  204. }
  205. if (StringUtils.equals(paymentClose.get("status").toString(), "failed")) {
  206. LOGGER.error("调用汇付[关单]接口同步返回,出现异常:{}", paymentClose);
  207. // 忽略关单异常
  208. // channel_close_fail 通道关单失败
  209. // close_order_exists 关单记录已存在,不允许重复关单
  210. List<String> errorCodes = Lists.newArrayList("close_order_exists"); // "channel_close_fail", "frequent_request"
  211. // 关单记录已存在,不允许重复关单,重复关单会不抛出异常,只记录异常信息
  212. if (errorCodes.contains(paymentClose.get("error_code").toString())) {
  213. LOGGER.warn("调用汇付[关单]接口同步返回,出现异常:{}", paymentClose);
  214. result.put("status", "success");
  215. return result;
  216. }
  217. result.put("status", "failed");
  218. result.put ("msg",paymentClose.get("error_msg").toString());
  219. return result;
  220. }
  221. result.put("status", "success");
  222. return result;
  223. }
  224. }