订单支付功能代码
This commit is contained in:
@@ -21,6 +21,7 @@ import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.file.Files;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Signature;
|
||||
import java.security.cert.X509Certificate;
|
||||
@@ -188,7 +189,7 @@ public class WeChatPayUtil {
|
||||
byte[] message = signMessage.getBytes();
|
||||
|
||||
Signature signature = Signature.getInstance("SHA256withRSA");
|
||||
signature.initSign(PemUtil.loadPrivateKey(new FileInputStream(new File(weChatProperties.getPrivateKeyFilePath()))));
|
||||
signature.initSign(PemUtil.loadPrivateKey(Files.newInputStream(new File(weChatProperties.getPrivateKeyFilePath()).toPath())));
|
||||
signature.update(message);
|
||||
String packageSign = Base64.getEncoder().encodeToString(signature.sign());
|
||||
|
||||
|
||||
@@ -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<Object, Object> 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();
|
||||
}
|
||||
}
|
||||
@@ -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("userOrderController")
|
||||
@RequestMapping("/user/order")
|
||||
@@ -22,9 +22,24 @@ public class OrderController {
|
||||
private OrderService orderService;
|
||||
|
||||
@PostMapping("/submit")
|
||||
public Result<OrderSubmitVO> submit(@RequestBody OrdersSubmitDTO ordersSubmitDTO) {
|
||||
public Result<OrderSubmitVO> submit(@RequestBody OrdersSubmitDTO ordersSubmitDTO) {
|
||||
log.info("order submit: {}", ordersSubmitDTO);
|
||||
OrderSubmitVO orderSubmitVO = orderService.submitOrder(ordersSubmitDTO);
|
||||
return Result.success(orderSubmitVO);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单支付
|
||||
*
|
||||
* @param ordersPaymentDTO
|
||||
* @return
|
||||
*/
|
||||
@PutMapping("/payment")
|
||||
@ApiOperation("订单支付")
|
||||
public Result<OrderPaymentVO> payment(@RequestBody OrdersPaymentDTO ordersPaymentDTO) throws Exception {
|
||||
log.info("订单支付:{}", ordersPaymentDTO);
|
||||
OrderPaymentVO orderPaymentVO = orderService.payment(ordersPaymentDTO);
|
||||
log.info("生成预支付交易单:{}", orderPaymentVO);
|
||||
return Result.success(orderPaymentVO);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,31 @@ package com.sky.mapper;
|
||||
|
||||
import com.sky.entity.Orders;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Mapper
|
||||
public interface OrderMapper {
|
||||
|
||||
void insert(Orders orders);
|
||||
|
||||
/**
|
||||
* 根据订单号查询订单
|
||||
*
|
||||
* @param orderNumber
|
||||
*/
|
||||
@Select("select * from orders where number = #{orderNumber}")
|
||||
Orders getByNumber(String orderNumber);
|
||||
|
||||
/**
|
||||
* 修改订单信息
|
||||
*
|
||||
* @param orders
|
||||
*/
|
||||
void update(Orders orders);
|
||||
|
||||
@Update("update orders set status = #{orderStatus},pay_status = #{orderPaidStatus} ,checkout_time = #{check_out_time} where id = #{id}")
|
||||
void updateStatus(Integer orderStatus, Integer orderPaidStatus, LocalDateTime check_out_time, Long id);
|
||||
}
|
||||
|
||||
@@ -20,4 +20,7 @@ public interface UserMapper {
|
||||
* @param user
|
||||
*/
|
||||
void insert(User user);
|
||||
|
||||
@Select("select * from sky_take_out.user where id = #{userId}")
|
||||
User getById(Long userId);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.sky.service;
|
||||
|
||||
import com.sky.dto.OrdersPaymentDTO;
|
||||
import com.sky.dto.OrdersSubmitDTO;
|
||||
import com.sky.vo.OrderPaymentVO;
|
||||
import com.sky.vo.OrderSubmitVO;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -13,4 +15,18 @@ public interface OrderService {
|
||||
* @return
|
||||
*/
|
||||
OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO);
|
||||
|
||||
/**
|
||||
* 订单支付
|
||||
* @param ordersPaymentDTO
|
||||
* @return
|
||||
*/
|
||||
OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception;
|
||||
|
||||
/**
|
||||
* 支付成功,修改订单状态
|
||||
* @param outTradeNo
|
||||
*/
|
||||
void paySuccess(String outTradeNo);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
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 lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
@@ -21,6 +20,7 @@ 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;
|
||||
@@ -37,6 +37,10 @@ public class OrderServiceImpl implements OrderService {
|
||||
private ShoppingCartMapper shoppingCartMapper;
|
||||
@Autowired
|
||||
private OrderDetailMapper orderDetailMapper;
|
||||
@Autowired
|
||||
private UserMapper userMapper;
|
||||
@Autowired
|
||||
private WeChatPayUtil weChatPayUtil;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@@ -90,4 +94,74 @@ public class OrderServiceImpl implements OrderService {
|
||||
.orderAmount(orders.getAmount())
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单支付
|
||||
*
|
||||
* @param ordersPaymentDTO
|
||||
* @return
|
||||
*/
|
||||
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
|
||||
);
|
||||
|
||||
if (jsonObject.getString("code") != null && jsonObject.getString("code").equals("ORDERPAID")) {
|
||||
throw new OrderBusinessException("该订单已支付");
|
||||
}*/
|
||||
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("code","ORDERPAID");
|
||||
|
||||
OrderPaymentVO vo = jsonObject.toJavaObject(OrderPaymentVO.class);
|
||||
vo.setPackageStr(jsonObject.getString("package"));
|
||||
|
||||
//为替代微信支付成功后的数据库订单状态更新,多定义一个方法进行修改
|
||||
|
||||
Integer OrderPaidStatus = Orders.PAID; //支付状态,已支付
|
||||
|
||||
Integer OrderStatus = Orders.TO_BE_CONFIRMED; //订单状态,待接单
|
||||
|
||||
|
||||
//发现没有将支付时间 check_out属性赋值,所以在这里更新
|
||||
|
||||
LocalDateTime check_out_time = LocalDateTime.now();
|
||||
|
||||
|
||||
Long orderId = orderMapper.getByNumber(ordersPaymentDTO.getOrderNumber()).getId();
|
||||
orderMapper.updateStatus(OrderStatus, OrderPaidStatus, check_out_time, orderId);
|
||||
|
||||
return new OrderPaymentVO();
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付成功,修改订单状态
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,3 +36,10 @@ spring.servlet.multipart.max-request-size=${spring.servlet.multipart.max-request
|
||||
|
||||
sky.wechat.appid=${sky.wechat.appid}
|
||||
sky.wechat.secret=${sky.wechat.secret}
|
||||
sky.wechat.mchid=${sky.wechat.mchid}
|
||||
sky.wechat.mch-serial-no=${sky.wechat.mch-serial-no}
|
||||
sky.wechat.private-key-file-path=${sky.wechat.private-key-file-path}
|
||||
sky.wechat.api-v3-key=${sky.wechat.api-v3-key}
|
||||
sky.wechat.we-chat-pay-cert-file-path=${sky.wechat.we-chat-pay-cert-file-path}
|
||||
sky.wechat.notify-url=${sky.wechat.notify-url}
|
||||
sky.wechat.refund-notify-url=${sky.wechat.refund-notify-url}
|
||||
@@ -14,4 +14,34 @@
|
||||
#{rejectionReason}, #{cancelTime}, #{estimatedDeliveryTime}, #{deliveryStatus}, #{deliveryTime},
|
||||
#{packAmount}, #{tablewareNumber}, #{tablewareStatus})
|
||||
</insert>
|
||||
<update id="update" parameterType="com.sky.entity.Orders">
|
||||
update orders
|
||||
<set>
|
||||
<if test="cancelReason != null and cancelReason!='' ">
|
||||
cancel_reason=#{cancelReason},
|
||||
</if>
|
||||
<if test="rejectionReason != null and rejectionReason!='' ">
|
||||
rejection_reason=#{rejectionReason},
|
||||
</if>
|
||||
<if test="cancelTime != null">
|
||||
cancel_time=#{cancelTime},
|
||||
</if>
|
||||
<if test="payStatus != null">
|
||||
pay_status=#{payStatus},
|
||||
</if>
|
||||
<if test="payMethod != null">
|
||||
pay_method=#{payMethod},
|
||||
</if>
|
||||
<if test="checkoutTime != null">
|
||||
checkout_time=#{checkoutTime},
|
||||
</if>
|
||||
<if test="status != null">
|
||||
status = #{status},
|
||||
</if>
|
||||
<if test="deliveryTime != null">
|
||||
delivery_time = #{deliveryTime}
|
||||
</if>
|
||||
</set>
|
||||
where id = #{id}
|
||||
</update>
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user