微信支付-没有支付资质

This commit is contained in:
Bunny 2024-01-10 13:43:58 +08:00
parent d24c17e1a9
commit c6cae41822
10 changed files with 299 additions and 15 deletions

View File

@ -1,16 +1,15 @@
package com.sky.controller.user; package com.sky.controller.user;
import com.sky.dto.OrdersPaymentDTO;
import com.sky.dto.OrdersSubmitDTO; import com.sky.dto.OrdersSubmitDTO;
import com.sky.result.Result; import com.sky.result.Result;
import com.sky.service.OrderService; import com.sky.service.OrderService;
import com.sky.vo.OrderPaymentVO;
import com.sky.vo.OrderSubmitVO; import com.sky.vo.OrderSubmitVO;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -35,4 +34,19 @@ public class OrderController {
OrderSubmitVO orderSubmitVO = orderService.submitOrder(ordersSubmitDTO); OrderSubmitVO orderSubmitVO = orderService.submitOrder(ordersSubmitDTO);
return Result.success(orderSubmitVO); 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);
}
} }

View File

@ -0,0 +1,119 @@
package com.sky.controller.user;
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.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
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 {
@Resource
private OrderService orderService;
@Resource
private WeChatProperties weChatProperties;
/**
* 支付成功回调
*
* @param request HttpServletRequest
*/
@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 HttpServletRequest
* @return String
* @throws Exception 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 String
* @return String
* @throws Exception 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 HttpServletResponse
*/
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();
}
}

View File

@ -2,9 +2,25 @@ package com.sky.mapper;
import com.sky.entity.Orders; import com.sky.entity.Orders;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
@Mapper @Mapper
public interface OrderMapper { public interface OrderMapper {
// 向订单中插入1条数据 // 向订单中插入1条数据
void insert(Orders orders); void insert(Orders orders);
/**
* 根据订单号查询订单
*
* @param orderNumber
*/
@Select("select * from orders where number = #{orderNumber}")
Orders getByNumber(String orderNumber);
/**
* 修改订单信息
*
* @param orders
*/
void update(Orders orders);
} }

View File

@ -8,14 +8,24 @@ public interface UserMapper {
/** /**
* 根据用户id查询用户 * 根据用户id查询用户
* @param openid String *
* @param openid String
* @return User * @return User
*/ */
User getByOpenid(String openid); User getByOpenid(String openid);
/** /**
* 如果为新用户自动完成注册 * 如果为新用户自动完成注册
*
* @param user User * @param user User
*/ */
void insert(User user); void insert(User user);
/**
* 当前登录用户id
*
* @param userId Long
* @return User
*/
User getById(Long userId);
} }

View File

@ -1,6 +1,8 @@
package com.sky.service; package com.sky.service;
import com.sky.dto.OrdersPaymentDTO;
import com.sky.dto.OrdersSubmitDTO; import com.sky.dto.OrdersSubmitDTO;
import com.sky.vo.OrderPaymentVO;
import com.sky.vo.OrderSubmitVO; import com.sky.vo.OrderSubmitVO;
public interface OrderService { public interface OrderService {
@ -11,4 +13,19 @@ public interface OrderService {
* @return OrderSubmitVO * @return OrderSubmitVO
*/ */
OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO); OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO);
/**
* 订单支付
*
* @param ordersPaymentDTO ordersPaymentDTO
* @return OrderPaymentVO
*/
OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception;
/**
* 支付成功修改订单状态
*
* @param outTradeNo String
*/
void paySuccess(String outTradeNo);
} }

View File

@ -1,25 +1,25 @@
package com.sky.service.impl; package com.sky.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.sky.constant.MessageConstant; import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext; import com.sky.context.BaseContext;
import com.sky.dto.OrdersPaymentDTO;
import com.sky.dto.OrdersSubmitDTO; import com.sky.dto.OrdersSubmitDTO;
import com.sky.entity.AddressBook; import com.sky.entity.*;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.entity.ShoppingCart;
import com.sky.exception.AddressBookBusinessException; import com.sky.exception.AddressBookBusinessException;
import com.sky.exception.OrderBusinessException;
import com.sky.exception.ShoppingCartBusinessException; import com.sky.exception.ShoppingCartBusinessException;
import com.sky.mapper.AddressBookMapper; import com.sky.mapper.*;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.ShoppingCartMapper;
import com.sky.service.OrderService; import com.sky.service.OrderService;
import com.sky.utils.WeChatPayUtil;
import com.sky.vo.OrderPaymentVO;
import com.sky.vo.OrderSubmitVO; import com.sky.vo.OrderSubmitVO;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -34,6 +34,10 @@ public class OrderServiceImpl implements OrderService {
private AddressBookMapper addressBookMapper; private AddressBookMapper addressBookMapper;
@Resource @Resource
private ShoppingCartMapper shoppingCartMapper; private ShoppingCartMapper shoppingCartMapper;
@Resource
private UserMapper userMapper;
@Resource
private WeChatPayUtil weChatPayUtil;
/** /**
* 用户下单 * 用户下单
@ -90,6 +94,56 @@ public class OrderServiceImpl implements OrderService {
.orderNumber(orders.getNumber()) .orderNumber(orders.getNumber())
.orderAmount(orders.getAmount()).build(); .orderAmount(orders.getAmount()).build();
} }
/**
* 订单支付
*
* @param ordersPaymentDTO OrdersPaymentDTO
* @return OrderPaymentVO
*/
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("该订单已支付");
}
OrderPaymentVO vo = jsonObject.toJavaObject(OrderPaymentVO.class);
vo.setPackageStr(jsonObject.getString("package"));
return vo;
}
/**
* 支付成功修改订单状态
*
* @param outTradeNo String
*/
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);
}
} }

View File

@ -19,3 +19,10 @@ sky:
wechat: wechat:
appid: wx18e5556d7539757b appid: wx18e5556d7539757b
secret: ac06f1c49f90a2ed69f1a946d4981833 secret: ac06f1c49f90a2ed69f1a946d4981833
mchid: 18012062876
mch-serial-no: xcxzczx
private-key-file-path: sadsad
api-v3-key: dasdasd
we-chat-pay-cert-file-path: asdasds
notify-url: asdsada
refund-notify-url: asdasdsa

View File

@ -59,3 +59,10 @@ sky:
wechat: wechat:
appid: ${sky.wechat.appid} appid: ${sky.wechat.appid}
secret: ${sky.wechat.secret} secret: ${sky.wechat.secret}
mchid: ${sky.wechat.mchid}
mch-serial-no: ${sky.wechat.mchSerialNo}
private-key-file-path: ${sky.wechat.privateKeyFilePath}
api-v3-key: ${sky.wechat.apiV3Key}
we-chat-pay-cert-file-path: ${sky.wechat.weChatPayCertFilePath}
notify-url: ${sky.wechat.notifyUrl}
refund-notify-url: ${sky.wechat.refundNotifyUrl}

View File

@ -13,4 +13,37 @@
#{rejectionReason}, #{cancelTime}, #{estimatedDeliveryTime}, #{deliveryStatus}, #{deliveryTime}, #{rejectionReason}, #{cancelTime}, #{estimatedDeliveryTime}, #{deliveryStatus}, #{deliveryTime},
#{packAmount}, #{tablewareNumber}, #{tablewareStatus}); #{packAmount}, #{tablewareNumber}, #{tablewareStatus});
</insert> </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> </mapper>

View File

@ -14,4 +14,11 @@
from user from user
where openid = #{openid}; where openid = #{openid};
</select> </select>
<!-- 当前登录用户id -->
<select id="getById" resultType="com.sky.entity.User">
select *
from user
where id = #{id};
</select>
</mapper> </mapper>