AlipayController.java 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. package com.nju.edu.pay.controller.api;
  2. import com.alipay.api.AlipayApiException;
  3. import com.alipay.api.AlipayClient;
  4. import com.alipay.api.DefaultAlipayClient;
  5. import com.alipay.api.domain.AlipayTradePagePayModel;
  6. import com.alipay.api.domain.AlipayTradeRefundModel;
  7. import com.alipay.api.request.AlipayTradePagePayRequest;
  8. import com.alipay.api.request.AlipayTradeRefundRequest;
  9. import com.alipay.api.response.AlipayTradePagePayResponse;
  10. import com.alipay.api.response.AlipayTradeRefundResponse;
  11. import com.nju.edu.pay.configuration.AlipayProperties;
  12. import com.nju.edu.pay.controller.dto.PayModelDTO;
  13. import com.nju.edu.pay.data.entity.Order;
  14. import com.nju.edu.pay.data.entity.Trade;
  15. import com.nju.edu.pay.service.AlipayService;
  16. import com.nju.edu.pay.service.OrderService;
  17. import com.nju.edu.pay.service.TradeService;
  18. import com.nju.edu.pay.util.enums.OrderStatus;
  19. import com.nju.edu.pay.web.response.ErrorResponse;
  20. import com.nju.edu.pay.web.response.Response;
  21. import com.nju.edu.pay.web.response.SuccessResponse;
  22. import lombok.extern.slf4j.Slf4j;
  23. import org.springframework.beans.factory.annotation.Autowired;
  24. import org.springframework.web.bind.annotation.*;
  25. import javax.servlet.http.HttpServletRequest;
  26. import java.io.IOException;
  27. import java.io.UnsupportedEncodingException;
  28. import java.util.Map;
  29. @Slf4j
  30. @RestController
  31. @RequestMapping("/api/alipay")
  32. public class AlipayController {
  33. private final AlipayProperties alipayProperties;
  34. private final AlipayService alipayService;
  35. private final OrderService orderService;
  36. private final TradeService tradeService;
  37. @Autowired
  38. public AlipayController(AlipayProperties alipayProperties, AlipayService alipayService, OrderService orderService, TradeService tradeService) {
  39. this.alipayProperties = alipayProperties;
  40. this.alipayService = alipayService;
  41. this.orderService = orderService;
  42. this.tradeService = tradeService;
  43. }
  44. @PostMapping("/pay")
  45. public Response pay(@RequestBody PayModelDTO payModelDTO) throws AlipayApiException, IOException {
  46. Order order=orderService.createOrder(payModelDTO.getUserId(),payModelDTO.getProductId(),payModelDTO.getPlatformType(),payModelDTO.getPrice());
  47. if (order==null)
  48. return new ErrorResponse(500,"订单创建失败");
  49. // 订单模型
  50. String productCode = "FAST_INSTANT_TRADE_PAY";
  51. AlipayTradePagePayModel model = new AlipayTradePagePayModel();
  52. model.setOutTradeNo(order.getOutTradeNo().toString());
  53. model.setSubject(payModelDTO.getSubject());
  54. model.setTotalAmount(String.valueOf(order.getPrice()));
  55. model.setBody(payModelDTO.getSubject()+", 共"+payModelDTO.getPrice()+"元");
  56. model.setProductCode(productCode);
  57. AlipayTradePagePayRequest pagePayRequest =new AlipayTradePagePayRequest();
  58. pagePayRequest.setReturnUrl(payModelDTO.getReturnUrl());
  59. pagePayRequest.setNotifyUrl(alipayProperties.getNotifyUrl());
  60. pagePayRequest.setBizModel(model);
  61. AlipayClient alipayClient=new DefaultAlipayClient(alipayProperties.getGatewayUrl(),alipayProperties.getAppid(),alipayProperties.getAppPrivateKey(),alipayProperties.getFormate(),alipayProperties.getCharset(),alipayProperties.getAlipayPublicKey(),alipayProperties.getSignType());
  62. // 调用SDK生成表单, 并直接将完整的表单html输出到页面
  63. AlipayTradePagePayResponse alipayTradePagePayResponse=alipayClient.pageExecute(pagePayRequest);
  64. if (alipayTradePagePayResponse.isSuccess()){
  65. return new SuccessResponse(alipayTradePagePayResponse.getBody());
  66. }else {
  67. order.setStatus(OrderStatus.FAILED);
  68. orderService.updateOrder(order);
  69. return new ErrorResponse(500,"调用支付失败");
  70. }
  71. }
  72. @RequestMapping("/notify")
  73. public String notify(HttpServletRequest request) throws AlipayApiException, UnsupportedEncodingException {
  74. // 一定要验签,防止黑客篡改参数
  75. Map<String, String[]> parameterMap = request.getParameterMap();
  76. StringBuilder notifyBuild = new StringBuilder("/****************************** alipay notify ******************************/\n");
  77. parameterMap.forEach((key, value) -> notifyBuild.append(key + "=" + value[0] + "\n") );
  78. log.info(notifyBuild.toString());
  79. boolean flag = alipayService.verifySign(request);
  80. if (flag) {
  81. /**
  82. * 需要严格按照如下描述校验通知数据的正确性
  83. *
  84. * 商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
  85. * 并判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
  86. * 同时需要校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email),
  87. *
  88. * 上述有任何一个验证不通过,则表明本次通知是异常通知,务必忽略。
  89. * 在上述验证通过后商户必须根据支付宝不同类型的业务通知,正确的进行不同的业务处理,并且过滤重复的通知结果数据。
  90. * 在支付宝的业务通知中,只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时,支付宝才会认定为买家付款成功。
  91. */
  92. //交易状态
  93. String tradeStatus = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
  94. // 商户订单号
  95. String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
  96. //支付宝交易号
  97. String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
  98. //付款金额
  99. String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8");
  100. //商户ID
  101. String seller_id = new String(request.getParameter("seller_id").getBytes("ISO-8859-1"),"UTF-8");
  102. Order order=orderService.retrieveOrder(Integer.parseInt(out_trade_no));
  103. if (order==null)
  104. return "failed";
  105. if (order.getPrice() == Double.parseDouble(total_amount)&& alipayProperties.getSellerId().equals(seller_id)) {
  106. tradeService.createTrade(Integer.parseInt(out_trade_no), trade_no);
  107. }
  108. if (tradeStatus.equals("TRADE_SUCCESS")||tradeStatus.equals("TRADE_FINISHED") ){
  109. System.out.println("notify trade success called");
  110. order.setStatus(OrderStatus.SUCCESS);
  111. orderService.updateOrder(order);
  112. return "success";
  113. }else {
  114. order.setStatus(OrderStatus.FAILED);
  115. orderService.updateOrder(order);
  116. }
  117. }
  118. return "fail";
  119. }
  120. @RequestMapping("/return")
  121. public String returnUrl(HttpServletRequest request) throws UnsupportedEncodingException {
  122. boolean verifyResult = alipayService.verifySign(request);
  123. if(verifyResult){
  124. //验证成功
  125. //请在这里加上商户的业务逻辑程序代码,如保存支付宝交易号
  126. //商户订单号
  127. String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");
  128. //支付宝交易号
  129. String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
  130. System.out.println("returnUrl called");
  131. return "PaySuccess";
  132. }else{
  133. return "PayFail";
  134. }
  135. }
  136. @PostMapping("/refund/{outTradeNo}")
  137. public Response refund(@PathVariable Integer outTradeNo) throws AlipayApiException {
  138. AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();
  139. Order order=orderService.retrieveOrder(outTradeNo);
  140. Trade trade=tradeService.retrieveTrade(outTradeNo);
  141. AlipayTradeRefundModel model=new AlipayTradeRefundModel();
  142. // 商户订单号
  143. model.setOutTradeNo(outTradeNo.toString());
  144. //支付宝订单号
  145. model.setTradeNo(String.valueOf(trade.getTradeNo()));
  146. // 退款金额
  147. model.setRefundAmount(String.valueOf(order.getPrice()));
  148. // 退款原因
  149. model.setRefundReason("无理由退款");
  150. // 退款订单号(同一个订单可以分多次部分退款,当分多次时必传)
  151. // model.setOutRequestNo(UUID.randomUUID().toString());
  152. alipayRequest.setBizModel(model);
  153. AlipayClient alipayClient=new DefaultAlipayClient(alipayProperties.getGatewayUrl(),alipayProperties.getAppid(),alipayProperties.getAppPrivateKey(),alipayProperties.getFormate(),alipayProperties.getCharset(),alipayProperties.getAlipayPublicKey(),alipayProperties.getSignType());
  154. AlipayTradeRefundResponse alipayResponse = alipayClient.execute(alipayRequest);
  155. if (alipayResponse.isSuccess()) {
  156. order.setStatus(OrderStatus.REFUND);
  157. orderService.updateOrder(order);
  158. return new SuccessResponse(alipayResponse.getBody());
  159. }
  160. return new ErrorResponse(500,"退款失败");
  161. }
  162. }