From 1aca8cfc24cc7dbebc14ef6f1b4382626d2799d1 Mon Sep 17 00:00:00 2001 From: zhangsan <646228430@qq.com> Date: Wed, 7 Aug 2024 14:11:29 +0800 Subject: [PATCH] 8.7 --- .../com/sky/config/WebSecurityConfig.java | 21 +++- .../notify/PayNotifyController.java | 117 ++++++++++++++++++ .../sky/controller/user/OrderController.java | 24 +++- .../main/java/com/sky/mapper/OrderMapper.java | 13 ++ .../main/java/com/sky/mapper/UserMapper.java | 2 + .../java/com/sky/service/OrderService.java | 10 ++ .../sky/service/impl/OrderServiceImpl.java | 66 ++++++++-- .../src/main/resources/mapper/OrderMapper.xml | 30 +++++ 8 files changed, 270 insertions(+), 13 deletions(-) create mode 100644 sky-server/src/main/java/com/sky/controller/notify/PayNotifyController.java diff --git a/sky-server/src/main/java/com/sky/config/WebSecurityConfig.java b/sky-server/src/main/java/com/sky/config/WebSecurityConfig.java index ae7898b..a6aa253 100644 --- a/sky-server/src/main/java/com/sky/config/WebSecurityConfig.java +++ b/sky-server/src/main/java/com/sky/config/WebSecurityConfig.java @@ -22,4 +22,23 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { public BCryptPasswordEncoder encoder(){ return new BCryptPasswordEncoder(); } -} \ No newline at end of file +} +//@Configuration +//@EnableWebSecurity +//public class WebSecurityConfig extends WebSecurityConfigurerAdapter { +// @Override +// protected void configure(HttpSecurity http) throws Exception { +// http +// .authorizeRequests() +// .anyRequest().authenticated() // 需要认证才能访问 +// .and() +// .httpBasic() // 使用基本的HTTP认证 +// .and() +// .csrf().disable(); // 禁用CSRF保护,适用于API服务 +// } +// +// @Bean +// public BCryptPasswordEncoder encoder() { +// return new BCryptPasswordEncoder(); +// } +//} \ No newline at end of file diff --git a/sky-server/src/main/java/com/sky/controller/notify/PayNotifyController.java b/sky-server/src/main/java/com/sky/controller/notify/PayNotifyController.java new file mode 100644 index 0000000..df59cf4 --- /dev/null +++ b/sky-server/src/main/java/com/sky/controller/notify/PayNotifyController.java @@ -0,0 +1,117 @@ +package com.sky.controller.notify; + +import com.alibaba.druid.support.json.JSONUtils; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.sky.properties.WeChatProperties; +import com.sky.service.OrderService; +import com.wechat.pay.contrib.apache.httpclient.util.AesUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.http.entity.ContentType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedReader; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; + +/** + * 支付回调相关接口 + */ +@RestController +@RequestMapping("/notify") +@Slf4j +public class PayNotifyController { + @Autowired + private OrderService orderService; + @Autowired + private WeChatProperties weChatProperties; + + /** + * 支付成功回调 + * + * @param request + */ + @RequestMapping("/paySuccess") + public void paySuccessNotify(HttpServletRequest request, HttpServletResponse response) throws Exception { + //读取数据 + String body = readData(request); + log.info("支付成功回调:{}", body); + + //数据解密 + String plainText = decryptData(body); + log.info("解密后的文本:{}", plainText); + + JSONObject jsonObject = JSON.parseObject(plainText); + String outTradeNo = jsonObject.getString("out_trade_no");//商户平台订单号 + String transactionId = jsonObject.getString("transaction_id");//微信支付交易号 + + log.info("商户平台订单号:{}", outTradeNo); + log.info("微信支付交易号:{}", transactionId); + + //业务处理,修改订单状态、来单提醒 + orderService.paySuccess(outTradeNo); + + //给微信响应 + responseToWeixin(response); + } + + /** + * 读取数据 + * + * @param request + * @return + * @throws Exception + */ + private String readData(HttpServletRequest request) throws Exception { + BufferedReader reader = request.getReader(); + StringBuilder result = new StringBuilder(); + String line = null; + while ((line = reader.readLine()) != null) { + if (result.length() > 0) { + result.append("\n"); + } + result.append(line); + } + return result.toString(); + } + + /** + * 数据解密 + * + * @param body + * @return + * @throws Exception + */ + private String decryptData(String body) throws Exception { + JSONObject resultObject = JSON.parseObject(body); + JSONObject resource = resultObject.getJSONObject("resource"); + String ciphertext = resource.getString("ciphertext"); + String nonce = resource.getString("nonce"); + String associatedData = resource.getString("associated_data"); + + AesUtil aesUtil = new AesUtil(weChatProperties.getApiV3Key().getBytes(StandardCharsets.UTF_8)); + //密文解密 + String plainText = aesUtil.decryptToString(associatedData.getBytes(StandardCharsets.UTF_8), + nonce.getBytes(StandardCharsets.UTF_8), + ciphertext); + + return plainText; + } + + /** + * 给微信响应 + * @param response + */ + private void responseToWeixin(HttpServletResponse response) throws Exception{ + response.setStatus(200); + HashMap map = new HashMap<>(); + map.put("code", "SUCCESS"); + map.put("message", "SUCCESS"); + response.setHeader("Content-type", ContentType.APPLICATION_JSON.toString()); + response.getOutputStream().write(JSONUtils.toJSONString(map).getBytes(StandardCharsets.UTF_8)); + response.flushBuffer(); + } +} diff --git a/sky-server/src/main/java/com/sky/controller/user/OrderController.java b/sky-server/src/main/java/com/sky/controller/user/OrderController.java index 0a07a3b..164ec36 100644 --- a/sky-server/src/main/java/com/sky/controller/user/OrderController.java +++ b/sky-server/src/main/java/com/sky/controller/user/OrderController.java @@ -1,16 +1,16 @@ package com.sky.controller.user; +import com.sky.dto.OrdersPaymentDTO; import com.sky.dto.OrdersSubmitDTO; import com.sky.result.Result; import com.sky.service.OrderService; +import com.sky.vo.OrderPaymentVO; import com.sky.vo.OrderSubmitVO; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RestController @Api("用户订单相关接口") @@ -20,8 +20,24 @@ public class OrderController { @Autowired private OrderService orderService; @PostMapping("/submit") + @ApiOperation("提交订单") public Result submit(@RequestBody OrdersSubmitDTO ordersSubmitDTO){ OrderSubmitVO orderSubmitVO=orderService.submit(ordersSubmitDTO); return Result.success(orderSubmitVO); } + /** + * 订单支付 + * + * @param ordersPaymentDTO + * @return + */ + @PutMapping("/payment") + @ApiOperation("订单支付") + public Result payment(@RequestBody OrdersPaymentDTO ordersPaymentDTO) throws Exception { + log.info("订单支付:{}", ordersPaymentDTO); + OrderPaymentVO orderPaymentVO = orderService.payment(ordersPaymentDTO); + log.info("生成预支付交易单:{}", orderPaymentVO); + orderService.paySuccess(ordersPaymentDTO.getOrderNumber()); + return Result.success(orderPaymentVO); + } } diff --git a/sky-server/src/main/java/com/sky/mapper/OrderMapper.java b/sky-server/src/main/java/com/sky/mapper/OrderMapper.java index 012d959..d049ec8 100644 --- a/sky-server/src/main/java/com/sky/mapper/OrderMapper.java +++ b/sky-server/src/main/java/com/sky/mapper/OrderMapper.java @@ -2,8 +2,21 @@ package com.sky.mapper; import com.sky.entity.Orders; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; @Mapper public interface OrderMapper { void insert(Orders order); + /** + * 根据订单号查询订单 + * @param orderNumber + */ + @Select("select * from orders where number = #{orderNumber}") + Orders getByNumber(String orderNumber); + + /** + * 修改订单信息 + * @param orders + */ + void update(Orders orders); } diff --git a/sky-server/src/main/java/com/sky/mapper/UserMapper.java b/sky-server/src/main/java/com/sky/mapper/UserMapper.java index 47ca3c4..98b4517 100644 --- a/sky-server/src/main/java/com/sky/mapper/UserMapper.java +++ b/sky-server/src/main/java/com/sky/mapper/UserMapper.java @@ -14,4 +14,6 @@ public interface UserMapper { * @param user */ void insert(User user); + @Select("select * from user where id=#{userId}") + User getById(Long userId); } diff --git a/sky-server/src/main/java/com/sky/service/OrderService.java b/sky-server/src/main/java/com/sky/service/OrderService.java index 4f6a10b..b52bfe7 100644 --- a/sky-server/src/main/java/com/sky/service/OrderService.java +++ b/sky-server/src/main/java/com/sky/service/OrderService.java @@ -1,8 +1,18 @@ package com.sky.service; +import com.sky.dto.OrdersPaymentDTO; import com.sky.dto.OrdersSubmitDTO; +import com.sky.vo.OrderPaymentVO; import com.sky.vo.OrderSubmitVO; public interface OrderService { OrderSubmitVO submit(OrdersSubmitDTO ordersSubmitDTO); + + OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception; + + /** + * 支付成功,修改订单状态 + * @param outTradeNo + */ + void paySuccess(String outTradeNo); } diff --git a/sky-server/src/main/java/com/sky/service/impl/OrderServiceImpl.java b/sky-server/src/main/java/com/sky/service/impl/OrderServiceImpl.java index 3e234cb..5cdcaed 100644 --- a/sky-server/src/main/java/com/sky/service/impl/OrderServiceImpl.java +++ b/sky-server/src/main/java/com/sky/service/impl/OrderServiceImpl.java @@ -1,25 +1,25 @@ package com.sky.service.impl; +import com.alibaba.fastjson.JSONObject; import com.sky.constant.MessageConstant; import com.sky.context.BaseContext; +import com.sky.dto.OrdersPaymentDTO; import com.sky.dto.OrdersSubmitDTO; -import com.sky.entity.AddressBook; -import com.sky.entity.OrderDetail; -import com.sky.entity.Orders; -import com.sky.entity.ShoppingCart; +import com.sky.entity.*; import com.sky.exception.AddressBookBusinessException; +import com.sky.exception.OrderBusinessException; import com.sky.exception.ShoppingCartBusinessException; -import com.sky.mapper.AddressBookMapper; -import com.sky.mapper.OrderDetailMapper; -import com.sky.mapper.OrderMapper; -import com.sky.mapper.ShoppingCartMapper; +import com.sky.mapper.*; import com.sky.service.OrderService; +import com.sky.utils.WeChatPayUtil; +import com.sky.vo.OrderPaymentVO; import com.sky.vo.OrderSubmitVO; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -34,6 +34,10 @@ public class OrderServiceImpl implements OrderService { private OrderMapper orderMapper; @Autowired private OrderDetailMapper orderDetailMapper; + @Autowired + private WeChatPayUtil weChatPayUtil; + @Autowired + private UserMapper userMapper; @Override @Transactional public OrderSubmitVO submit(OrdersSubmitDTO ordersSubmitDTO) { @@ -87,4 +91,50 @@ public class OrderServiceImpl implements OrderService { return orderSubmitVO; } + + @Override + public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception { + // 当前登录用户id + Long userId = BaseContext.getCurrentId(); + User user = userMapper.getById(userId); + + //调用微信支付接口,生成预支付交易单 + //取消调用微信支付 +// JSONObject jsonObject = weChatPayUtil.pay( +// ordersPaymentDTO.getOrderNumber(), //商户订单号 +// new BigDecimal(0.01), //支付金额,单位 元 +// "苍穹外卖订单", //商品描述 +// user.getOpenid() //微信用户的openid +// ); + JSONObject jsonObject=new JSONObject(); + + if (jsonObject.getString("code") != null && jsonObject.getString("code").equals("ORDERPAID")) { + throw new OrderBusinessException("该订单已支付"); + } + + OrderPaymentVO vo = jsonObject.toJavaObject(OrderPaymentVO.class); + vo.setPackageStr(jsonObject.getString("package")); + + return vo; + } + /** + * 支付成功,修改订单状态 + * + * @param outTradeNo + */ + public void paySuccess(String outTradeNo) { + + // 根据订单号查询订单 + Orders ordersDB = orderMapper.getByNumber(outTradeNo); + + // 根据订单id更新订单的状态、支付方式、支付状态、结账时间 + Orders orders = Orders.builder() + .id(ordersDB.getId()) + .status(Orders.TO_BE_CONFIRMED) + .payStatus(Orders.PAID) + .checkoutTime(LocalDateTime.now()) + .build(); + + orderMapper.update(orders); + } } diff --git a/sky-server/src/main/resources/mapper/OrderMapper.xml b/sky-server/src/main/resources/mapper/OrderMapper.xml index 818b7f7..5c820a5 100644 --- a/sky-server/src/main/resources/mapper/OrderMapper.xml +++ b/sky-server/src/main/resources/mapper/OrderMapper.xml @@ -12,4 +12,34 @@ #{payStatus}, #{amount}, #{remark}, #{phone}, #{address}, #{consignee}, #{estimatedDeliveryTime}, #{deliveryStatus}, #{packAmount}, #{tablewareNumber}, #{tablewareStatus}) + + update orders + + + cancel_reason=#{cancelReason}, + + + rejection_reason=#{rejectionReason}, + + + cancel_time=#{cancelTime}, + + + pay_status=#{payStatus}, + + + pay_method=#{payMethod}, + + + checkout_time=#{checkoutTime}, + + + status = #{status}, + + + delivery_time = #{deliveryTime} + + + where id = #{id} + \ No newline at end of file