微信支付-没有支付资质
This commit is contained in:
parent
d24c17e1a9
commit
c6cae41822
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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}
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue