OrderController.java 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. package com.cyksj.web.controller.payment;
  2. import cn.hutool.core.util.StrUtil;
  3. import cn.hutool.extra.qrcode.QrCodeUtil;
  4. import cn.hutool.extra.qrcode.QrConfig;
  5. import com.alipay.api.response.AlipayFundTransCommonQueryResponse;
  6. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  7. import com.cyksj.common.constant.Constant;
  8. import com.cyksj.common.exception.BusinessRuntimeException;
  9. import com.cyksj.common.util.IoKit;
  10. import com.cyksj.common.util.Jsons;
  11. import com.cyksj.common.util.Xmls;
  12. import com.cyksj.config.zfb.BaseZfbConfig;
  13. import com.cyksj.config.zfb.ZfbProductCode;
  14. import com.cyksj.dto.Result;
  15. import com.cyksj.enums.GatewayApiCode;
  16. import com.cyksj.enums.GatewayResponse;
  17. import com.cyksj.mapper.OrderDonWaybillMapper;
  18. import com.cyksj.mapper.UserMapper;
  19. import com.cyksj.mapper.channel.UserPayEquipmentAvailableBenefitsMapper;
  20. import com.cyksj.mapper.market.task.UserBindDetailMapper;
  21. import com.cyksj.model.dto.AliPayParams;
  22. import com.cyksj.model.dto.H5JsPayParams;
  23. import com.cyksj.model.entity.*;
  24. import com.cyksj.model.manage.views.OrderDonSearchView;
  25. import com.cyksj.model.manage.views.OrderDonView;
  26. import com.cyksj.model.request.AlipayOrderDonReq;
  27. import com.cyksj.model.request.OrderPayRequest;
  28. import com.cyksj.model.response.AliPayTradeStatus;
  29. import com.cyksj.model.views.GoodsDonSkuView;
  30. import com.cyksj.model.views.OrderCommentView;
  31. import com.cyksj.service.order.OrderDonService;
  32. import com.cyksj.service.paypal.PayPalService;
  33. import com.cyksj.service.paypal.PaypalPayConfigService;
  34. import com.cyksj.service.shop.YhShopFrontService;
  35. import com.cyksj.service.stripe.StripePayConfigService;
  36. import com.cyksj.service.stripe.StripeService;
  37. import com.cyksj.service.user.UserBindRelationService;
  38. import com.cyksj.web.util.StpUserUtil;
  39. import com.ejlchina.searcher.BeanSearcher;
  40. import com.ejlchina.searcher.SearchResult;
  41. import com.ejlchina.searcher.param.Operator;
  42. import com.ejlchina.searcher.util.MapBuilder;
  43. import com.ejlchina.searcher.util.MapUtils;
  44. import com.google.gson.JsonSyntaxException;
  45. import com.paypal.api.payments.Links;
  46. import com.paypal.api.payments.Payment;
  47. import com.stripe.exception.SignatureVerificationException;
  48. import com.stripe.model.*;
  49. import com.stripe.model.checkout.Session;
  50. import com.stripe.net.Webhook;
  51. import lombok.extern.slf4j.Slf4j;
  52. import org.apache.commons.lang3.StringUtils;
  53. import org.springframework.beans.factory.annotation.Autowired;
  54. import org.springframework.validation.annotation.Validated;
  55. import org.springframework.web.bind.annotation.*;
  56. import javax.annotation.Resource;
  57. import javax.servlet.http.HttpServletRequest;
  58. import javax.servlet.http.HttpServletResponse;
  59. import java.io.InputStream;
  60. import java.io.OutputStream;
  61. import java.nio.charset.StandardCharsets;
  62. import java.util.HashMap;
  63. import java.util.List;
  64. import java.util.Map;
  65. import java.util.Set;
  66. import java.util.stream.Collectors;
  67. /**
  68. * @author chan
  69. * @date 2021/10/11 下午3:50
  70. */
  71. @Slf4j
  72. @RequestMapping("/applets/order")
  73. @RestController
  74. public class OrderController {
  75. @Autowired
  76. private OrderDonService orderDonService;
  77. @Resource
  78. private BeanSearcher beanSearcher;
  79. @Resource
  80. private HttpServletRequest request;
  81. @Resource
  82. private HttpServletResponse response;
  83. @Autowired
  84. private UserBindDetailMapper userBindDetailMapper;
  85. @Autowired
  86. private UserMapper userMapper;
  87. @Autowired
  88. private UserPayEquipmentAvailableBenefitsMapper availableBenefitsMapper;
  89. @Autowired
  90. private OrderDonWaybillMapper waybillMapper;
  91. @Autowired
  92. private UserBindRelationService UserBindRelationService;
  93. @Autowired
  94. private PaypalPayConfigService paypalPayConfigService;
  95. @Autowired
  96. private PayPalService payPalService;
  97. @Autowired
  98. private StripePayConfigService stripePayConfigService;
  99. @Autowired
  100. private StripeService stripeService;
  101. @Autowired
  102. private YhShopFrontService yhShopFrontService;
  103. /**
  104. * 支付
  105. * @author chan
  106. * @date 2021-10-11 下午4:56
  107. */
  108. @PostMapping("/post/submit")
  109. public Result<OrderDon> submit(@Validated @RequestBody OrderPayRequest payRequest) throws Exception {
  110. final String methodName = "吊起微信支付";
  111. payRequest.setUserId(StpUserUtil.getUserIdAfterLogin());
  112. log.info("{}[start] params:{}",methodName,payRequest);
  113. OrderDon orderDon = orderDonService.submit(payRequest);
  114. return GatewayResponse.SUCCESS.newBuilder().toResult(orderDon);
  115. }
  116. /**
  117. * 0元订单确认
  118. */
  119. @PostMapping("/post/order/status/{orderId}")
  120. public Result<String> zeroOrderConfirm(@PathVariable Long orderId) {
  121. orderDonService.zeroOrderConfirm(orderId);
  122. return GatewayResponse.SUCCESS.newBuilder().toResult();
  123. }
  124. /**
  125. * 支付
  126. * @author chan
  127. * @date 2021-10-11 下午4:56
  128. */
  129. @PostMapping("/post/pay/{orderId}")
  130. public Result<H5JsPayParams> pay(@PathVariable Long orderId) throws Exception {
  131. final String methodName = "吊起微信支付";
  132. log.info("{}[start] orderId:{}",methodName,orderId);
  133. H5JsPayParams payParams = orderDonService.pay(orderId, "JSAPI");
  134. return GatewayResponse.SUCCESS.newBuilder().toResult(payParams);
  135. }
  136. /**
  137. * 调用生成订单之后
  138. * 微信网页预下单获取交易链接生成二维码
  139. */
  140. @PostMapping("/get/wx/orderQrCode/{orderId}")
  141. public Result<String> createUnifiedOrderQr(@PathVariable Long orderId) throws Exception {
  142. //预下单
  143. H5JsPayParams payParams = orderDonService.wxPcWebPay(orderId, "NATIVE");
  144. //获取二维码链接code_url
  145. String codeUrl = payParams.getCodeUrl();
  146. QrConfig qrConfig = new QrConfig(300, 300);
  147. return GatewayResponse.SUCCESS.newBuilder().toResult(QrCodeUtil.generateAsBase64(codeUrl, qrConfig, "png"));
  148. }
  149. /**
  150. * 微信支付回调
  151. * @author chan
  152. * @date 2021-10-11 下午5:42
  153. */
  154. @PostMapping("/prepay/notify")
  155. public void prepayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
  156. String xml = IoKit.toString(request.getInputStream());
  157. log.info("=== 微信支付成功的回调: \n {}", xml);
  158. // 解析xml
  159. Map<String, String> map = Xmls.toMap(xml);
  160. // 支付失败
  161. if (!StringUtils.equals("SUCCESS", map.get("return_code")) || !StringUtils.equals("SUCCESS", map.get("result_code"))) {
  162. throw BusinessRuntimeException.getInstance("支付失败.");
  163. }
  164. orderDonService.prepayNotify(map);
  165. String toWeChatXmlResponse = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
  166. OutputStream out = null;
  167. try {
  168. out = response.getOutputStream();
  169. IoKit.write(toWeChatXmlResponse, out);
  170. } catch (Exception e) {
  171. throw BusinessRuntimeException.getInstance(e,e.getMessage());
  172. } finally {
  173. IoKit.close(out);
  174. }
  175. }
  176. /**
  177. * pc端微信支付回调
  178. * @author chan
  179. * @date 2021-10-11 下午5:42
  180. */
  181. @PostMapping("/pc/prepay/notify")
  182. public void pcPrepayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {
  183. String xml = IoKit.toString(request.getInputStream());
  184. log.info("=== 微信pc端分发支付成功的回调: \n {}", xml);
  185. // 解析xml
  186. Map<String, String> map = Xmls.toMap(xml);
  187. // 支付失败
  188. if (!StringUtils.equals("SUCCESS", map.get("return_code")) || !StringUtils.equals("SUCCESS", map.get("result_code"))) {
  189. throw BusinessRuntimeException.getInstance("支付失败.");
  190. }
  191. orderDonService.prepayNotify(map);
  192. log.info("pc端微信支付回调修改订单状态成功");
  193. String toWeChatXmlResponse = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
  194. OutputStream out = null;
  195. try {
  196. out = response.getOutputStream();
  197. IoKit.write(toWeChatXmlResponse, out);
  198. } catch (Exception e) {
  199. throw BusinessRuntimeException.getInstance(e,e.getMessage());
  200. } finally {
  201. IoKit.close(out);
  202. }
  203. }
  204. /**
  205. * 支付宝表单支付
  206. * 支付宝调起支付宝表单
  207. * 手机支付
  208. */
  209. @PostMapping("/post/pay/zfb")
  210. @Deprecated
  211. public Result<String> aliPay(@RequestBody @Validated AlipayOrderDonReq re) throws Exception {
  212. Long orderId = re.getOrderId();
  213. String returnUrl = re.getReturnUrl();
  214. AliPayParams aliPayParams = orderDonService.aliPay(orderId, returnUrl, ZfbProductCode.MOBILE_WEB.getProductCode(), null);
  215. // response.setContentType("text/html;charset=" + BaseZfbConfig.charset);
  216. //直接将完整的表单html输出到页面
  217. // response.getWriter().write(aliPayParams.getBody());
  218. // response.getWriter().flush();
  219. // response.getWriter().close();
  220. return GatewayResponse.SUCCESS.newBuilder().toResult(aliPayParams.getBody());
  221. }
  222. /**
  223. * 支付宝web支付
  224. * pc网页内嵌二维码
  225. */
  226. @PostMapping("/get/zfb/orderQrCode")
  227. public Result<String> zfbWebQrCode(@RequestBody @Validated AlipayOrderDonReq re) throws Exception {
  228. Long orderId = re.getOrderId();
  229. String returnUrl = re.getReturnUrl();
  230. AliPayParams aliPayParams = orderDonService.aliPay(orderId, returnUrl, ZfbProductCode.PC_WEB.getProductCode(), BaseZfbConfig.qrPayMode_orderCode);
  231. // response.setContentType("text/html;charset=" + BaseZfbConfig.charset);
  232. //直接将完整的表单html输出到页面
  233. // response.getWriter().write(aliPayParams.getBody());
  234. // response.getWriter().flush();
  235. // response.getWriter().close();
  236. return GatewayResponse.SUCCESS.newBuilder().toResult(aliPayParams.getBody());
  237. }
  238. /**
  239. * 支付宝web支付
  240. * pc网页跳转二维码
  241. */
  242. @PostMapping("/get/zfb/orderRedirect")
  243. public Result<String> zfbWebRedirectQrCode(@RequestBody @Validated AlipayOrderDonReq re) throws Exception {
  244. Long orderId = re.getOrderId();
  245. String returnUrl = re.getReturnUrl();
  246. AliPayParams aliPayParams = orderDonService.aliPay(orderId, returnUrl, ZfbProductCode.PC_WEB.getProductCode(), BaseZfbConfig.qrPayMode_redirect);
  247. return GatewayResponse.SUCCESS.newBuilder().toResult(aliPayParams.getBody());
  248. }
  249. /**
  250. * 支付宝回调
  251. */
  252. @PostMapping("/prepay/zfb/notify")
  253. public String aliPayNotify(HttpServletRequest request) throws Exception {
  254. ////将异步通知中收到的所有参数都存放到map中
  255. Map<String, String> params = convertRequestParamsToMap(request);
  256. String tradeStatus = params.get("trade_status");
  257. String orderNo = params.get("out_trade_no");
  258. if (AliPayTradeStatus.TRADE_SUCCESS.getStatus().equals(tradeStatus) || AliPayTradeStatus.TRADE_FINISHED.getStatus().equals(tradeStatus)) {
  259. log.info("支付宝商家订单号orderNo:{},status:{}开始回调", orderNo, tradeStatus);
  260. orderDonService.aliPayNotify(params);
  261. } else {
  262. log.error("支付宝回调 error 状态不符合 成功或完成 status:{} ,orderNo:{}", tradeStatus, orderNo);
  263. return "fail";
  264. }
  265. return "success";
  266. }
  267. /**
  268. * 支付宝转账
  269. */
  270. // @PostMapping("/zfb/transfer/accounts")
  271. // @NoSubmit
  272. // public Result<String> zfbTransferAccounts(@RequestBody @Validated TransferAccountsReq transferAccountsReq) throws Exception {
  273. // long userId = StpUserUtil.getLoginIdAsLong();
  274. // transferAccountsReq.setUserId(userId);
  275. // orderDonService.transferAccounts(transferAccountsReq);
  276. // return GatewayResponse.SUCCESS.newBuilder().toResult("转账成功");
  277. // }
  278. /**
  279. * 查询支付宝转账状态
  280. */
  281. @GetMapping("/zfb/transfer/status")
  282. public Result<String> getTransFerStatusByTid(String translationId) throws Exception {
  283. AlipayFundTransCommonQueryResponse response = orderDonService.getTransFerStatusByTid(translationId);
  284. if (response.isSuccess()) {
  285. if (!Constant.SUCCESS.equals(response.getStatus())) {
  286. return GatewayResponse.SUCCESS.newBuilder().toResult(response.getFailReason());
  287. }
  288. return GatewayResponse.SUCCESS.newBuilder().toResult("该红包已转账成功");
  289. }
  290. return GatewayResponse.SUCCESS.newBuilder().toResult(response.getSubMsg());
  291. }
  292. /**
  293. * 获取订单列表
  294. */
  295. @GetMapping("/get")
  296. public Result<SearchResult<OrderDonView>> list(String customId){
  297. long userId = StpUserUtil.getLoginIdAsLong();
  298. MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap());
  299. Long yhsId = yhShopFrontService.getYhsIdByCustomId(customId);
  300. List<Long> userIds = UserBindRelationService.getRelationUserIdList(userId, null);
  301. SearchResult<OrderDonView> search = beanSearcher.search(OrderDonView.class, builder
  302. .field(OrderDonView::getYhsId, yhsId)
  303. .field(OrderDonView::getUserId, userIds).op(Operator.InList)
  304. .orderBy(OrderDonView::getId).desc()
  305. .build());
  306. search.getDataList().forEach(data->{
  307. Integer count = availableBenefitsMapper.selectCount(Wrappers.lambdaQuery(UserPayEquipmentAvailableBenefits.class)
  308. .eq(UserPayEquipmentAvailableBenefits::getRealOrderId, data.getId())
  309. .eq(UserPayEquipmentAvailableBenefits::getDeleted, true));
  310. data.setIsHasBenefits(count > 0 ? true : false);
  311. if (data.getIsBenefits() != null && data.getIsBenefits()) {
  312. String benefitsList = data.getBenefitsList();
  313. if (StrUtil.isNotBlank(benefitsList)) {
  314. try {
  315. List<Long> skuIds = Jsons.parseList(benefitsList, GoodsDonSku.class).stream().map(GoodsDonSku::getId).collect(Collectors.toList());
  316. data.setBenefitsViews(beanSearcher.searchAll(GoodsDonSkuView.class, MapUtils.builder().field(GoodsDonSkuView::getSkuId, skuIds).op(Operator.InList).build()));
  317. } catch (Exception e) {
  318. }
  319. }
  320. }
  321. data.setWaybill(waybillMapper.selectOne(Wrappers.lambdaQuery(OrderDonWaybill.class).eq(OrderDonWaybill::getOrderId, data.getId()).last("limit 1")));
  322. });
  323. return GatewayResponse.SUCCESS.newBuilder().toResult(search);
  324. }
  325. /**
  326. * 获取订单详情
  327. */
  328. @GetMapping("/get/{orderId}")
  329. public Result<OrderDetailView> detail(@PathVariable Long orderId, Boolean isNoLogin) {
  330. Long userId = StpUserUtil.getUserIdAfterLogin();
  331. OrderDetailView detail = orderDonService.getDetail(orderId, userId);
  332. return GatewayResponse.SUCCESS.newBuilder().toResult(detail);
  333. }
  334. /**
  335. * 取消订单
  336. */
  337. @GetMapping("/get/close/{orderId}")
  338. public Result<String> closeOrder(@PathVariable Long orderId) {
  339. long userId = StpUserUtil.getLoginIdAsLong();
  340. orderDonService.closeOrder(orderId, userId);
  341. return GatewayResponse.SUCCESS.newBuilder().toResult();
  342. }
  343. @GetMapping("/get/order/status/{orderId}")
  344. public Result<OrderDonSearchView> getOrderStatusById(@PathVariable Long orderId) {
  345. if (orderId < 1) {
  346. throw BusinessRuntimeException.getInstance("订单不存在");
  347. }
  348. OrderDonSearchView orderDonView = beanSearcher.searchFirst(OrderDonSearchView.class, MapUtils.builder()
  349. .put("orderId", String.format("where id = %s", orderId))
  350. .build());
  351. if (orderDonView == null) {
  352. throw BusinessRuntimeException.getInstance("订单不存在");
  353. }
  354. return GatewayResponse.SUCCESS.newBuilder().toResult(orderDonView);
  355. }
  356. @PostMapping("/get/noLogin/order")
  357. public Result<List<OrderDonView>> getSearchResult(@RequestBody List<Long> orderIds) {
  358. List<OrderDonView> orderDonViews = beanSearcher.searchAll(OrderDonView.class, MapUtils.builder()
  359. .field(OrderDonView::getId, orderIds).op(Operator.InList)
  360. .orderBy(OrderDonView::getId).desc().build());
  361. return GatewayResponse.SUCCESS.newBuilder().toResult(orderDonViews);
  362. }
  363. /**
  364. * 平台评论列表
  365. */
  366. @GetMapping("/get/orderComment")
  367. public Result<SearchResult<OrderCommentView>> getOrderCommentView() {
  368. SearchResult<OrderCommentView> search = beanSearcher.search(OrderCommentView.class, MapUtils.flatBuilder(request.getParameterMap()).build());
  369. return GatewayResponse.SUCCESS.newBuilder().toResult(search);
  370. }
  371. /**
  372. * 电脑端手机号注册 购买车票是否绑定了微信用户
  373. */
  374. @GetMapping("/isBindWx")
  375. public Result<Boolean> isBindWx() {
  376. Long userId = StpUserUtil.getLoginIdAsLong();
  377. User user = userMapper.selectById(userId);
  378. if (user == null) {
  379. throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID);
  380. }
  381. if (StrUtil.isEmpty(user.getLoginPhone())) {
  382. return GatewayResponse.SUCCESS.newBuilder().toResult(true);
  383. }
  384. UserBindDetail userBindDetail = userBindDetailMapper.selectOne(Wrappers.lambdaQuery(UserBindDetail.class)
  385. .eq(UserBindDetail::getPhone, user.getLoginPhone()));
  386. if (userBindDetail == null) {
  387. return GatewayResponse.SUCCESS.newBuilder().toResult(false);
  388. }
  389. return GatewayResponse.SUCCESS.newBuilder().toResult(true);
  390. }
  391. /**
  392. * 是否绑定了邮箱或手机号
  393. */
  394. @GetMapping("/isBind")
  395. public Result<Boolean> isBindPhoneOrEmail() {
  396. Long userId = StpUserUtil.getLoginIdAsLong();
  397. User user = userMapper.selectById(userId);
  398. if (user == null) {
  399. throw BusinessRuntimeException.getGatewayApiCode(GatewayApiCode.CMS_TOKEN_VALID);
  400. }
  401. //手机号注册 无需绑定
  402. if (StrUtil.isNotEmpty(user.getLoginPhone())) {
  403. return GatewayResponse.SUCCESS.newBuilder().toResult(true);
  404. }
  405. //是否绑定了手机号
  406. UserBindDetail userBindDetail = userBindDetailMapper.selectOne(Wrappers.lambdaQuery(UserBindDetail.class)
  407. .eq(StrUtil.isNotEmpty(user.getOpenId()), UserBindDetail::getUserId, userId)
  408. .eq(StrUtil.isNotEmpty(user.getEmail()), UserBindDetail::getEmailUserId, userId).last("limit 1"));
  409. if (userBindDetail == null || StrUtil.isEmpty(userBindDetail.getPhone())) {
  410. return GatewayResponse.SUCCESS.newBuilder().toResult(false);
  411. }
  412. return GatewayResponse.SUCCESS.newBuilder().toResult(true);
  413. }
  414. /**
  415. * 获取支付宝回调参数
  416. */
  417. private static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
  418. Map<String, String> retMap = new HashMap<>();
  419. Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();
  420. for (Map.Entry<String, String[]> entry : entrySet) {
  421. String name = entry.getKey();
  422. String[] values = entry.getValue();
  423. int valLen = values.length;
  424. if (valLen == 1) {
  425. retMap.put(name, values[0]);
  426. } else if (valLen > 1) {
  427. StringBuilder sb = new StringBuilder();
  428. for (String val : values) {
  429. sb.append(",").append(val);
  430. }
  431. retMap.put(name, sb.substring(1));
  432. } else {
  433. retMap.put(name, "");
  434. }
  435. }
  436. return retMap;
  437. }
  438. /**
  439. * paypal支付
  440. */
  441. @PostMapping("/paypal/pay/{orderId}")
  442. public Result<String> paypalPay(@PathVariable Long orderId,String successUrl) throws Exception {
  443. final String methodName = "paypal支付";
  444. log.info("{}[start] orderId:{}",methodName,orderId);
  445. Payment payment = payPalService.createPayment(orderId,successUrl);
  446. String payUrl = "/";
  447. log.info("paypal links:{}",payment.getLinks());
  448. for(Links links : payment.getLinks()){
  449. if("approval_url".equals(links.getRel())){
  450. // 客户付款登陆地址
  451. String payPalUrl = links.getHref();
  452. log.info("PayPal调起支付成功[end]:{}", orderId);
  453. payUrl = payPalUrl;
  454. }
  455. }
  456. log.info("paypal支付成功[end]");
  457. return GatewayResponse.SUCCESS.newBuilder().toResult(payUrl);
  458. }
  459. /**
  460. * stripe支付
  461. */
  462. @PostMapping("/stripe/pay/{orderId}")
  463. public Result<String> stripePay(@PathVariable Long orderId,String successUrl) throws Exception {
  464. final String methodName = "stripe支付";
  465. log.info("{}[start] orderId:{}",methodName,orderId);
  466. String payUrl = stripeService.checkOutStripe(orderId,successUrl);
  467. log.info("Stripe支付成功 result:{}[end]",payUrl);
  468. return GatewayResponse.SUCCESS.newBuilder().toResult(payUrl);
  469. }
  470. /**
  471. * paypal支付回调
  472. */
  473. @RequestMapping(value = "/paypal/notify")
  474. public void successPay(@RequestParam(value = "paymentId") String paymentId, @RequestParam(value = "PayerID") String PayerID) throws Exception {
  475. PaypalPayConfig paypalPayConfig = paypalPayConfigService.getById(1);
  476. response.sendRedirect(payPalService.successPayment(paymentId,PayerID,paypalPayConfig));
  477. }
  478. /**
  479. * stripe支付回调
  480. */
  481. @PostMapping("/stripe/notify")
  482. @ResponseBody
  483. public String webhooks() throws Exception {
  484. InputStream inputStream = request.getInputStream();
  485. byte[] bytes = IoKit.toBytes(inputStream);
  486. String payload = new String(bytes, StandardCharsets.UTF_8);
  487. String sigHeader = request.getHeader("Stripe-Signature");
  488. StripePayConfig stripePayConfig = stripePayConfigService.getById(1);
  489. Event event = null;
  490. try {
  491. event = Webhook.constructEvent(
  492. payload, sigHeader, stripePayConfig.getWebhookSecret()
  493. );
  494. } catch (JsonSyntaxException | SignatureVerificationException e) {
  495. response.setStatus(400);
  496. return "";
  497. }
  498. // Deserialize the nested object inside the event
  499. EventDataObjectDeserializer dataObjectDeserializer = event.getDataObjectDeserializer();
  500. StripeObject stripeObject = null;
  501. if (dataObjectDeserializer.getObject().isPresent()) {
  502. stripeObject = dataObjectDeserializer.getObject().orElse(null);
  503. } else {
  504. // Deserialization failed, probably due to an API version mismatch.
  505. // Refer to the Javadoc documentation on `EventDataObjectDeserializer` for
  506. // instructions on how to handle this case, or return an error here.
  507. }
  508. // Handle the event
  509. switch (event.getType()) {
  510. case "payment_intent.succeeded":
  511. PaymentIntent paymentIntent = (PaymentIntent) stripeObject;
  512. response.setStatus(200);
  513. break;
  514. case "charge.succeeded":
  515. //使用token支付成功回调
  516. Charge charge = (Charge) stripeObject;
  517. //TODO 此时根据charge ID 查询出关联的订单并处理支付成功业务代码
  518. response.setStatus(200);
  519. break;
  520. case "checkout.session.completed":
  521. //使用checkout支付成功回调
  522. Session session = (Session) stripeObject;
  523. stripeService.fulfillOrder(session);
  524. response.setStatus(200);
  525. break;
  526. default:
  527. response.setStatus(400);
  528. return "";
  529. }
  530. response.setStatus(200);
  531. return "";
  532. }
  533. }