AliPayCommonServiceImpl.java 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. package com.cyksj.service.pay.impl;
  2. import cn.hutool.core.date.DateUtil;
  3. import cn.hutool.core.util.StrUtil;
  4. import com.alipay.api.AlipayApiException;
  5. import com.alipay.api.AlipayClient;
  6. import com.alipay.api.AlipayRequest;
  7. import com.alipay.api.domain.AlipayTradePagePayModel;
  8. import com.alipay.api.domain.AlipayTradeWapPayModel;
  9. import com.alipay.api.request.AlipayTradePagePayRequest;
  10. import com.alipay.api.request.AlipayTradeWapPayRequest;
  11. import com.baomidou.mybatisplus.core.toolkit.Assert;
  12. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  13. import com.cyksj.common.EnvCommonService;
  14. import com.cyksj.common.exception.BusinessRuntimeException;
  15. import com.cyksj.common.util.Codec;
  16. import com.cyksj.common.util.Jsons;
  17. import com.cyksj.common.util.StringUtil;
  18. import com.cyksj.config.zfb.AliPayClientFactory;
  19. import com.cyksj.config.zfb.BaseZfbConfig;
  20. import com.cyksj.config.zfb.ZfbProductCode;
  21. import com.cyksj.mapper.GoodsDonMapper;
  22. import com.cyksj.mapper.OrderDonMapper;
  23. import com.cyksj.mapper.RegisterOrderDonMapper;
  24. import com.cyksj.mapper.channel.ShopConfigMapper;
  25. import com.cyksj.mapper.order.OrderDonPostMapper;
  26. import com.cyksj.model.dto.AliPayParams;
  27. import com.cyksj.model.dto.OrderPayBuilderDto;
  28. import com.cyksj.model.entity.*;
  29. import com.cyksj.model.request.AlipayOrderDonReq;
  30. import com.cyksj.model.request.OrderAttach;
  31. import com.cyksj.service.pay.AliPayCommonService;
  32. import com.cyksj.service.sys.SysConfigService;
  33. import lombok.RequiredArgsConstructor;
  34. import lombok.extern.slf4j.Slf4j;
  35. import org.springframework.stereotype.Service;
  36. import java.math.BigDecimal;
  37. import java.math.RoundingMode;
  38. import java.util.Date;
  39. import java.util.Optional;
  40. /*
  41. *项目名: netflix
  42. *文件名: AliPayCommonServiceImpl
  43. *创建者: JavaZou
  44. *创建时间:2023/6/14 15:19
  45. */
  46. @Service
  47. @RequiredArgsConstructor
  48. @Slf4j
  49. public class AliPayCommonServiceImpl implements AliPayCommonService {
  50. private final RegisterOrderDonMapper registerOrderDonMapper;
  51. private final OrderDonMapper orderDonMapper;
  52. private final GoodsDonMapper goodsDonMapper;
  53. private final ShopConfigMapper shopConfigMapper;
  54. private final EnvCommonService envCommonService;
  55. private final SysConfigService sysConfigService;
  56. private final OrderDonPostMapper orderDonPostMapper;
  57. @Override
  58. public AliPayParams unifiedPayRegister(Long orderId, String productCode, String payMode, String returnUrl) throws Exception {
  59. RegisterOrderDon orderDon = registerOrderDonMapper.selectById(orderId);
  60. Assert.notNull(orderDon, "订单不存在");
  61. if (StrUtil.isEmpty(productCode)) throw BusinessRuntimeException.getInstance("支付异常");
  62. //获取支付宝默认商户
  63. String shopId = sysConfigService.getDefaultShopConfigByType("zfb");
  64. orderDon.setShopId(shopId);
  65. orderDon.setType(RegisterOrderDon.Type.ALI_PAY);
  66. if (orderDon.getType() != RegisterOrderDon.Type.ALI_PAY) {
  67. orderDon.setType(RegisterOrderDon.Type.ALI_PAY);
  68. }
  69. registerOrderDonMapper.updateById(orderDon);
  70. //回调地址
  71. String host = envCommonService.getHost();
  72. String notifyUrl = String.format("%s%s", host, BaseZfbConfig.zfb_register_notify_url);
  73. if (ZfbProductCode.MOBILE_WEB.getProductCode().equals(productCode) && BaseZfbConfig.qrPayMode_redirect.equals(payMode)) {
  74. returnUrl = String.format("%s%s", envCommonService.getDomain(), BaseZfbConfig.zfb_register_login_return_url);
  75. }
  76. String subject = "注册服务";
  77. AliPayParams aliPayParams = builderPayParams(orderDon.getId(),
  78. orderDon.getOrderNo(),
  79. orderDon.getShopId(),
  80. orderDon.getMoney(),
  81. orderDon.getCreatedTime(),
  82. subject,
  83. productCode,
  84. payMode,
  85. notifyUrl,
  86. returnUrl);
  87. return aliPayParams;
  88. }
  89. @Override
  90. public AliPayParams unifiedPay(AlipayOrderDonReq re, String productCode, String payMode) throws Exception {
  91. Long orderId = re.getOrderId();
  92. String returnUrl = re.getReturnUrl();
  93. OrderDon orderDon = orderDonMapper.selectById(orderId);
  94. //获取支付宝默认商户
  95. String appId = sysConfigService.getDefaultShopConfigByType("zfb");
  96. if (orderDon.getPopularizeId() != null) {
  97. ShopConfig shopConfig = shopConfigMapper.getByChannelPopularizeId(orderDon.getPopularizeId(), "zfb");
  98. if (shopConfig != null) {
  99. appId = shopConfig.getAppId();
  100. }
  101. }
  102. if (OrderDon.Type.ALI_PAY != orderDon.getType()) {
  103. orderDon.setType(OrderDon.Type.ALI_PAY);
  104. }
  105. orderDon.setShopId(appId);
  106. if (ZfbProductCode.PC_WEB.getProductCode().equals(productCode)) {
  107. orderDon.setIsWebPay(true);
  108. }
  109. if (ZfbProductCode.MOBILE_WEB.getProductCode().equals(productCode)) {
  110. orderDon.setIsWebPay(false);
  111. }
  112. orderDonMapper.updateById(orderDon);
  113. GoodsDon goodsDon = goodsDonMapper.selectById(orderDon.getGoodsId());
  114. String subject = goodsDon.getTitle().contains("ChatGPT") ? "AI订阅" : goodsDon.getTitle();
  115. //回调地址
  116. String host = envCommonService.getHost();
  117. String notifyUrl = String.format("%s%s", host, BaseZfbConfig.notifyUrl);
  118. //手机h5 跳转
  119. OrderDonPost orderDonPost = orderDonPostMapper.selectOne(Wrappers.lambdaQuery(OrderDonPost.class)
  120. .eq(OrderDonPost::getOrderId, orderId).last("limit 1"));
  121. //百度回传 跳转
  122. Boolean is_bdPost = false;
  123. if (orderDonPost != null && OrderDonPost.Type.BaiDu == orderDonPost.getType()) {
  124. is_bdPost = true;
  125. }
  126. //是否在微信内支付 微信内支付宝支付后 支付宝回调页面不跳转
  127. Boolean isWx = Optional.ofNullable(re.getIsWx()).orElse(false);
  128. if (ZfbProductCode.MOBILE_WEB.getProductCode().equals(productCode) && !isWx) {
  129. if (is_bdPost) {
  130. //页面 拼接订单号,前端从url获取订单id.
  131. returnUrl = String.format("%s%s", envCommonService.getDomain(), BaseZfbConfig.SUCCESS_URL) + orderDon.getId();
  132. } else {
  133. //默认跳转页
  134. returnUrl = String.format("%s%s", envCommonService.getDomain(), BaseZfbConfig.DEFAULT_URL);
  135. }
  136. }
  137. AliPayParams aliPayParams = builderPayParams(orderDon.getId(),
  138. orderDon.getOrderNo(),
  139. orderDon.getShopId(),
  140. orderDon.getMoney(),
  141. orderDon.getCreatedTime(),
  142. subject,
  143. productCode,
  144. payMode,
  145. notifyUrl,
  146. returnUrl);
  147. return aliPayParams;
  148. }
  149. public AliPayParams builderPayParams(Long orderId, String orderNo, String shopId, BigDecimal money, Date orderCreatedTime, String subject, String productCode, String payMode, String notifyUrl, String returnUrl) throws Exception {
  150. OrderPayBuilderDto orderPayBuilderDto = new OrderPayBuilderDto();
  151. orderPayBuilderDto.setOrderId(orderId);
  152. orderPayBuilderDto.setMoney(money);
  153. orderPayBuilderDto.setOrderNo(orderNo);
  154. orderPayBuilderDto.setSubject(subject);
  155. orderPayBuilderDto.setOrderCreatedTime(orderCreatedTime);
  156. orderPayBuilderDto.setProductCode(productCode);
  157. orderPayBuilderDto.setPayMode(payMode);
  158. orderPayBuilderDto.setReturnUrl(returnUrl);
  159. orderPayBuilderDto.setNotifyUrl(notifyUrl);
  160. orderPayBuilderDto.setShopId(shopId);
  161. AliPayParams aliPayParams = commonAliPay(orderPayBuilderDto);
  162. return aliPayParams;
  163. }
  164. public AliPayParams commonAliPay(OrderPayBuilderDto orderPayBuilderDto) throws Exception {
  165. AlipayClient alipayClient = AliPayClientFactory.getAlipayClient(Optional.ofNullable(orderPayBuilderDto.getShopId()).orElse(ShopConfig.ZFB_DEFAULT_APP_ID));
  166. String returnUrl = orderPayBuilderDto.getReturnUrl();
  167. String notifyUrl = orderPayBuilderDto.getNotifyUrl();
  168. // 创建API对应的request
  169. AlipayRequest alipayRequest = getAliAayRequest(orderPayBuilderDto);
  170. if (alipayRequest == null) {
  171. throw BusinessRuntimeException.getInstance("支付宝不支持该支付方式:{0}", orderPayBuilderDto.getProductCode());
  172. }
  173. if (StrUtil.isNotBlank(returnUrl)) {
  174. alipayRequest.setReturnUrl(returnUrl);
  175. }
  176. alipayRequest.setNotifyUrl(notifyUrl);
  177. String form = null;
  178. try {
  179. //调用SDK生成表单
  180. //pagePay 统一下单接口
  181. form = alipayClient.pageExecute(alipayRequest).getBody();
  182. } catch (AlipayApiException e) {
  183. log.error("支付宝生成表单错误:{}", StringUtil.getErrorText(e));
  184. }
  185. log.info("支付宝返回参数:{}", form);
  186. return new AliPayParams(form);
  187. }
  188. /**
  189. * 支付宝获取不同的request
  190. */
  191. private AlipayRequest getAliAayRequest(OrderPayBuilderDto payBuilderDto) throws Exception {
  192. Long orderId = payBuilderDto.getOrderId();
  193. BigDecimal money = payBuilderDto.getMoney();
  194. String orderNo = payBuilderDto.getOrderNo();
  195. //productCode 销售产品码,与支付宝签约的产品码名称
  196. String productCode = payBuilderDto.getProductCode();
  197. String subject = payBuilderDto.getSubject();
  198. Date orderCreatedTime = payBuilderDto.getOrderCreatedTime();
  199. //网页支付跳转模式
  200. String qrPayMode = payBuilderDto.getPayMode();
  201. OrderAttach attach = new OrderAttach();
  202. attach.setO(orderId);
  203. String body = Codec.DoBase64.custom()
  204. .setData(Jsons.toJson(attach)).encodeAsText();
  205. String moneyStr = money.divide(new BigDecimal(100), 2, RoundingMode.HALF_EVEN).toString();
  206. if (ZfbProductCode.MOBILE_WEB.getProductCode().equals(productCode)) {
  207. //手机网站支付
  208. AlipayTradeWapPayRequest alipayTradeWapPayRequest = new AlipayTradeWapPayRequest();
  209. //手机网站支付支付参数
  210. AlipayTradeWapPayModel alipayTradeWapPayModel = new AlipayTradeWapPayModel();
  211. alipayTradeWapPayModel.setBody(body);
  212. alipayTradeWapPayModel.setOutTradeNo(orderNo);
  213. alipayTradeWapPayModel.setTotalAmount(moneyStr);
  214. alipayTradeWapPayModel.setSubject(subject);
  215. alipayTradeWapPayModel.setProductCode(productCode);
  216. //5分钟订单失效时间
  217. alipayTradeWapPayModel.setTimeExpire(DateUtil.offsetMinute(orderCreatedTime, 5).toString());
  218. alipayTradeWapPayRequest.setBizModel(alipayTradeWapPayModel);
  219. return alipayTradeWapPayRequest;
  220. } else if (ZfbProductCode.PC_WEB.getProductCode().equals(productCode)) {
  221. //电脑网站支付
  222. AlipayTradePagePayRequest alipayTradePagePayRequest = new AlipayTradePagePayRequest();
  223. //电脑网站支付参数
  224. AlipayTradePagePayModel alipayTradePagePayModel = new AlipayTradePagePayModel();
  225. alipayTradePagePayModel.setBody(body);
  226. alipayTradePagePayModel.setOutTradeNo(orderNo);
  227. alipayTradePagePayModel.setTotalAmount(moneyStr);
  228. alipayTradePagePayModel.setSubject(subject);
  229. alipayTradePagePayModel.setProductCode(productCode);
  230. //5分钟订单失效时间
  231. alipayTradePagePayModel.setTimeExpire(DateUtil.offsetMinute(orderCreatedTime, 5).toString());
  232. if (StrUtil.isEmpty(qrPayMode)) {
  233. qrPayMode = BaseZfbConfig.qrPayMode_orderCode;
  234. }
  235. alipayTradePagePayModel.setQrPayMode(qrPayMode);
  236. alipayTradePagePayRequest.setBizModel(alipayTradePagePayModel);
  237. return alipayTradePagePayRequest;
  238. }
  239. return null;
  240. }
  241. }