PageRenderTime 79ms CodeModel.GetById 31ms RepoModel.GetById 1ms app.codeStats 0ms

/src/main/java/com/penuel/mythopoet/controllers/PayController.java

https://gitlab.com/tycoon/mythopoet
Java | 327 lines | 237 code | 30 blank | 60 comment | 68 complexity | 1ba3c5b3fe5496eae3e7654727fd349e MD5 | raw file
  1. package com.penuel.mythopoet.controllers;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.penuel.mythopoet.annotation.LoginRequired;
  4. import com.penuel.mythopoet.constants.PoetConstants;
  5. import com.penuel.mythopoet.model.*;
  6. import com.penuel.mythopoet.modelView.OrderView;
  7. import com.penuel.mythopoet.service.*;
  8. import com.penuel.mythopoet.utils.RequestUtil;
  9. import com.penuel.mythopoet.utils.ResponseUtil;
  10. import org.apache.commons.lang3.math.NumberUtils;
  11. import org.slf4j.Logger;
  12. import org.slf4j.LoggerFactory;
  13. import org.springframework.beans.factory.annotation.Autowired;
  14. import org.springframework.stereotype.Controller;
  15. import org.springframework.ui.Model;
  16. import org.springframework.util.CollectionUtils;
  17. import org.springframework.web.bind.annotation.*;
  18. import javax.servlet.http.Cookie;
  19. import javax.servlet.http.HttpServletRequest;
  20. import javax.servlet.http.HttpServletResponse;
  21. import java.util.Date;
  22. import java.util.List;
  23. import java.util.SortedMap;
  24. /**
  25. * PayController Created with mythopoet.
  26. * User: penuel (penuel.leo@gmail.com)
  27. * Date: 15/4/23 上午8:29
  28. * Desc:
  29. */
  30. @Controller @RequestMapping("/pay")
  31. public class PayController {
  32. private static final Logger LOGGER = LoggerFactory.getLogger(PayController.class);
  33. @Autowired
  34. private PayService payService;
  35. @Autowired
  36. private OrderService orderService;
  37. @Autowired
  38. private OrderDetailService orderDetailService;
  39. @Autowired
  40. private ItemSkuService itemSkuService;
  41. @Autowired
  42. private WxAuthService wxAuthService;
  43. @Autowired
  44. private AccessLogService accessLogService;
  45. /*
  46. https://api.mch.weixin.qq.com/pay/unifiedorder
  47. */
  48. @LoginRequired
  49. @RequestMapping(value = "/prepay", method = RequestMethod.POST, produces = "application/json;charset=utf-8") @ResponseBody
  50. public String prepay(HttpServletRequest request, Model model,
  51. @CookieValue("userId") Long userId,
  52. @RequestParam("orderId") Long orderId,
  53. @RequestParam( value = "payType", defaultValue = "0" ) int payType) {
  54. Orders order;
  55. try {
  56. order = orderService.getById(userId, orderId);
  57. List<OrderDetail> orderDetailList = orderDetailService.getByOrderId(orderId);
  58. if ( order == null || CollectionUtils.isEmpty(orderDetailList) ) {
  59. return ResponseUtil.result(1, "该订单不存在", "");
  60. }
  61. if ( order.getAddressId() == 0 ) {
  62. return ResponseUtil.result(1, "未选择收货地址,请确认", "");
  63. }
  64. for ( OrderDetail orderDetail : orderDetailList ) {
  65. ItemSku itemSku = itemSkuService.getValidSkuByItemAndProps(orderDetail.getItemId(), orderDetail.getProps());
  66. if ( itemSku == null || itemSku.getCount() < orderDetail.getCount() ) {
  67. int haveCount = itemSku == null ? 0 : itemSku.getCount();
  68. return ResponseUtil.result(1, "下手太慢了,【" + itemSku.getName() + "】商品已被其他人抢先支付了,剩余" + haveCount + "件", null);
  69. }
  70. }
  71. String userIp = RequestUtil.getRemoteHost(request);
  72. WxAuthUser wxAuthUser = wxAuthService.getByUserId(userId);
  73. if ( wxAuthUser == null || "".equals(wxAuthUser.getCode())) {
  74. //发送授权请求
  75. String authUrl = wxAuthService.authorizeURL(userId, orderId);
  76. return ResponseUtil.result(1001, "微信授权", authUrl);
  77. }
  78. //accesstoken expired
  79. long millSecond = (new Date()).getTime() - wxAuthUser.getRefreshTime().getTime();
  80. if ( millSecond + 5 * 60 * 1000 > wxAuthUser.getExpiresIn() * 1000 ) {//提前5分钟,就刷新accesstoken
  81. wxAuthService.refreshAccessToken(wxAuthUser);
  82. }
  83. PayResult prePayResult = payService.prePay(order, userIp, wxAuthUser.getOpenId());
  84. if ( prePayResult.isRequestSuccess() ) {
  85. if ( prePayResult.isTradeSuccess() ) {
  86. SortedMap<Object, Object> map = payService.fillPayParam4JS(prePayResult.getPrepay_id());
  87. return ResponseUtil.result(0, "OK", map);
  88. } else {
  89. LOGGER.info("PayController.prepay prePayResult=" + JSONObject.toJSONString(prePayResult));
  90. return ResponseUtil.result(1, prePayResult.getErr_code_des(), null);
  91. }
  92. }
  93. return ResponseUtil.result(1, "支付失败,请重试", order);
  94. } catch ( Exception e ) {
  95. LOGGER.error("OrderController.detail Error:userId=" + userId + ",ordrId=" + orderId, e);
  96. return ResponseUtil.result(1, "支付失败", null);
  97. }
  98. }
  99. /**
  100. * 微信支付 回调URL
  101. *
  102. * @param request
  103. * @param model
  104. * @param userId
  105. * @param orderId
  106. * @return
  107. */
  108. @RequestMapping(value = "/recall", method = RequestMethod.POST, produces = "application/json;charset=utf-8") @ResponseBody
  109. public String recall(HttpServletRequest request, HttpServletResponse response, Model model, @CookieValue("userId") Long userId,
  110. @RequestParam("orderId") Long orderId) {
  111. Orders order;
  112. try {
  113. LOGGER.info("PayController.recall : request=" + request.getQueryString() + "---" + request.getParameterMap());
  114. //TODO 判断返回值
  115. order = orderService.getById(userId, orderId);
  116. //TODO 判断订单状态,不冲突的情况下,进行修改
  117. //TODO 回执给微信,表示收到
  118. payService.paySuccess(request, response);
  119. } catch ( Exception e ) {
  120. LOGGER.error("OrderController.recall Error:userId=" + userId + ",ordrId=" + orderId, e);
  121. return ResponseUtil.result(1, "微信通知失败", null);
  122. }
  123. return ResponseUtil.result(0, "OK", order);
  124. }
  125. /**
  126. * js收到回调之后,通知后段,后段再去调用微信查询接口,更改订单状态
  127. *
  128. * @param model
  129. * @param userId
  130. * @param orderId
  131. * @return
  132. */
  133. @RequestMapping(value = "/jsNotify", method = RequestMethod.POST, produces = "application/json;charset=utf-8") @ResponseBody
  134. public String jsNotify(Model model, @CookieValue("userId") Long userId, @RequestParam("orderId") Long orderId) {
  135. Orders order;
  136. try {
  137. LOGGER.info("PayController.jsNotify : userId=" + userId + ",orderId=" + orderId);
  138. order = orderService.getById(userId, orderId);
  139. PayResult payResult;
  140. if ( order != null ) {
  141. payResult = payService.orderQuery(order);
  142. LOGGER.info(
  143. "PayController.jsNotify-orderQuery : userId=" + userId + ",orderId=" + orderId + ",payResult=" + JSONObject.toJSONString(payResult));
  144. if ( payResult.getOut_trade_no() != null && payResult.getOut_trade_no().equals(order.getViewId())) {
  145. //0=未支付,1=支付中,4=支付完成,5=支付失败,6=取消支付,7=转入退款
  146. if ( "SUCCESS".equals(payResult.getTrade_state()) ) {//支付成功
  147. if ( order.getPayStatus() < 4 && order.getStatus() < 4 ) {
  148. order.setPayStatus(4);
  149. order.setStatus(1);
  150. itemSkuService.reduceSku(order);//支付成功减少库存
  151. /*if(pword==null||pword.equals("")){
  152. ticketServcie.haveUsed(order.getId(),pword);//将券状态设置为已经使用
  153. }*/
  154. }
  155. } else if ( "REFUND".equals(payResult.getTrade_state()) ) {
  156. order.setPayStatus(7);
  157. } else if ( "NOTPAY".equals(payResult.getTrade_state()) ) {
  158. order.setPayStatus(0);
  159. } else if ( "CLOSED".equals(payResult.getTrade_state()) ) {
  160. order.setPayStatus(5);
  161. } else if ( "REVOKED".equals(payResult.getTrade_state()) ) {
  162. order.setPayStatus(6);
  163. } else if ( "USERPAYING".equals(payResult.getTrade_state()) ) {
  164. order.setPayStatus(1);
  165. } else if ( "PAYERROR".equals(payResult.getTrade_state()) ) {
  166. order.setPayStatus(5);
  167. }
  168. orderService.payOrder(order);
  169. }
  170. if ( order.getPayStatus() == 4 ) {
  171. return ResponseUtil.result(0, "支付成功", order);
  172. } else {
  173. return ResponseUtil.result(0, payResult.getTrade_state_desc(), order);
  174. }
  175. }
  176. //TODO 回执给微信,表示收到
  177. } catch ( Exception e ) {
  178. LOGGER.error("OrderController.jsNotify Error:userId=" + userId + ",ordrId=" + orderId, e);
  179. return ResponseUtil.result(1, "微信通知错误", null);
  180. }
  181. return ResponseUtil.result(1, "支付通知失败", null);
  182. }
  183. /**
  184. * js收到回调之后,通知后段,后段再去调用微信查询接口,更改订单状态
  185. *
  186. * @param model
  187. * @param userId
  188. * @param orderId
  189. * @return
  190. */
  191. @RequestMapping(value = "/notify/{orderId}", method = RequestMethod.GET)
  192. public String notify(Model model, @CookieValue("userId") Long userId, @PathVariable("orderId") Long orderId) {
  193. Orders order;
  194. try {
  195. LOGGER.info("PayController.notify : userId=" + userId + ",orderId=" + orderId);
  196. order = orderService.getById(userId, orderId);
  197. PayResult payResult;
  198. if ( order != null ) {
  199. payResult = payService.orderQuery(order);
  200. LOGGER.info(
  201. "PayController.notify-orderQuery : userId=" + userId + ",orderId=" + orderId + ",payResult=" + JSONObject.toJSONString(payResult));
  202. if ( payResult.getOut_trade_no() != null && payResult.getOut_trade_no().equals(order.getViewId())) {
  203. //0=未支付,1=支付中,4=支付完成,5=支付失败,6=取消支付,7=转入退款
  204. if ( "SUCCESS".equals(payResult.getTrade_state()) ) {//支付成功
  205. if ( order.getPayStatus() < 4 && order.getStatus() < 4 ) {
  206. order.setPayStatus(4);
  207. order.setStatus(1);
  208. itemSkuService.reduceSku(order);//支付成功减少库存
  209. /*if(pword==null||pword.equals("")){
  210. ticketServcie.haveUsed(order.getId(),pword);//将券状态设置为已经使用
  211. }*/
  212. }
  213. } else if ( "REFUND".equals(payResult.getTrade_state()) ) {
  214. order.setPayStatus(7);
  215. } else if ( "NOTPAY".equals(payResult.getTrade_state()) ) {
  216. order.setPayStatus(0);
  217. } else if ( "CLOSED".equals(payResult.getTrade_state()) ) {
  218. order.setPayStatus(5);
  219. } else if ( "REVOKED".equals(payResult.getTrade_state()) ) {
  220. order.setPayStatus(6);
  221. } else if ( "USERPAYING".equals(payResult.getTrade_state()) ) {
  222. order.setPayStatus(1);
  223. } else if ( "PAYERROR".equals(payResult.getTrade_state()) ) {
  224. order.setPayStatus(5);
  225. }
  226. orderService.payOrder(order);
  227. }
  228. if ( order.getPayStatus() == 4 ) {
  229. LOGGER.info("PayController.notify : order is OK" );
  230. } else {
  231. LOGGER.error( "PayController.notify: order is fail ");
  232. }
  233. }
  234. //TODO 回执给微信,表示收到
  235. } catch ( Exception e ) {
  236. LOGGER.error("OrderController.notify Error:userId=" + userId + ",ordrId=" + orderId, e);
  237. }
  238. return "redirect:/order/page";
  239. }
  240. @RequestMapping(value = "/confirm/{orderId}", method = RequestMethod.GET)
  241. public String confirm(Model model, @PathVariable Long orderId) {
  242. model.addAttribute("orderId", orderId);
  243. return "/order/pay_confirm";
  244. }
  245. @RequestMapping(value = "/order", method = RequestMethod.POST, produces = "application/json;charset=utf-8") @ResponseBody
  246. public String payOrder(Model model, @CookieValue("userId") Long userId, @RequestParam(value = "orderId", defaultValue = "0") Long orderId,@RequestParam(value = "source", defaultValue = "hshs") String source) {
  247. try {
  248. Orders order = orderService.getById(userId, orderId);
  249. if ( order != null ) {
  250. order.setStatus(1);
  251. order.setPayStatus(4);
  252. order.setPayType(PoetConstants.PAY_STATUS_WX_WEB);
  253. } else {
  254. return ResponseUtil.result(1, "支付订单错误,请重新下单", null);
  255. }
  256. int result = orderService.payOrder(order);
  257. if ( result > 0 ) {
  258. return ResponseUtil.result(0, "支付成功", order);
  259. }
  260. } catch ( Exception e ) {
  261. LOGGER.error("PayController.payOrder Error:userId=" + userId + ",orderId=" + orderId, e);
  262. return ResponseUtil.result(1, "支付订单失败", null);
  263. }
  264. return ResponseUtil.result(1, "支付订单失败,请重试", null);
  265. }
  266. /**
  267. * 支付页面<br/>
  268. * 请求本页面可以加上 ?showwxpaytitle=1 微信中会出现安全支付 副标题
  269. *
  270. * @param request
  271. * @param userId
  272. * @param orderId
  273. * @param model
  274. * @param errMsg
  275. * @return
  276. */
  277. @RequestMapping(value = "/order/{orderId}")
  278. public String pay(HttpServletRequest request, HttpServletResponse response,@CookieValue("userId") Long userId, @PathVariable Long orderId, Model model,
  279. @RequestParam(value = "errMsg", defaultValue = "") String errMsg) {
  280. OrderView orderView = null;
  281. try {
  282. Orders order = orderService.getById(userId, orderId);
  283. orderView = orderService.buildOrderViewByOrder(order);
  284. } catch ( Exception e ) {
  285. LOGGER.error("OrderController.detail Error:userId=" + userId + ",orderId=" + orderId, e);
  286. }
  287. model.addAttribute("errMsg", errMsg);
  288. model.addAttribute("order", orderView);
  289. boolean isWeixin = false;
  290. String ua = request.getHeader("user-agent");
  291. if(ua!=null&&ua.contains("MicroMessenger")){
  292. isWeixin = true;
  293. }
  294. model.addAttribute("isWeixin", isWeixin);
  295. return "order/pay";
  296. }
  297. }