微信支付宝退款
This commit is contained in:
@@ -58,6 +58,7 @@ public class ShiroConfig {
|
|||||||
filterMap.put("book/task/list","anon"); // 网站接口
|
filterMap.put("book/task/list","anon"); // 网站接口
|
||||||
filterMap.put("/pay/aliPay/notify","anon"); // 支付宝回调接口
|
filterMap.put("/pay/aliPay/notify","anon"); // 支付宝回调接口
|
||||||
filterMap.put("/pay/payNotify","anon"); // 微信回调接口
|
filterMap.put("/pay/payNotify","anon"); // 微信回调接口
|
||||||
|
filterMap.put("/pay/refundNotify","anon"); // 微信退款回调接口
|
||||||
filterMap.put("/weChat/**","anon");
|
filterMap.put("/weChat/**","anon");
|
||||||
filterMap.put("/book/baseArea/getAllBaseArea","anon");//登录前获取全部区域
|
filterMap.put("/book/baseArea/getAllBaseArea","anon");//登录前获取全部区域
|
||||||
// filterMap.put("/book/bookchaptercontent/**","anon");
|
// filterMap.put("/book/bookchaptercontent/**","anon");
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ public class OrderCancelConsumer {
|
|||||||
shopProduct.setProductStock(shopProduct.getProductStock()+b.getQuantity());
|
shopProduct.setProductStock(shopProduct.getProductStock()+b.getQuantity());
|
||||||
shopProductDao.updateById(shopProduct);
|
shopProductDao.updateById(shopProduct);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
buyOrderService.updateById(buyOrder);
|
buyOrderService.updateById(buyOrder);
|
||||||
|
buyOrderService.removeById(buyOrder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,7 +102,8 @@ public class AliPayUtil {
|
|||||||
// 退款原因
|
// 退款原因
|
||||||
model.setRefundReason(reFundDTO.getRefundReason());
|
model.setRefundReason(reFundDTO.getRefundReason());
|
||||||
}
|
}
|
||||||
model.setOutRequestNo(UUID.randomUUID().toString().substring(0, 6));
|
//退款请求号。标识一次退款请求,需要保证在交易号下唯一,如需部分退款,则此参数必传。
|
||||||
|
model.setOutRequestNo(reFundDTO.getOutRequestNo());
|
||||||
request.setBizModel(model);
|
request.setBizModel(model);
|
||||||
AlipayTradeRefundResponse response = null;
|
AlipayTradeRefundResponse response = null;
|
||||||
|
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ public class AliPayController {
|
|||||||
* 支付宝退款
|
* 支付宝退款
|
||||||
*/
|
*/
|
||||||
@RequestMapping("/refund")
|
@RequestMapping("/refund")
|
||||||
public R refund(@RequestBody ReFundDTO reFundDTO) {
|
public R refund(@RequestBody Map<String,Object> params) {
|
||||||
String refund = aliPayService.refund(reFundDTO);
|
String refund = aliPayService.refund(params);
|
||||||
return R.ok().put("msg",refund);
|
return R.ok().put("msg",refund);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,4 +35,9 @@ public class ReFundDTO {
|
|||||||
*/
|
*/
|
||||||
private String customerId;
|
private String customerId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款请求号 标识一次退款请求,需要保证在交易号下唯一,如需部分退款,则此参数必传。
|
||||||
|
*/
|
||||||
|
private String outRequestNo;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package com.peanut.modules.pay.alipay.service;
|
|||||||
import com.peanut.modules.pay.alipay.dto.AlipayDTO;
|
import com.peanut.modules.pay.alipay.dto.AlipayDTO;
|
||||||
import com.peanut.modules.pay.alipay.dto.ReFundDTO;
|
import com.peanut.modules.pay.alipay.dto.ReFundDTO;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
public interface AliPayService {
|
public interface AliPayService {
|
||||||
@@ -26,10 +27,8 @@ public interface AliPayService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付宝退款
|
* 支付宝退款
|
||||||
* @param reFundDTO
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
String refund(ReFundDTO reFundDTO);
|
String refund(Map<String,Object> params);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import com.alibaba.fastjson.JSONObject;
|
|||||||
import com.alipay.api.internal.util.AlipaySignature;
|
import com.alipay.api.internal.util.AlipaySignature;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||||
import com.peanut.common.utils.CopyUtils;
|
import com.peanut.common.utils.CopyUtils;
|
||||||
import com.peanut.common.utils.OrderUtils;
|
import com.peanut.common.utils.OrderUtils;
|
||||||
import com.peanut.modules.book.dao.BuyOrderProductDao;
|
import com.peanut.modules.book.dao.BuyOrderProductDao;
|
||||||
@@ -18,6 +19,8 @@ import com.peanut.modules.pay.alipay.config.AliPayUtil;
|
|||||||
import com.peanut.modules.pay.alipay.dto.AlipayDTO;
|
import com.peanut.modules.pay.alipay.dto.AlipayDTO;
|
||||||
import com.peanut.modules.pay.alipay.dto.ReFundDTO;
|
import com.peanut.modules.pay.alipay.dto.ReFundDTO;
|
||||||
import com.peanut.modules.pay.alipay.service.AliPayService;
|
import com.peanut.modules.pay.alipay.service.AliPayService;
|
||||||
|
import com.peanut.modules.pay.refund.entity.PayRefundOrder;
|
||||||
|
import com.peanut.modules.pay.refund.service.PayRefundOrderService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -54,6 +57,8 @@ public class AliPayServiceImpl implements AliPayService {
|
|||||||
private ShopProductBookDao shopProductBookDao;
|
private ShopProductBookDao shopProductBookDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserEbookBuyDao userEbookBuyDao;
|
private UserEbookBuyDao userEbookBuyDao;
|
||||||
|
@Autowired
|
||||||
|
private PayRefundOrderService refundOrderService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String pay(AlipayDTO payDto) {
|
public String pay(AlipayDTO payDto) {
|
||||||
@@ -248,8 +253,20 @@ public class AliPayServiceImpl implements AliPayService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String refund(ReFundDTO reFundDTO) {
|
@Transactional
|
||||||
|
public String refund(Map<String,Object> params) {
|
||||||
log.info(">>>>>>>>>>App请求支付宝退款接口");
|
log.info(">>>>>>>>>>App请求支付宝退款接口");
|
||||||
|
LambdaQueryWrapper<PayZfbOrderEntity> wrapper = new LambdaQueryWrapper();
|
||||||
|
wrapper.eq(PayZfbOrderEntity::getRelevanceoid,params.get("orderSn").toString());
|
||||||
|
PayZfbOrderEntity payZfbOrder = payZfbOrderService.getOne(wrapper);
|
||||||
|
ReFundDTO reFundDTO = new ReFundDTO();
|
||||||
|
reFundDTO.setOutTrandeNo(payZfbOrder.getOutTradeNo());
|
||||||
|
reFundDTO.setTradeNo(payZfbOrder.getTradeNo());
|
||||||
|
reFundDTO.setCustomerId(payZfbOrder.getCustomerid());
|
||||||
|
reFundDTO.setRefundReason(params.get("reason").toString());
|
||||||
|
reFundDTO.setRefundAmount(new BigDecimal(params.get("refundFee").toString()));
|
||||||
|
// reFundDTO.setOutRequestNo(params.get("outRequestNo").toString());
|
||||||
|
reFundDTO.setOutRequestNo(UUID.randomUUID().toString());
|
||||||
Map<String, Object> map = aliPayUtil.aliPayRefund(reFundDTO);
|
Map<String, Object> map = aliPayUtil.aliPayRefund(reFundDTO);
|
||||||
Object obj = map.get("msg");
|
Object obj = map.get("msg");
|
||||||
String resJson = obj.toString();
|
String resJson = obj.toString();
|
||||||
@@ -260,23 +277,26 @@ public class AliPayServiceImpl implements AliPayService {
|
|||||||
"Y".equals(((Map)res.get("alipay_trade_refund_response")).get("fund_change"))){
|
"Y".equals(((Map)res.get("alipay_trade_refund_response")).get("fund_change"))){
|
||||||
log.info(">>>>>>>>>>>支付宝退款成功!<<<<<<<<<<<<<");
|
log.info(">>>>>>>>>>>支付宝退款成功!<<<<<<<<<<<<<");
|
||||||
//表操作
|
//表操作
|
||||||
|
MPJLambdaWrapper<BuyOrder> w = new MPJLambdaWrapper();
|
||||||
|
w.leftJoin(PayZfbOrderEntity.class,PayZfbOrderEntity::getRelevanceoid, BuyOrder::getOrderSn);
|
||||||
|
w.eq("trade_no",((Map)res.get("alipay_trade_refund_response")).get("trade_no"));
|
||||||
|
BuyOrder order = buyOrderService.getOne(w);
|
||||||
|
PayRefundOrder refund = new PayRefundOrder();
|
||||||
|
refund.setPayType("2");
|
||||||
|
refund.setOrderId(order.getOrderId());
|
||||||
|
refund.setTradeNo(((Map)res.get("alipay_trade_refund_response")).get("trade_no").toString());
|
||||||
|
refund.setOutTradeNo(((Map)res.get("alipay_trade_refund_response")).get("out_trade_no").toString());
|
||||||
|
refund.setRefundFee(((Map)res.get("alipay_trade_refund_response")).get("refund_fee").toString());
|
||||||
|
refundOrderService.save(refund);
|
||||||
|
refundOrderService.businessOpt(order);
|
||||||
}
|
}
|
||||||
return resJson;
|
return resJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO 更新订单状态
|
//TODO 更新订单状态
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//TODO 更新用户优惠券状态
|
//TODO 更新用户优惠券状态
|
||||||
|
|
||||||
|
|
||||||
//TODO 推送一路健康优惠券
|
//TODO 推送一路健康优惠券
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.peanut.modules.pay.refund.controller;
|
||||||
|
|
||||||
|
import com.peanut.common.utils.R;
|
||||||
|
import com.peanut.modules.pay.refund.service.PayRefundOrderService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/refund")
|
||||||
|
@Slf4j
|
||||||
|
public class RefundController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PayRefundOrderService refundOrderService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 花生币退款
|
||||||
|
*/
|
||||||
|
@RequestMapping("/refundPeanutCoin")
|
||||||
|
public R pay(@RequestBody Map<String,Object> map) {
|
||||||
|
return refundOrderService.refundPeanutCoin(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.peanut.modules.pay.refund.dao;
|
||||||
|
|
||||||
|
import com.github.yulichang.base.MPJBaseMapper;
|
||||||
|
import com.peanut.modules.pay.refund.entity.PayRefundOrder;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface PayRefundOrderDao extends MPJBaseMapper<PayRefundOrder> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.peanut.modules.pay.refund.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款信息
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("pay_refund_order")
|
||||||
|
public class PayRefundOrder implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
|
||||||
|
@TableId
|
||||||
|
private Integer refundId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付方式 1微信,2支付宝,3虚拟币
|
||||||
|
*/
|
||||||
|
private String payType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BuyOrder
|
||||||
|
*/
|
||||||
|
private Integer orderId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信支付宝订单号
|
||||||
|
*/
|
||||||
|
private String tradeNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商户订单号
|
||||||
|
*/
|
||||||
|
private String outTradeNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款总金额
|
||||||
|
*/
|
||||||
|
private String refundFee;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@TableField(fill = FieldFill.INSERT)//创建注解
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.peanut.modules.pay.refund.service;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.peanut.common.utils.R;
|
||||||
|
import com.peanut.modules.book.entity.BuyOrder;
|
||||||
|
import com.peanut.modules.pay.refund.entity.PayRefundOrder;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface PayRefundOrderService extends IService<PayRefundOrder> {
|
||||||
|
|
||||||
|
R refundPeanutCoin(Map<String,Object> map);
|
||||||
|
|
||||||
|
void businessOpt(BuyOrder order);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,190 @@
|
|||||||
|
package com.peanut.modules.pay.refund.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||||
|
import com.peanut.common.utils.R;
|
||||||
|
import com.peanut.modules.book.entity.*;
|
||||||
|
import com.peanut.modules.book.service.*;
|
||||||
|
import com.peanut.modules.pay.refund.dao.PayRefundOrderDao;
|
||||||
|
import com.peanut.modules.pay.refund.entity.PayRefundOrder;
|
||||||
|
import com.peanut.modules.pay.refund.service.PayRefundOrderService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class PayRefundOrderServiceImpl extends ServiceImpl<PayRefundOrderDao, PayRefundOrder> implements PayRefundOrderService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BuyOrderService buyOrderService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CouponHistoryService couponHistoryService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BuyOrderProductService buyOrderProductService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ShopProductService shopProductService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserEbookBuyService userEbookBuyService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MyUserService userService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PayRefundOrderService refundOrderService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TransactionDetailsService transactionDetailsService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public R refundPeanutCoin(Map<String,Object> map) {
|
||||||
|
log.info(">>>>>>>>>>>花生币退款<<<<<<<<<<<<<");
|
||||||
|
MPJLambdaWrapper<BuyOrder> w = new MPJLambdaWrapper();
|
||||||
|
w.eq("order_id",map.get("orderId"));
|
||||||
|
BuyOrder order = buyOrderService.getOne(w);
|
||||||
|
//退款详细
|
||||||
|
PayRefundOrder refund = new PayRefundOrder();
|
||||||
|
refund.setPayType("3");
|
||||||
|
refund.setOrderId(order.getOrderId());
|
||||||
|
refund.setRefundFee(map.get("refundFee").toString());
|
||||||
|
refundOrderService.save(refund);
|
||||||
|
//权限回退
|
||||||
|
refundOrderService.businessOpt(order);
|
||||||
|
//修改用户花生币
|
||||||
|
MyUserEntity byId = userService.getById(order.getUserId());
|
||||||
|
int i = byId.getPeanutCoin().intValue() + Integer.valueOf(map.get("refundFee").toString());
|
||||||
|
byId.setPeanutCoin(new BigDecimal(i));
|
||||||
|
userService.updateById(byId);
|
||||||
|
//插入花生比交易明细
|
||||||
|
TransactionDetailsEntity transactionDetailsEntity = new TransactionDetailsEntity();
|
||||||
|
transactionDetailsEntity.setUserId(order.getUserId());
|
||||||
|
transactionDetailsEntity.setOrderType("退款");
|
||||||
|
transactionDetailsEntity.setTel(byId.getTel());
|
||||||
|
transactionDetailsEntity.setUserName(byId.getNickname());
|
||||||
|
transactionDetailsEntity.setNote(map.get("note").toString());
|
||||||
|
transactionDetailsEntity.setChangeAmount(new BigDecimal(map.get("refundFee").toString()));
|
||||||
|
transactionDetailsEntity.setRemark("退款");
|
||||||
|
BigDecimal balance = new BigDecimal(i);
|
||||||
|
transactionDetailsEntity.setUserBalance(balance);
|
||||||
|
transactionDetailsService.save(transactionDetailsEntity);
|
||||||
|
log.info(">>>>>>>>>>>花生币退款成功<<<<<<<<<<<<<");
|
||||||
|
return R.ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void businessOpt(BuyOrder order) {
|
||||||
|
//优惠卷回滚
|
||||||
|
if (order.getCouponId() != null) {
|
||||||
|
Integer couponId = order.getCouponId();
|
||||||
|
CouponHistoryEntity couponHistory = couponHistoryService.getById(couponId);
|
||||||
|
couponHistory.setUseStatus(0);
|
||||||
|
couponHistoryService.updateById(couponHistory);
|
||||||
|
}
|
||||||
|
//查询订单所有商品
|
||||||
|
QueryWrapper<BuyOrderProduct> w1 = new QueryWrapper<>();
|
||||||
|
w1.eq("order_id", order.getOrderId());
|
||||||
|
List<BuyOrderProduct> buyOrderProductList = buyOrderProductService.list(w1);
|
||||||
|
for (BuyOrderProduct buyOrderProduct : buyOrderProductList) {
|
||||||
|
//查询用户之前是否拥有书籍,如没有删除电子书
|
||||||
|
QueryWrapper<ShopProduct> w2 = new QueryWrapper<>();
|
||||||
|
w2.eq("product_id",buyOrderProduct.getProductId());
|
||||||
|
ShopProduct sp = shopProductService.getOne(w2);
|
||||||
|
if (sp!=null){
|
||||||
|
if (!"".equals(sp.getBookId())) {
|
||||||
|
String bookids[] = sp.getBookId().split(",");
|
||||||
|
if (bookids.length > 0){
|
||||||
|
for (int i=0;i < bookids.length; i++){
|
||||||
|
//查询这本书在哪些商品里
|
||||||
|
QueryWrapper<ShopProduct> w3 = new QueryWrapper<>();
|
||||||
|
w3.eq("book_ids",bookids[i])
|
||||||
|
.or().like("book_ids",","+bookids[i]+",")
|
||||||
|
.or().likeLeft("book_ids",","+bookids[i])
|
||||||
|
.or().likeRight("book_ids",bookids[i]+",");
|
||||||
|
List<ShopProduct> list = shopProductService.list(w3);
|
||||||
|
//查询此用户之前是否买过这些商品,并且剔除当前订单
|
||||||
|
if (list.size() > 0){
|
||||||
|
int flag = 0;
|
||||||
|
for (ShopProduct item : list) {
|
||||||
|
String arr[] = {item.getProductId().toString()};
|
||||||
|
if (isBought(order,arr)){
|
||||||
|
flag++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//如果用户之前没买过此书,删除电子书权限
|
||||||
|
if (flag==0){
|
||||||
|
QueryWrapper<UserEbookBuyEntity> w5 = new QueryWrapper<>();
|
||||||
|
w5.eq("book_id",bookids[i]);
|
||||||
|
w5.eq("user_id",order.getUserId());
|
||||||
|
userEbookBuyService.remove(w5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//查询用户之前是否拥有权限
|
||||||
|
//脉穴的权限0无权,1有权
|
||||||
|
MyUserEntity userInfo = userService.getById(order.getUserId());
|
||||||
|
if (buyOrderProduct.getProductId()==128||buyOrderProduct.getProductId()==129 ||buyOrderProduct.getProductId()==130
|
||||||
|
||buyOrderProduct.getProductId()==131||buyOrderProduct.getProductId()==136){
|
||||||
|
String arr[] = {"128","129","130","131","136"};
|
||||||
|
if (!isBought(order,arr)){
|
||||||
|
userInfo.setPointPower(0);
|
||||||
|
userService.updateById(userInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//时辰取穴权限 0没有1有
|
||||||
|
if (buyOrderProduct.getProductId()==133||buyOrderProduct.getProductId()==134
|
||||||
|
||buyOrderProduct.getProductId()==135){
|
||||||
|
String arr[] = {"133","134","135"};
|
||||||
|
if (!isBought(order,arr)){
|
||||||
|
userInfo.setTgdzPower(0);
|
||||||
|
userService.updateById(userInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//五运六气的权限0无权1有权
|
||||||
|
if (buyOrderProduct.getProductId()==39||buyOrderProduct.getProductId()==62
|
||||||
|
||buyOrderProduct.getProductId()==123||buyOrderProduct.getProductId()==127){
|
||||||
|
String arr[] = {"39","62","123","127"};
|
||||||
|
if (!isBought(order, arr)){
|
||||||
|
userInfo.setWylqPower(0);
|
||||||
|
userService.updateById(userInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//库存回滚
|
||||||
|
Integer productId = buyOrderProduct.getProductId();
|
||||||
|
ShopProduct product = shopProductService.getById(productId);
|
||||||
|
product.setProductStock(product.getProductStock() + buyOrderProduct.getQuantity());
|
||||||
|
shopProductService.updateById(product);
|
||||||
|
}
|
||||||
|
//订单设置交易失败状态并删除
|
||||||
|
order.setOrderStatus("4");
|
||||||
|
buyOrderService.saveOrUpdate(order);
|
||||||
|
buyOrderService.removeById(order.getOrderId());
|
||||||
|
}
|
||||||
|
|
||||||
|
//本订单的用户之前是否买过当前商品
|
||||||
|
public boolean isBought(BuyOrder order,String[] productId){
|
||||||
|
MPJLambdaWrapper<BuyOrder> w4 = new MPJLambdaWrapper<>();
|
||||||
|
w4.selectAll(BuyOrder.class);
|
||||||
|
w4.leftJoin(BuyOrderProduct.class,BuyOrderProduct::getOrderId,BuyOrder::getOrderId);
|
||||||
|
w4.in(BuyOrderProduct::getProductId,productId);
|
||||||
|
w4.eq(BuyOrder::getUserId,order.getUserId());
|
||||||
|
w4.ne(BuyOrder::getOrderId,order.getOrderId());
|
||||||
|
w4.in(BuyOrder::getOrderStatus,"1","2","3");
|
||||||
|
return buyOrderService.list(w4).size() > 0 ? true : false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -53,6 +53,11 @@ public class WechatPayConfig implements Serializable {
|
|||||||
*/
|
*/
|
||||||
@Value("${wxpay.payUrl}")
|
@Value("${wxpay.payUrl}")
|
||||||
private String payUrl;
|
private String payUrl;
|
||||||
|
/**
|
||||||
|
* pay url
|
||||||
|
*/
|
||||||
|
@Value("${wxpay.refundUrl}")
|
||||||
|
private String refundUrl;
|
||||||
/**
|
/**
|
||||||
* 回调地址
|
* 回调地址
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.peanut.modules.pay.weChatPay.controller;
|
package com.peanut.modules.pay.weChatPay.controller;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.alibaba.fastjson.TypeReference;
|
import com.alibaba.fastjson.TypeReference;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
@@ -10,6 +11,7 @@ import com.peanut.modules.book.entity.*;
|
|||||||
import com.peanut.modules.book.service.*;
|
import com.peanut.modules.book.service.*;
|
||||||
import com.peanut.modules.pay.weChatPay.config.WechatPayConfig;
|
import com.peanut.modules.pay.weChatPay.config.WechatPayConfig;
|
||||||
import com.peanut.modules.pay.weChatPay.dto.WechatPaymentInfo;
|
import com.peanut.modules.pay.weChatPay.dto.WechatPaymentInfo;
|
||||||
|
import com.peanut.modules.pay.weChatPay.service.WxpayService;
|
||||||
import com.peanut.modules.pay.weChatPay.util.HttpUtils;
|
import com.peanut.modules.pay.weChatPay.util.HttpUtils;
|
||||||
import com.peanut.modules.pay.weChatPay.util.WechatPayValidator;
|
import com.peanut.modules.pay.weChatPay.util.WechatPayValidator;
|
||||||
import com.peanut.modules.pay.weChatPay.util.WxPayUtil;
|
import com.peanut.modules.pay.weChatPay.util.WxPayUtil;
|
||||||
@@ -31,41 +33,26 @@ import java.util.stream.Collectors;
|
|||||||
@CrossOrigin
|
@CrossOrigin
|
||||||
@RequestMapping("/pay")
|
@RequestMapping("/pay")
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public class WeChatPayController {
|
public class WeChatPayController {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private MyUserService userService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private BuyOrderService buyOrderService;
|
private BuyOrderService buyOrderService;
|
||||||
@Autowired
|
|
||||||
private BuyOrderProductDao buyOrderProductDao;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@Lazy
|
@Lazy
|
||||||
private WechatPayConfig wechatPayConfig;
|
private WechatPayConfig wechatPayConfig;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private BookBuyConfigService bookBuyConfigService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private PayWechatOrderService payWechatOrderService;
|
private PayWechatOrderService payWechatOrderService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private PayPaymentOrderService payPaymentOrderService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private TransactionDetailsService transactionDetailsService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ShopProductBookService shopProductBookService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private UserEbookBuyService userEbookBuyService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private WxPayUtil wxPayUtil;
|
private WxPayUtil wxPayUtil;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WxpayService wxpayService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成预订单
|
* 生成预订单
|
||||||
*
|
*
|
||||||
@@ -74,8 +61,7 @@ public class WeChatPayController {
|
|||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = "/placeAnOrder/shoppingPay")
|
@RequestMapping(value = "/placeAnOrder/shoppingPay")
|
||||||
@Transactional(rollbackFor = Exception.class)
|
public R newShoppingPay(@RequestBody WechatPaymentInfo paymentInfo){
|
||||||
public R newShoppingPay(@RequestBody WechatPaymentInfo paymentInfo) {
|
|
||||||
QueryWrapper<BuyOrder> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<BuyOrder> queryWrapper = new QueryWrapper<>();
|
||||||
queryWrapper.eq("order_sn", paymentInfo.getOrderSn());
|
queryWrapper.eq("order_sn", paymentInfo.getOrderSn());
|
||||||
BuyOrder order = buyOrderService.getOne(queryWrapper);
|
BuyOrder order = buyOrderService.getOne(queryWrapper);
|
||||||
@@ -114,122 +100,28 @@ public class WeChatPayController {
|
|||||||
*/
|
*/
|
||||||
@PostMapping("/payNotify")
|
@PostMapping("/payNotify")
|
||||||
@Transactional
|
@Transactional
|
||||||
public R payNotify(HttpServletRequest request, HttpServletResponse response) {
|
public void payNotify(HttpServletRequest request, HttpServletResponse response){
|
||||||
log.info("微信支付回调");
|
wxpayService.payNotify(request);
|
||||||
// 处理通知参数
|
|
||||||
Map<String, Object> bodyMap = getNotifyBody(request);
|
|
||||||
if (bodyMap == null) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
// 解密resource中的通知数据
|
|
||||||
String resource = bodyMap.get("resource").toString();
|
/**
|
||||||
Map<String, Object> resourceMap = WechatPayValidator.decryptFromResource(resource, wechatPayConfig.getApiV3Key(), 1);
|
* 微信退款申请
|
||||||
String orderNo = resourceMap.get("out_trade_no").toString();
|
*/
|
||||||
// 根据订单号,做幂等处理,并且在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱
|
@RequestMapping("/refund" )
|
||||||
BuyOrder order = this.buyOrderService.getOne(new QueryWrapper<BuyOrder>().eq("order_sn", orderNo));
|
public R refund(@RequestBody Map<String,Object> map){
|
||||||
// 1.根据订单id获取订单信息
|
return R.ok(wxpayService.refund(map));
|
||||||
if ("order".equals(order.getOrderType())) {
|
|
||||||
BuyOrder orderEntity = buyOrderService.getBaseMapper().selectOne(new QueryWrapper<BuyOrder>().eq("order_sn", orderNo));
|
|
||||||
BigDecimal realMoney = orderEntity.getRealMoney();
|
|
||||||
// 查询订单的所有 book_id
|
|
||||||
List<Integer> orderBookIdList = shopProductBookService.getOrderBookId(order.getOrderSn());
|
|
||||||
// 去重
|
|
||||||
Set<Integer> set = new HashSet<>(orderBookIdList);
|
|
||||||
orderBookIdList.clear();
|
|
||||||
orderBookIdList.addAll(set);
|
|
||||||
// 查询用户的所有 book_id
|
|
||||||
List<Integer> userBookIdList = userEbookBuyService.getUserBookId(order.getUserId());
|
|
||||||
// 取差集
|
|
||||||
orderBookIdList.removeAll(userBookIdList);
|
|
||||||
// 为用户添加书籍
|
|
||||||
List<UserEbookBuyEntity> userEbookBuyEntities = new ArrayList<>();
|
|
||||||
for (Integer bookId : orderBookIdList) {
|
|
||||||
UserEbookBuyEntity entity = new UserEbookBuyEntity();
|
|
||||||
entity.setUserId(order.getUserId());
|
|
||||||
entity.setBookId(bookId);
|
|
||||||
userEbookBuyEntities.add(entity);
|
|
||||||
}
|
}
|
||||||
userEbookBuyService.saveBatch(userEbookBuyEntities);
|
|
||||||
//手摸脚模购买后会开启用户的脉穴的功能
|
/**
|
||||||
List<Integer> collect = buyOrderProductDao.selectList(new LambdaQueryWrapper<BuyOrderProduct>().eq(BuyOrderProduct::getOrderId, order.getOrderId())).stream().map(BuyOrderProduct::getProductId).collect(Collectors.toList());
|
* 微信退款回调
|
||||||
if(collect.contains(128)||collect.contains(129)||collect.contains(130)||collect.contains(131)||collect.contains(136)){
|
* @return R
|
||||||
MyUserEntity userInfo = userService.getById(order.getUserId());
|
*/
|
||||||
userInfo.setPointPower(1);
|
@PostMapping("/refundNotify")
|
||||||
userService.updateById(userInfo);
|
public void refundNotify(HttpServletRequest request){
|
||||||
}
|
wxpayService.refundNotify(request);
|
||||||
if(collect.contains(133)||collect.contains(134)||collect.contains(135)){
|
|
||||||
MyUserEntity userInfo = userService.getById(order.getUserId());
|
|
||||||
userInfo.setTgdzPower(1);
|
|
||||||
userService.updateById(userInfo);
|
|
||||||
}
|
|
||||||
if(collect.contains(39)||collect.contains(62)||collect.contains(123)||collect.contains(127)){
|
|
||||||
MyUserEntity userInfo = userService.getById(order.getUserId());
|
|
||||||
userInfo.setWylqPower(1);
|
|
||||||
userService.updateById(userInfo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
buyOrderService.updateOrderStatus(order.getUserId(), order.getOrderSn(), "0");
|
|
||||||
}
|
|
||||||
if ("point".equals(order.getOrderType())) {
|
|
||||||
PayWechatOrderEntity buy_order_id = payWechatOrderService.getBaseMapper().selectOne(new QueryWrapper<PayWechatOrderEntity>().eq("order_sn", order.getOrderSn()));
|
|
||||||
Integer buyorder = buy_order_id.getBuyOrderId();
|
|
||||||
BookBuyConfigEntity bookBuyConfigEntity = bookBuyConfigService.getById(buyorder);
|
|
||||||
String realMoney = bookBuyConfigEntity.getRealMoney();
|
|
||||||
int money = Integer.parseInt(realMoney);
|
|
||||||
userService.rechargeHSPoint(order.getUserId(), money);
|
|
||||||
TransactionDetailsEntity transactionDetailsEntity = new TransactionDetailsEntity();
|
|
||||||
transactionDetailsEntity.setUserId(order.getUserId());
|
|
||||||
transactionDetailsEntity.setChangeAmount(new BigDecimal(money));
|
|
||||||
transactionDetailsEntity.setOrderType("充值");
|
|
||||||
transactionDetailsEntity.setRelationId(buy_order_id.getId().intValue());
|
|
||||||
transactionDetailsEntity.setRemark("充值");
|
|
||||||
|
|
||||||
MyUserEntity user = userService.getById(order.getUserId());
|
|
||||||
BigDecimal peanutCoin = user.getPeanutCoin();
|
|
||||||
transactionDetailsEntity.setUserBalance(peanutCoin);
|
|
||||||
transactionDetailsEntity.setUserName(user.getNickname());
|
|
||||||
transactionDetailsEntity.setTel(user.getTel());
|
|
||||||
transactionDetailsService.save(transactionDetailsEntity);
|
|
||||||
// 插入 花生币 充值记录
|
|
||||||
PayPaymentOrderEntity payPaymentOrderEntity = new PayPaymentOrderEntity();
|
|
||||||
payPaymentOrderEntity.setUserId(order.getUserId());
|
|
||||||
payPaymentOrderEntity.setOrderId(String.valueOf(buy_order_id.getId()));
|
|
||||||
payPaymentOrderEntity.setRealAmount(new BigDecimal(bookBuyConfigEntity.getRealMoney()));
|
|
||||||
payPaymentOrderEntity.setRechargeAmount(new BigDecimal(bookBuyConfigEntity.getMoney()));
|
|
||||||
payPaymentOrderEntity.setRechargeChannel(bookBuyConfigEntity.getQudao());
|
|
||||||
payPaymentOrderEntity.setRechargeStatus("success");
|
|
||||||
payPaymentOrderEntity.setSuccessTime(new Date());
|
|
||||||
payPaymentOrderEntity.setUserName(user.getNickname());
|
|
||||||
payPaymentOrderEntity.setTel(user.getTel());
|
|
||||||
payPaymentOrderService.save(payPaymentOrderEntity);
|
|
||||||
buyOrderService.updateOrderStatus(order.getUserId(), order.getOrderSn(), "2");
|
|
||||||
}
|
|
||||||
// 成功应答
|
|
||||||
return R.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private Map<String, Object> getNotifyBody(HttpServletRequest request) {
|
|
||||||
// 处理通知参数
|
|
||||||
String body = HttpUtils.readData(request);
|
|
||||||
log.info("支付回调参数:{}", body);
|
|
||||||
// 转换为Map
|
|
||||||
Map<String, Object> bodyMap = JSONObject.parseObject(body, new TypeReference<Map<String, Object>>() {
|
|
||||||
});
|
|
||||||
// 微信的通知ID(通知的唯一ID)
|
|
||||||
String notifyId = bodyMap.get("id").toString();
|
|
||||||
// 验证签名信息
|
|
||||||
try {
|
|
||||||
WechatPayValidator wechatPayValidator = new WechatPayValidator(wechatPayConfig.getVerifier(), notifyId, body);
|
|
||||||
if (!wechatPayValidator.validate(request)) {
|
|
||||||
log.error("通知验签失败");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
log.info("通知验签成功");
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error(e.getMessage());
|
|
||||||
}
|
|
||||||
return bodyMap;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,13 +5,19 @@ import com.peanut.modules.book.entity.PayWechatOrderEntity;
|
|||||||
import com.peanut.modules.pay.weChatPay.dto.WechatPaymentInfo;
|
import com.peanut.modules.pay.weChatPay.dto.WechatPaymentInfo;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public interface WxpayService extends IService<PayWechatOrderEntity> {
|
public interface WxpayService extends IService<PayWechatOrderEntity> {
|
||||||
|
|
||||||
void prepay(WechatPaymentInfo wechatDto) throws IOException;
|
void prepay(WechatPaymentInfo wechatDto);
|
||||||
|
|
||||||
|
void payNotify(HttpServletRequest request);
|
||||||
|
|
||||||
|
String refund(Map<String,Object> map);
|
||||||
|
|
||||||
|
void refundNotify(HttpServletRequest request);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,22 +2,34 @@ package com.peanut.modules.pay.weChatPay.service.impl;
|
|||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.fastjson.TypeReference;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||||
|
import com.peanut.common.exception.RRException;
|
||||||
|
import com.peanut.modules.book.dao.BuyOrderProductDao;
|
||||||
import com.peanut.modules.book.dao.PayWechatOrderDao;
|
import com.peanut.modules.book.dao.PayWechatOrderDao;
|
||||||
import com.peanut.modules.book.entity.PayWechatOrderEntity;
|
import com.peanut.modules.book.entity.*;
|
||||||
import com.peanut.modules.book.service.PayWechatOrderService;
|
import com.peanut.modules.book.service.*;
|
||||||
|
import com.peanut.modules.pay.refund.entity.PayRefundOrder;
|
||||||
|
import com.peanut.modules.pay.refund.service.PayRefundOrderService;
|
||||||
import com.peanut.modules.pay.weChatPay.config.WechatPayConfig;
|
import com.peanut.modules.pay.weChatPay.config.WechatPayConfig;
|
||||||
import com.peanut.modules.pay.weChatPay.dto.WechatPaymentInfo;
|
import com.peanut.modules.pay.weChatPay.dto.WechatPaymentInfo;
|
||||||
import com.peanut.modules.pay.weChatPay.service.WxpayService;
|
import com.peanut.modules.pay.weChatPay.service.WxpayService;
|
||||||
|
import com.peanut.modules.pay.weChatPay.util.HttpUtils;
|
||||||
|
import com.peanut.modules.pay.weChatPay.util.WechatPayValidator;
|
||||||
import com.peanut.modules.pay.weChatPay.util.WxPayUtil;
|
import com.peanut.modules.pay.weChatPay.util.WxPayUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.Map;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@@ -32,8 +44,33 @@ public class WxpayServiceImpl extends ServiceImpl<PayWechatOrderDao, PayWechatOr
|
|||||||
@Autowired
|
@Autowired
|
||||||
private PayWechatOrderService payWechatOrderService;
|
private PayWechatOrderService payWechatOrderService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MyUserService userService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BuyOrderProductDao buyOrderProductDao;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BookBuyConfigService bookBuyConfigService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PayPaymentOrderService payPaymentOrderService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TransactionDetailsService transactionDetailsService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ShopProductBookService shopProductBookService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserEbookBuyService userEbookBuyService;
|
||||||
|
@Autowired
|
||||||
|
private BuyOrderService buyOrderService;
|
||||||
|
@Autowired
|
||||||
|
private PayRefundOrderService refundOrderService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void prepay(WechatPaymentInfo paymentInfo) throws IOException {
|
public void prepay(WechatPaymentInfo paymentInfo){
|
||||||
Map<String, Object> paramMap = new HashMap<>();
|
Map<String, Object> paramMap = new HashMap<>();
|
||||||
// app id
|
// app id
|
||||||
paramMap.put("appid", wechatPayConfig.getAppId());
|
paramMap.put("appid", wechatPayConfig.getAppId());
|
||||||
@@ -65,4 +102,191 @@ public class WxpayServiceImpl extends ServiceImpl<PayWechatOrderDao, PayWechatOr
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void payNotify(HttpServletRequest request){
|
||||||
|
log.info("微信支付回调");
|
||||||
|
// 处理通知参数
|
||||||
|
Map<String, Object> bodyMap = getNotifyBody(request);
|
||||||
|
// 解密resource中的通知数据
|
||||||
|
String resource = bodyMap.get("resource").toString();
|
||||||
|
Map<String, Object> resourceMap = WechatPayValidator.decryptFromResource(resource, wechatPayConfig.getApiV3Key(), 1);
|
||||||
|
String orderNo = resourceMap.get("out_trade_no").toString();
|
||||||
|
//修改微信订单表
|
||||||
|
MPJLambdaWrapper<PayWechatOrderEntity> wrapper = new MPJLambdaWrapper();
|
||||||
|
wrapper.eq(PayWechatOrderEntity::getOrderSn,orderNo);
|
||||||
|
PayWechatOrderEntity payWechatOrderEntity = payWechatOrderService.getOne(wrapper);
|
||||||
|
payWechatOrderEntity.setOrderId(resourceMap.get("transaction_id").toString());
|
||||||
|
payWechatOrderService.updateById(payWechatOrderEntity);
|
||||||
|
// 根据订单号,做幂等处理,并且在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱
|
||||||
|
BuyOrder order = this.buyOrderService.getOne(new QueryWrapper<BuyOrder>().eq("order_sn", orderNo));
|
||||||
|
// 1.根据订单id获取订单信息
|
||||||
|
if ("order".equals(order.getOrderType())) {
|
||||||
|
BuyOrder orderEntity = buyOrderService.getBaseMapper().selectOne(new QueryWrapper<BuyOrder>().eq("order_sn", orderNo));
|
||||||
|
BigDecimal realMoney = orderEntity.getRealMoney();
|
||||||
|
// 查询订单的所有 book_id
|
||||||
|
List<Integer> orderBookIdList = shopProductBookService.getOrderBookId(order.getOrderSn());
|
||||||
|
// 去重
|
||||||
|
Set<Integer> set = new HashSet<>(orderBookIdList);
|
||||||
|
orderBookIdList.clear();
|
||||||
|
orderBookIdList.addAll(set);
|
||||||
|
// 查询用户的所有 book_id
|
||||||
|
List<Integer> userBookIdList = userEbookBuyService.getUserBookId(order.getUserId());
|
||||||
|
// 取差集
|
||||||
|
orderBookIdList.removeAll(userBookIdList);
|
||||||
|
// 为用户添加书籍
|
||||||
|
List<UserEbookBuyEntity> userEbookBuyEntities = new ArrayList<>();
|
||||||
|
for (Integer bookId : orderBookIdList) {
|
||||||
|
UserEbookBuyEntity entity = new UserEbookBuyEntity();
|
||||||
|
entity.setUserId(order.getUserId());
|
||||||
|
entity.setBookId(bookId);
|
||||||
|
userEbookBuyEntities.add(entity);
|
||||||
|
}
|
||||||
|
userEbookBuyService.saveBatch(userEbookBuyEntities);
|
||||||
|
//手摸脚模购买后会开启用户的脉穴的功能
|
||||||
|
List<Integer> collect = buyOrderProductDao.selectList(new LambdaQueryWrapper<BuyOrderProduct>().eq(BuyOrderProduct::getOrderId, order.getOrderId())).stream().map(BuyOrderProduct::getProductId).collect(Collectors.toList());
|
||||||
|
if(collect.contains(128)||collect.contains(129)||collect.contains(130)||collect.contains(131)||collect.contains(136)){
|
||||||
|
MyUserEntity userInfo = userService.getById(order.getUserId());
|
||||||
|
userInfo.setPointPower(1);
|
||||||
|
userService.updateById(userInfo);
|
||||||
|
}
|
||||||
|
if(collect.contains(133)||collect.contains(134)||collect.contains(135)){
|
||||||
|
MyUserEntity userInfo = userService.getById(order.getUserId());
|
||||||
|
userInfo.setTgdzPower(1);
|
||||||
|
userService.updateById(userInfo);
|
||||||
|
}
|
||||||
|
if(collect.contains(39)||collect.contains(62)||collect.contains(123)||collect.contains(127)){
|
||||||
|
MyUserEntity userInfo = userService.getById(order.getUserId());
|
||||||
|
userInfo.setWylqPower(1);
|
||||||
|
userService.updateById(userInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
buyOrderService.updateOrderStatus(order.getUserId(), order.getOrderSn(), "0");
|
||||||
|
}
|
||||||
|
if ("point".equals(order.getOrderType())) {
|
||||||
|
PayWechatOrderEntity buy_order_id = payWechatOrderService.getBaseMapper().selectOne(new QueryWrapper<PayWechatOrderEntity>().eq("order_sn", order.getOrderSn()));
|
||||||
|
Integer buyorder = buy_order_id.getBuyOrderId();
|
||||||
|
BookBuyConfigEntity bookBuyConfigEntity = bookBuyConfigService.getById(buyorder);
|
||||||
|
String realMoney = bookBuyConfigEntity.getRealMoney();
|
||||||
|
int money = Integer.parseInt(realMoney);
|
||||||
|
userService.rechargeHSPoint(order.getUserId(), money);
|
||||||
|
TransactionDetailsEntity transactionDetailsEntity = new TransactionDetailsEntity();
|
||||||
|
transactionDetailsEntity.setUserId(order.getUserId());
|
||||||
|
transactionDetailsEntity.setChangeAmount(new BigDecimal(money));
|
||||||
|
transactionDetailsEntity.setOrderType("充值");
|
||||||
|
transactionDetailsEntity.setRelationId(buy_order_id.getId().intValue());
|
||||||
|
transactionDetailsEntity.setRemark("充值");
|
||||||
|
|
||||||
|
MyUserEntity user = userService.getById(order.getUserId());
|
||||||
|
BigDecimal peanutCoin = user.getPeanutCoin();
|
||||||
|
transactionDetailsEntity.setUserBalance(peanutCoin);
|
||||||
|
transactionDetailsEntity.setUserName(user.getNickname());
|
||||||
|
transactionDetailsEntity.setTel(user.getTel());
|
||||||
|
transactionDetailsService.save(transactionDetailsEntity);
|
||||||
|
// 插入 花生币 充值记录
|
||||||
|
PayPaymentOrderEntity payPaymentOrderEntity = new PayPaymentOrderEntity();
|
||||||
|
payPaymentOrderEntity.setUserId(order.getUserId());
|
||||||
|
payPaymentOrderEntity.setOrderId(String.valueOf(buy_order_id.getId()));
|
||||||
|
payPaymentOrderEntity.setRealAmount(new BigDecimal(bookBuyConfigEntity.getRealMoney()));
|
||||||
|
payPaymentOrderEntity.setRechargeAmount(new BigDecimal(bookBuyConfigEntity.getMoney()));
|
||||||
|
payPaymentOrderEntity.setRechargeChannel(bookBuyConfigEntity.getQudao());
|
||||||
|
payPaymentOrderEntity.setRechargeStatus("success");
|
||||||
|
payPaymentOrderEntity.setSuccessTime(new Date());
|
||||||
|
payPaymentOrderEntity.setUserName(user.getNickname());
|
||||||
|
payPaymentOrderEntity.setTel(user.getTel());
|
||||||
|
payPaymentOrderService.save(payPaymentOrderEntity);
|
||||||
|
buyOrderService.updateOrderStatus(order.getUserId(), order.getOrderSn(), "2");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String refund(Map<String,Object> map){
|
||||||
|
LambdaQueryWrapper<PayWechatOrderEntity> wrapper = new LambdaQueryWrapper();
|
||||||
|
wrapper.eq(PayWechatOrderEntity::getOrderSn,map.get("orderSn").toString());
|
||||||
|
PayWechatOrderEntity order = payWechatOrderService.getOne(wrapper);
|
||||||
|
Map<String, Object> paramMap = new HashMap<>();
|
||||||
|
//构建订单金额信息
|
||||||
|
//退款金额
|
||||||
|
BigDecimal refund = new BigDecimal(map.get("refundFee").toString());
|
||||||
|
//原订单总金额
|
||||||
|
BigDecimal total = order.getTotalAmount();
|
||||||
|
// 这里 * 100,微信支付单位为 ‘分’
|
||||||
|
BigDecimal hand = new BigDecimal("100");
|
||||||
|
Map<String, Object> amountMap = new HashMap<>();
|
||||||
|
amountMap.put("refund", refund.multiply(hand));
|
||||||
|
amountMap.put("total", total.multiply(hand).intValue());
|
||||||
|
amountMap.put("currency", "CNY");
|
||||||
|
paramMap.put("amount", amountMap);
|
||||||
|
//商户退款单号 商户系统内 部的退款单号,商户系统内部唯一,只能是数字、大小写字母_-|*@ ,同一退款单号多次请求只退一笔。
|
||||||
|
// paramMap.put("out_refund_no", map.get("outRefundNo").toString());
|
||||||
|
paramMap.put("out_refund_no", UUID.randomUUID().toString());
|
||||||
|
//微信支付订单号
|
||||||
|
paramMap.put("transaction_id", order.getOrderId());
|
||||||
|
//退款原因
|
||||||
|
paramMap.put("reason", map.get("reason").toString());
|
||||||
|
// 微信退款回调地址
|
||||||
|
paramMap.put("notify_url", wechatPayConfig.getRefundNotifyUrl());
|
||||||
|
JSONObject json = JSONObject.parseObject(JSON.toJSONString(paramMap));
|
||||||
|
log.info("微信退款申请请求参数:{}", paramMap);
|
||||||
|
log.info(">>>>>>>>>>App请求微信退款申请接口");
|
||||||
|
JSONObject responseJson = wxPayUtil.doPostWexinV3(wechatPayConfig.getRefundUrl(), json.toJSONString());
|
||||||
|
log.info(">>>>>>>>>>>微信退款返回的信息是 resJson = {}", responseJson.toJSONString());
|
||||||
|
if ("SUCCESS".equals(responseJson.get("status"))){
|
||||||
|
//退款申请成功,等待到账
|
||||||
|
}
|
||||||
|
return responseJson.toJSONString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void refundNotify(HttpServletRequest request){
|
||||||
|
log.info("微信退款回调");
|
||||||
|
// 处理通知参数
|
||||||
|
Map<String, Object> bodyMap = getNotifyBody(request);
|
||||||
|
// 解密resource中的通知数据
|
||||||
|
String resource = bodyMap.get("resource").toString();
|
||||||
|
Map<String, Object> resourceMap = WechatPayValidator.decryptFromResource(resource, wechatPayConfig.getApiV3Key(), 2);
|
||||||
|
log.info("微信退款回调结果 msg={}",resourceMap);
|
||||||
|
if ("SUCCESS".equals(resourceMap.get("refund_status").toString())){
|
||||||
|
log.info(">>>>>>>>>>>微信退款成功!<<<<<<<<<<<<<");
|
||||||
|
MPJLambdaWrapper<BuyOrder> w = new MPJLambdaWrapper();
|
||||||
|
w.selectAll(BuyOrder.class);
|
||||||
|
w.leftJoin(PayWechatOrderEntity.class,PayWechatOrderEntity::getOrderSn, BuyOrder::getOrderSn);
|
||||||
|
w.eq("t1.order_id",resourceMap.get("transaction_id").toString());
|
||||||
|
BuyOrder order = buyOrderService.getOne(w);
|
||||||
|
PayRefundOrder refund = new PayRefundOrder();
|
||||||
|
refund.setPayType("1");
|
||||||
|
refund.setOrderId(order.getOrderId());
|
||||||
|
refund.setTradeNo(resourceMap.get("transaction_id").toString());
|
||||||
|
refund.setOutTradeNo(resourceMap.get("out_trade_no").toString());
|
||||||
|
refund.setRefundFee(((Map)resourceMap.get("amount")).get("refund").toString());
|
||||||
|
refundOrderService.save(refund);
|
||||||
|
refundOrderService.businessOpt(order);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Map<String, Object> getNotifyBody(HttpServletRequest request) {
|
||||||
|
// 处理通知参数
|
||||||
|
String body = HttpUtils.readData(request);
|
||||||
|
log.info("支付回调参数:{}", body);
|
||||||
|
// 转换为Map
|
||||||
|
Map<String, Object> bodyMap = JSONObject.parseObject(body, new TypeReference<Map<String, Object>>() {
|
||||||
|
});
|
||||||
|
// 微信的通知ID(通知的唯一ID)
|
||||||
|
String notifyId = bodyMap.get("id").toString();
|
||||||
|
// 验证签名信息
|
||||||
|
try {
|
||||||
|
WechatPayValidator wechatPayValidator = new WechatPayValidator(wechatPayConfig.getVerifier(), notifyId, body);
|
||||||
|
if (!wechatPayValidator.validate(request)) {
|
||||||
|
log.error("通知验签失败");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
log.info("通知验签成功");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage());
|
||||||
|
}
|
||||||
|
return bodyMap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,8 @@ wxpay:
|
|||||||
mchId: 1612860909
|
mchId: 1612860909
|
||||||
payUrl: https://api.mch.weixin.qq.com/v3/pay/transactions/app
|
payUrl: https://api.mch.weixin.qq.com/v3/pay/transactions/app
|
||||||
notifyUrl: https://testapi.nuttyreading.com/pay/payNotify
|
notifyUrl: https://testapi.nuttyreading.com/pay/payNotify
|
||||||
refundNotifyUrl: http://pjm6m9.natappfree.cc/pay/refundNotify
|
refundUrl: https://api.mch.weixin.qq.com/v3/refund/domestic/refunds
|
||||||
|
refundNotifyUrl: https://testapi.nuttyreading.com/pay/refundNotify
|
||||||
keyPemPath: D:/hs/nuttyreading-java/src/main/resources/cent/apiclient_key.pem
|
keyPemPath: D:/hs/nuttyreading-java/src/main/resources/cent/apiclient_key.pem
|
||||||
serialNo: 679AECB2F7AC4183033F713828892BA640E4EEE3
|
serialNo: 679AECB2F7AC4183033F713828892BA640E4EEE3
|
||||||
apiV3Key: 4aYFklzaULeGlr7oJPZ6rHWKcxjihZUF
|
apiV3Key: 4aYFklzaULeGlr7oJPZ6rHWKcxjihZUF
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ spring:
|
|||||||
pool:
|
pool:
|
||||||
core-size: 5
|
core-size: 5
|
||||||
max-size: 50
|
max-size: 50
|
||||||
|
main:
|
||||||
|
allow-circular-references: true
|
||||||
|
|
||||||
#mybatis
|
#mybatis
|
||||||
mybatis-plus:
|
mybatis-plus:
|
||||||
|
|||||||
Reference in New Issue
Block a user