package com.nju.edu.pay.controller.api; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayClient; import com.alipay.api.DefaultAlipayClient; import com.alipay.api.domain.AlipayTradePagePayModel; import com.alipay.api.domain.AlipayTradeRefundModel; import com.alipay.api.request.AlipayTradePagePayRequest; import com.alipay.api.request.AlipayTradeRefundRequest; import com.alipay.api.response.AlipayTradePagePayResponse; import com.alipay.api.response.AlipayTradeRefundResponse; import com.nju.edu.pay.configuration.AlipayProperties; import com.nju.edu.pay.controller.dto.PayModelDTO; import com.nju.edu.pay.data.entity.Order; import com.nju.edu.pay.data.entity.Trade; import com.nju.edu.pay.service.AlipayService; import com.nju.edu.pay.service.OrderService; import com.nju.edu.pay.service.TradeService; import com.nju.edu.pay.util.enums.OrderStatus; import com.nju.edu.pay.web.response.ErrorResponse; import com.nju.edu.pay.web.response.Response; import com.nju.edu.pay.web.response.SuccessResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Map; @Slf4j @RestController @RequestMapping("/api/alipay") public class AlipayController { private final AlipayProperties alipayProperties; private final AlipayService alipayService; private final OrderService orderService; private final TradeService tradeService; @Autowired public AlipayController(AlipayProperties alipayProperties, AlipayService alipayService, OrderService orderService, TradeService tradeService) { this.alipayProperties = alipayProperties; this.alipayService = alipayService; this.orderService = orderService; this.tradeService = tradeService; } @PostMapping("/pay") public Response pay(@RequestBody PayModelDTO payModelDTO) throws AlipayApiException, IOException { Order order=orderService.createOrder(payModelDTO.getUserId(),payModelDTO.getProductId(),payModelDTO.getPlatformType(),payModelDTO.getPrice()); if (order==null) return new ErrorResponse(500,"订单创建失败"); // 订单模型 String productCode = "FAST_INSTANT_TRADE_PAY"; AlipayTradePagePayModel model = new AlipayTradePagePayModel(); model.setOutTradeNo(order.getOutTradeNo().toString()); model.setSubject(payModelDTO.getSubject()); model.setTotalAmount(String.valueOf(order.getPrice())); model.setBody(payModelDTO.getSubject()+", 共"+payModelDTO.getPrice()+"元"); model.setProductCode(productCode); AlipayTradePagePayRequest pagePayRequest =new AlipayTradePagePayRequest(); pagePayRequest.setReturnUrl(payModelDTO.getReturnUrl()); pagePayRequest.setNotifyUrl(alipayProperties.getNotifyUrl()); pagePayRequest.setBizModel(model); AlipayClient alipayClient=new DefaultAlipayClient(alipayProperties.getGatewayUrl(),alipayProperties.getAppid(),alipayProperties.getAppPrivateKey(),alipayProperties.getFormate(),alipayProperties.getCharset(),alipayProperties.getAlipayPublicKey(),alipayProperties.getSignType()); // 调用SDK生成表单, 并直接将完整的表单html输出到页面 AlipayTradePagePayResponse alipayTradePagePayResponse=alipayClient.pageExecute(pagePayRequest); if (alipayTradePagePayResponse.isSuccess()){ return new SuccessResponse(alipayTradePagePayResponse.getBody()); }else { order.setStatus(OrderStatus.FAILED); orderService.updateOrder(order); return new ErrorResponse(500,"调用支付失败"); } } @RequestMapping("/notify") public String notify(HttpServletRequest request) throws AlipayApiException, UnsupportedEncodingException { // 一定要验签,防止黑客篡改参数 Map parameterMap = request.getParameterMap(); StringBuilder notifyBuild = new StringBuilder("/****************************** alipay notify ******************************/\n"); parameterMap.forEach((key, value) -> notifyBuild.append(key + "=" + value[0] + "\n") ); log.info(notifyBuild.toString()); boolean flag = alipayService.verifySign(request); if (flag) { /** * 需要严格按照如下描述校验通知数据的正确性 * * 商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号, * 并判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额), * 同时需要校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email), * * 上述有任何一个验证不通过,则表明本次通知是异常通知,务必忽略。 * 在上述验证通过后商户必须根据支付宝不同类型的业务通知,正确的进行不同的业务处理,并且过滤重复的通知结果数据。 * 在支付宝的业务通知中,只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时,支付宝才会认定为买家付款成功。 */ //交易状态 String tradeStatus = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8"); // 商户订单号 String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8"); //支付宝交易号 String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8"); //付款金额 String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8"); //商户ID String seller_id = new String(request.getParameter("seller_id").getBytes("ISO-8859-1"),"UTF-8"); Order order=orderService.retrieveOrder(Integer.parseInt(out_trade_no)); if (order==null) return "failed"; if (order.getPrice() == Double.parseDouble(total_amount)&& alipayProperties.getSellerId().equals(seller_id)) { tradeService.createTrade(Integer.parseInt(out_trade_no), trade_no); } if (tradeStatus.equals("TRADE_SUCCESS")||tradeStatus.equals("TRADE_FINISHED") ){ System.out.println("notify trade success called"); order.setStatus(OrderStatus.SUCCESS); orderService.updateOrder(order); return "success"; }else { order.setStatus(OrderStatus.FAILED); orderService.updateOrder(order); } } return "fail"; } @RequestMapping("/return") public String returnUrl(HttpServletRequest request) throws UnsupportedEncodingException { boolean verifyResult = alipayService.verifySign(request); if(verifyResult){ //验证成功 //请在这里加上商户的业务逻辑程序代码,如保存支付宝交易号 //商户订单号 String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8"); //支付宝交易号 String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8"); System.out.println("returnUrl called"); return "PaySuccess"; }else{ return "PayFail"; } } @PostMapping("/refund/{outTradeNo}") public Response refund(@PathVariable Integer outTradeNo) throws AlipayApiException { AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest(); Order order=orderService.retrieveOrder(outTradeNo); Trade trade=tradeService.retrieveTrade(outTradeNo); AlipayTradeRefundModel model=new AlipayTradeRefundModel(); // 商户订单号 model.setOutTradeNo(outTradeNo.toString()); //支付宝订单号 model.setTradeNo(String.valueOf(trade.getTradeNo())); // 退款金额 model.setRefundAmount(String.valueOf(order.getPrice())); // 退款原因 model.setRefundReason("无理由退款"); // 退款订单号(同一个订单可以分多次部分退款,当分多次时必传) // model.setOutRequestNo(UUID.randomUUID().toString()); alipayRequest.setBizModel(model); AlipayClient alipayClient=new DefaultAlipayClient(alipayProperties.getGatewayUrl(),alipayProperties.getAppid(),alipayProperties.getAppPrivateKey(),alipayProperties.getFormate(),alipayProperties.getCharset(),alipayProperties.getAlipayPublicKey(),alipayProperties.getSignType()); AlipayTradeRefundResponse alipayResponse = alipayClient.execute(alipayRequest); if (alipayResponse.isSuccess()) { order.setStatus(OrderStatus.REFUND); orderService.updateOrder(order); return new SuccessResponse(alipayResponse.getBody()); } return new ErrorResponse(500,"退款失败"); } }