AliPayCommonServiceImpl.java 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  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.snowflake.Sequence;
  16. import com.cyksj.common.util.Codec;
  17. import com.cyksj.common.util.Jsons;
  18. import com.cyksj.common.util.StringUtil;
  19. import com.cyksj.config.zfb.AliPayClientFactory;
  20. import com.cyksj.config.zfb.BaseZfbConfig;
  21. import com.cyksj.config.zfb.ZfbProductCode;
  22. import com.cyksj.mapper.*;
  23. import com.cyksj.mapper.channel.ShopConfigMapper;
  24. import com.cyksj.mapper.order.OrderDonPostMapper;
  25. import com.cyksj.model.dto.AliPayParams;
  26. import com.cyksj.model.dto.OrderPayBuilderDto;
  27. import com.cyksj.model.entity.*;
  28. import com.cyksj.model.request.AlipayOrderDonReq;
  29. import com.cyksj.model.request.OrderAttach;
  30. import com.cyksj.service.pay.AliPayCommonService;
  31. import com.cyksj.service.sys.SysConfigService;
  32. import lombok.RequiredArgsConstructor;
  33. import lombok.extern.slf4j.Slf4j;
  34. import org.springframework.stereotype.Service;
  35. import java.math.BigDecimal;
  36. import java.math.RoundingMode;
  37. import java.util.Date;
  38. import java.util.Optional;
  39. /*
  40. *项目名: netflix
  41. *文件名: AliPayCommonServiceImpl
  42. *创建者: JavaZou
  43. *创建时间:2023/6/14 15:19
  44. */
  45. @Service
  46. @RequiredArgsConstructor
  47. @Slf4j
  48. public class AliPayCommonServiceImpl implements AliPayCommonService {
  49. private final RegisterOrderDonMapper registerOrderDonMapper;
  50. private final OrderDonMapper orderDonMapper;
  51. private final GoodsDonMapper goodsDonMapper;
  52. private final ShopConfigMapper shopConfigMapper;
  53. private final EnvCommonService envCommonService;
  54. private final SysConfigService sysConfigService;
  55. private final OrderDonPostMapper orderDonPostMapper;
  56. private final UpgradeOrderDonMapper upgradeOrderDonMapper;
  57. private final UpgradePackageMapper upgradePackageMapper;
  58. private final GoodsWholesaleOrderDonMapper goodsWholesaleOrderDonMapper;
  59. private final GoodsWholesaleUserDepositMapper depositMapper;
  60. private static final Sequence SEQUENCE = new Sequence(0);
  61. @Override
  62. public AliPayParams unifiedPayRegister(Long orderId, String productCode, String payMode, String returnUrl) throws Exception {
  63. RegisterOrderDon orderDon = registerOrderDonMapper.selectById(orderId);
  64. Assert.notNull(orderDon, "订单不存在");
  65. if (StrUtil.isEmpty(productCode)) throw BusinessRuntimeException.getInstance("支付异常");
  66. //获取支付宝默认商户
  67. String shopId = sysConfigService.getDefaultShopConfigByType("zfb");
  68. orderDon.setShopId(shopId);
  69. orderDon.setType(RegisterOrderDon.Type.ALI_PAY);
  70. if (orderDon.getType() != RegisterOrderDon.Type.ALI_PAY) {
  71. orderDon.setType(RegisterOrderDon.Type.ALI_PAY);
  72. }
  73. registerOrderDonMapper.updateById(orderDon);
  74. //回调地址
  75. String host = envCommonService.getHost();
  76. String notifyUrl = String.format("%s%s", host, BaseZfbConfig.zfb_register_notify_url);
  77. if (ZfbProductCode.MOBILE_WEB.getProductCode().equals(productCode) && BaseZfbConfig.qrPayMode_redirect.equals(payMode)) {
  78. returnUrl = String.format("%s%s", envCommonService.getDomain(), BaseZfbConfig.zfb_register_login_return_url);
  79. }
  80. String subject = "注册服务";
  81. AliPayParams aliPayParams = builderPayParams(orderDon.getId(),
  82. orderDon.getOrderNo(),
  83. orderDon.getShopId(),
  84. orderDon.getMoney(),
  85. orderDon.getCreatedTime(),
  86. subject,
  87. productCode,
  88. payMode,
  89. notifyUrl,
  90. returnUrl);
  91. return aliPayParams;
  92. }
  93. @Override
  94. public AliPayParams unifiedPay(AlipayOrderDonReq re, String productCode, String payMode) throws Exception {
  95. Long orderId = re.getOrderId();
  96. String returnUrl = re.getReturnUrl();
  97. OrderDon orderDon = orderDonMapper.selectById(orderId);
  98. //获取支付宝默认商户
  99. String appId = sysConfigService.getDefaultShopConfigByType("zfb");
  100. if (orderDon.getPopularizeId() != null) {
  101. ShopConfig shopConfig = shopConfigMapper.getByChannelPopularizeId(orderDon.getPopularizeId(), "zfb");
  102. if (shopConfig != null) {
  103. appId = shopConfig.getAppId();
  104. }
  105. }
  106. if (OrderDon.Type.ALI_PAY != orderDon.getType()) {
  107. orderDon.setType(OrderDon.Type.ALI_PAY);
  108. }
  109. orderDon.setShopId(appId);
  110. if (ZfbProductCode.PC_WEB.getProductCode().equals(productCode)) {
  111. orderDon.setIsWebPay(true);
  112. }
  113. if (ZfbProductCode.MOBILE_WEB.getProductCode().equals(productCode)) {
  114. orderDon.setIsWebPay(false);
  115. }
  116. orderDonMapper.updateById(orderDon);
  117. GoodsDon goodsDon = goodsDonMapper.selectById(orderDon.getGoodsId());
  118. String subject = goodsDon.getTitle().contains("ChatGPT") ? "AI订阅" : goodsDon.getTitle();
  119. //回调地址
  120. String host = envCommonService.getHost();
  121. String notifyUrl = String.format("%s%s", host, BaseZfbConfig.notifyUrl);
  122. //手机h5 跳转
  123. OrderDonPost orderDonPost = orderDonPostMapper.selectOne(Wrappers.lambdaQuery(OrderDonPost.class)
  124. .eq(OrderDonPost::getOrderId, orderId).last("limit 1"));
  125. //百度回传 跳转
  126. Boolean is_bdPost = false;
  127. if (orderDonPost != null && OrderDonPost.Type.BaiDu == orderDonPost.getType()) {
  128. is_bdPost = true;
  129. }
  130. //是否在微信内支付 微信内支付宝支付后 支付宝回调页面不跳转
  131. Boolean isWx = Optional.ofNullable(re.getIsWx()).orElse(false);
  132. if (ZfbProductCode.MOBILE_WEB.getProductCode().equals(productCode) && !isWx) {
  133. if (is_bdPost) {
  134. //页面 拼接订单号,前端从url获取订单id.
  135. returnUrl = String.format("%s%s", envCommonService.getDomain(), BaseZfbConfig.SUCCESS_URL) + orderDon.getId();
  136. } else {
  137. //默认跳转页
  138. returnUrl = String.format("%s%s", envCommonService.getDomain(), BaseZfbConfig.DEFAULT_URL);
  139. }
  140. }
  141. AliPayParams aliPayParams = builderPayParams(orderDon.getId(),
  142. orderDon.getOrderNo(),
  143. orderDon.getShopId(),
  144. orderDon.getMoney(),
  145. orderDon.getCreatedTime(),
  146. subject,
  147. productCode,
  148. payMode,
  149. notifyUrl,
  150. returnUrl);
  151. return aliPayParams;
  152. }
  153. 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 {
  154. OrderPayBuilderDto orderPayBuilderDto = new OrderPayBuilderDto();
  155. orderPayBuilderDto.setOrderId(orderId);
  156. orderPayBuilderDto.setMoney(money);
  157. orderPayBuilderDto.setOrderNo(orderNo);
  158. orderPayBuilderDto.setSubject(subject);
  159. orderPayBuilderDto.setOrderCreatedTime(orderCreatedTime);
  160. orderPayBuilderDto.setProductCode(productCode);
  161. orderPayBuilderDto.setPayMode(payMode);
  162. orderPayBuilderDto.setReturnUrl(returnUrl);
  163. orderPayBuilderDto.setNotifyUrl(notifyUrl);
  164. orderPayBuilderDto.setShopId(shopId);
  165. AliPayParams aliPayParams = commonAliPay(orderPayBuilderDto);
  166. return aliPayParams;
  167. }
  168. public AliPayParams commonAliPay(OrderPayBuilderDto orderPayBuilderDto) throws Exception {
  169. AlipayClient alipayClient = AliPayClientFactory.getAlipayClient(Optional.ofNullable(orderPayBuilderDto.getShopId()).orElse(ShopConfig.ZFB_DEFAULT_APP_ID));
  170. String returnUrl = orderPayBuilderDto.getReturnUrl();
  171. String notifyUrl = orderPayBuilderDto.getNotifyUrl();
  172. // 创建API对应的request
  173. AlipayRequest alipayRequest = getAliAayRequest(orderPayBuilderDto);
  174. if (alipayRequest == null) {
  175. throw BusinessRuntimeException.getInstance("支付宝不支持该支付方式:{0}", orderPayBuilderDto.getProductCode());
  176. }
  177. if (StrUtil.isNotBlank(returnUrl)) {
  178. alipayRequest.setReturnUrl(returnUrl);
  179. }
  180. alipayRequest.setNotifyUrl(notifyUrl);
  181. String form = null;
  182. try {
  183. //调用SDK生成表单
  184. //pagePay 统一下单接口
  185. form = alipayClient.pageExecute(alipayRequest).getBody();
  186. } catch (AlipayApiException e) {
  187. log.error("支付宝生成表单错误:{}", StringUtil.getErrorText(e));
  188. }
  189. log.info("支付宝返回参数:{}", form);
  190. return new AliPayParams(form);
  191. }
  192. /**
  193. * 支付宝获取不同的request
  194. */
  195. private AlipayRequest getAliAayRequest(OrderPayBuilderDto payBuilderDto) throws Exception {
  196. Long orderId = payBuilderDto.getOrderId();
  197. BigDecimal money = payBuilderDto.getMoney();
  198. String orderNo = payBuilderDto.getOrderNo();
  199. //productCode 销售产品码,与支付宝签约的产品码名称
  200. String productCode = payBuilderDto.getProductCode();
  201. String subject = payBuilderDto.getSubject();
  202. Date orderCreatedTime = payBuilderDto.getOrderCreatedTime();
  203. //网页支付跳转模式
  204. String qrPayMode = payBuilderDto.getPayMode();
  205. OrderAttach attach = new OrderAttach();
  206. attach.setO(orderId);
  207. String body = Codec.DoBase64.custom()
  208. .setData(Jsons.toJson(attach)).encodeAsText();
  209. String moneyStr = money.divide(new BigDecimal(100), 2, RoundingMode.HALF_EVEN).toString();
  210. if (ZfbProductCode.MOBILE_WEB.getProductCode().equals(productCode)) {
  211. //手机网站支付
  212. AlipayTradeWapPayRequest alipayTradeWapPayRequest = new AlipayTradeWapPayRequest();
  213. //手机网站支付支付参数
  214. AlipayTradeWapPayModel alipayTradeWapPayModel = new AlipayTradeWapPayModel();
  215. alipayTradeWapPayModel.setBody(body);
  216. alipayTradeWapPayModel.setOutTradeNo(orderNo);
  217. alipayTradeWapPayModel.setTotalAmount(moneyStr);
  218. alipayTradeWapPayModel.setSubject(subject);
  219. alipayTradeWapPayModel.setProductCode(productCode);
  220. //5分钟订单失效时间
  221. alipayTradeWapPayModel.setTimeExpire(DateUtil.offsetMinute(orderCreatedTime, 5).toString());
  222. alipayTradeWapPayRequest.setBizModel(alipayTradeWapPayModel);
  223. return alipayTradeWapPayRequest;
  224. } else if (ZfbProductCode.PC_WEB.getProductCode().equals(productCode)) {
  225. //电脑网站支付
  226. AlipayTradePagePayRequest alipayTradePagePayRequest = new AlipayTradePagePayRequest();
  227. //电脑网站支付参数
  228. AlipayTradePagePayModel alipayTradePagePayModel = new AlipayTradePagePayModel();
  229. alipayTradePagePayModel.setBody(body);
  230. alipayTradePagePayModel.setOutTradeNo(orderNo);
  231. alipayTradePagePayModel.setTotalAmount(moneyStr);
  232. alipayTradePagePayModel.setSubject(subject);
  233. alipayTradePagePayModel.setProductCode(productCode);
  234. //5分钟订单失效时间
  235. alipayTradePagePayModel.setTimeExpire(DateUtil.offsetMinute(orderCreatedTime, 5).toString());
  236. if (StrUtil.isEmpty(qrPayMode)) {
  237. qrPayMode = BaseZfbConfig.qrPayMode_orderCode;
  238. }
  239. alipayTradePagePayModel.setQrPayMode(qrPayMode);
  240. alipayTradePagePayRequest.setBizModel(alipayTradePagePayModel);
  241. return alipayTradePagePayRequest;
  242. }
  243. return null;
  244. }
  245. @Override
  246. public AliPayParams unifiedPayUpgrade(AlipayOrderDonReq re, String productCode, String payMode) throws Exception {
  247. Long orderId = re.getOrderId();
  248. String returnUrl = re.getReturnUrl();
  249. UpgradeOrderDon orderDon = upgradeOrderDonMapper.selectById(orderId);
  250. //获取支付宝默认商户
  251. String appId = sysConfigService.getDefaultShopConfigByType("zfb");
  252. if (UpgradeOrderDon.Type.ALI_PAY != orderDon.getType()) {
  253. orderDon.setType(UpgradeOrderDon.Type.ALI_PAY);
  254. }
  255. orderDon.setShopId(appId);
  256. if (ZfbProductCode.PC_WEB.getProductCode().equals(productCode)) {
  257. orderDon.setIsWebPay(true);
  258. }
  259. if (ZfbProductCode.MOBILE_WEB.getProductCode().equals(productCode)) {
  260. orderDon.setIsWebPay(false);
  261. }
  262. upgradeOrderDonMapper.updateById(orderDon);
  263. UpgradePackage upgradePackage = upgradePackageMapper.selectById(orderDon.getPackageId());
  264. String subject = upgradePackage.getName();
  265. //回调地址
  266. String host = envCommonService.getHost();
  267. String notifyUrl = String.format("%s%s", host, BaseZfbConfig.upgradeNotifyUrl);
  268. //是否在微信内支付 微信内支付宝支付后 支付宝回调页面不跳转
  269. Boolean isWx = Optional.ofNullable(re.getIsWx()).orElse(false);
  270. if (ZfbProductCode.MOBILE_WEB.getProductCode().equals(productCode) && !isWx) {
  271. //默认跳转页
  272. returnUrl = String.format("%s%s", envCommonService.getDomain(), BaseZfbConfig.DEFAULT_URL);
  273. }
  274. return builderPayParams(orderDon.getId(),
  275. orderDon.getOrderNo(),
  276. orderDon.getShopId(),
  277. orderDon.getMoney(),
  278. orderDon.getCreatedTime(),
  279. subject,
  280. productCode,
  281. payMode,
  282. notifyUrl,
  283. returnUrl);
  284. }
  285. @Override
  286. public AliPayParams aliPayUnifiedWholesale(AlipayOrderDonReq re, String productCode, String payMode) throws Exception {
  287. Long orderId = re.getOrderId();
  288. String returnUrl = re.getReturnUrl();
  289. GoodsWholesaleOrderDon orderDon = goodsWholesaleOrderDonMapper.selectById(orderId);
  290. //获取支付宝默认商户
  291. String appId = sysConfigService.getDefaultShopConfigByType("zfb");
  292. if (GoodsWholesaleOrderDon.Type.ALI_PAY != orderDon.getType()) {
  293. orderDon.setType(GoodsWholesaleOrderDon.Type.ALI_PAY);
  294. }
  295. orderDon.setShopId(appId);
  296. if (ZfbProductCode.PC_WEB.getProductCode().equals(productCode)) {
  297. orderDon.setIsWebPay(true);
  298. }
  299. if (ZfbProductCode.MOBILE_WEB.getProductCode().equals(productCode)) {
  300. orderDon.setIsWebPay(false);
  301. }
  302. goodsWholesaleOrderDonMapper.updateById(orderDon);
  303. GoodsDon goodsDon = goodsDonMapper.selectById(orderDon.getGoodsId());
  304. String subject = goodsDon.getTitle();
  305. //回调地址
  306. String host = envCommonService.getHost();
  307. String notifyUrl = String.format("%s%s", host, BaseZfbConfig.wholesaleNotifyUrl);
  308. //是否在微信内支付 微信内支付宝支付后 支付宝回调页面不跳转
  309. Boolean isWx = Optional.ofNullable(re.getIsWx()).orElse(false);
  310. if (StrUtil.isEmpty(returnUrl) && ZfbProductCode.MOBILE_WEB.getProductCode().equals(productCode) && !isWx) {
  311. //默认跳转页
  312. returnUrl = String.format("%s%s", envCommonService.getDomain(), BaseZfbConfig.DEFAULT_URL);
  313. }
  314. return builderPayParams(orderDon.getId(),
  315. orderDon.getOrderNo(),
  316. orderDon.getShopId(),
  317. orderDon.getMoney(),
  318. orderDon.getCreatedTime(),
  319. subject,
  320. productCode,
  321. payMode,
  322. notifyUrl,
  323. returnUrl);
  324. }
  325. @Override
  326. public AliPayParams aliPayUnifiedWholesaleDeposit(AlipayOrderDonReq re, String productCode, String payMode) throws Exception {
  327. Long orderId = re.getOrderId();
  328. String returnUrl = re.getReturnUrl();
  329. GoodsWholesaleUserDeposit orderDon = depositMapper.selectById(orderId);
  330. //获取支付宝默认商户
  331. String appId = sysConfigService.getDefaultShopConfigByType("zfb");
  332. if (GoodsWholesaleUserDeposit.Type.ALI_PAY != orderDon.getType()) {
  333. orderDon.setType(GoodsWholesaleUserDeposit.Type.ALI_PAY);
  334. }
  335. orderDon.setShopId(appId);
  336. if (ZfbProductCode.PC_WEB.getProductCode().equals(productCode)) {
  337. orderDon.setIsWebPay(true);
  338. }
  339. if (ZfbProductCode.MOBILE_WEB.getProductCode().equals(productCode)) {
  340. orderDon.setIsWebPay(false);
  341. }
  342. depositMapper.updateById(orderDon);
  343. String subject = "押金";
  344. //回调地址
  345. String host = envCommonService.getHost();
  346. String notifyUrl = String.format("%s%s", host, BaseZfbConfig.wholesaleDepositNotifyUrl);
  347. //是否在微信内支付 微信内支付宝支付后 支付宝回调页面不跳转
  348. Boolean isWx = Optional.ofNullable(re.getIsWx()).orElse(false);
  349. if (StrUtil.isEmpty(returnUrl) && ZfbProductCode.MOBILE_WEB.getProductCode().equals(productCode) && !isWx) {
  350. //默认跳转页
  351. returnUrl = String.format("%s%s", envCommonService.getDomain(), BaseZfbConfig.DEFAULT_URL);
  352. }
  353. return builderPayParams(orderDon.getId(),
  354. orderDon.getOrderNo(),
  355. orderDon.getShopId(),
  356. orderDon.getMoney(),
  357. orderDon.getUpdateTime(),
  358. subject,
  359. productCode,
  360. payMode,
  361. notifyUrl,
  362. returnUrl);
  363. }
  364. }