pay notify

This commit is contained in:
Cauchy
2023-10-08 14:56:26 +08:00
parent b18fc6cff9
commit 059f5f8fe8
16 changed files with 810 additions and 834 deletions

1
.gitignore vendored
View File

@@ -12,3 +12,4 @@ buildNumber.properties
/.idea/
/src/test/
peanut_book.iml
weChatConfig.properties

View File

@@ -478,7 +478,7 @@
</repository>
<repository>
<id>com.e-iceblue</id>
<url>http://repo.e-iceblue.cn/repository/maven-public/</url>
<url>https://repo.e-iceblue.cn/repository/maven-public/</url>
</repository>
</repositories>
<pluginRepositories>

View File

@@ -9,6 +9,5 @@ import java.util.List;
@Mapper
public interface ShopProudictBookDao extends BaseMapper<ShopProudictBookEntity> {
List<Integer> getOrderBookId(String orderSn);
}

View File

@@ -5,6 +5,8 @@ import com.peanut.modules.book.entity.UserEbookBuyEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 用户购买书籍表
*
@@ -15,4 +17,5 @@ import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserEbookBuyDao extends MPJBaseMapper<UserEbookBuyEntity> {
List<Integer> getUserBookId(Integer userId);
}

View File

@@ -19,4 +19,6 @@ public interface ShopProudictBookService extends IService<ShopProudictBookEntity
Integer getProductByBookId(Integer bookId);
List<Integer> getOrderBookId(String orderSn);
}

View File

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.peanut.common.utils.PageUtils;
import com.peanut.modules.book.entity.UserEbookBuyEntity;
import java.util.List;
import java.util.Map;
/**
@@ -19,6 +20,8 @@ public interface UserEbookBuyService extends IService<UserEbookBuyEntity> {
PageUtils queryPages(Map<String, Object> params);
List<Integer> getUserBookId(Integer userId);
}

View File

@@ -4,37 +4,36 @@ import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.OSSObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Joiner;
import com.peanut.common.utils.*;
import com.peanut.common.utils.ConstantPropertiesUtils;
import com.peanut.common.utils.FileDownloadUtil;
import com.peanut.common.utils.PageUtils;
import com.peanut.common.utils.Query;
import com.peanut.modules.book.dao.BookDao;
import com.peanut.modules.book.entity.*;
import com.peanut.modules.book.entity.SysDictDataEntity;
import com.peanut.modules.book.service.*;
import com.peanut.modules.book.vo.BookIndexVo;
import com.peanut.modules.book.service.BookChapterService;
import com.peanut.modules.book.service.BookForumArticlesService;
import com.peanut.modules.book.service.BookService;
import com.peanut.modules.book.service.PublisherService;
import com.peanut.modules.sys.service.SysDictDataService;
import com.spire.doc.Document;
import com.spire.doc.Section;
import com.spire.doc.documents.Paragraph;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLDecoder;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.peanut.modules.book.dao.BookDao;
import org.springframework.util.CollectionUtils;
@Service("bookService")
public class BookServiceImpl extends ServiceImpl<BookDao, BookEntity> implements BookService {

View File

@@ -1,4 +1,5 @@
package com.peanut.modules.book.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -15,17 +16,20 @@ import com.peanut.modules.book.service.ShopProudictBookService;
import com.peanut.modules.book.vo.ProudictBookqueryVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service("shopProudictBookService")
public class ShopProudictBookServiceImpl extends ServiceImpl<ShopProudictBookDao,ShopProudictBookEntity> implements ShopProudictBookService {
public class ShopProudictBookServiceImpl extends ServiceImpl<ShopProudictBookDao, ShopProudictBookEntity> implements ShopProudictBookService {
@Autowired
private ShopProductService shopProductService;
@Autowired
private BookService bookService;
@Autowired
private ShopProudictBookDao shopProudictBookDao;
@Override
public PageUtils queryPage(Map<String, Object> params) {
@@ -42,7 +46,7 @@ public class ShopProudictBookServiceImpl extends ServiceImpl<ShopProudictBookDa
Object proudictId = params.get("proudictId");
IPage<ShopProudictBookEntity> page = this.page(
new Query<ShopProudictBookEntity>().getPage(params),
new QueryWrapper<ShopProudictBookEntity>().eq("proudict_id",proudictId)
new QueryWrapper<ShopProudictBookEntity>().eq("proudict_id", proudictId)
);
List<ShopProudictBookEntity> records = page.getRecords();
return new PageUtils(page);
@@ -75,9 +79,9 @@ public class ShopProudictBookServiceImpl extends ServiceImpl<ShopProudictBookDa
@Override
public List<Integer> getBookidsByProductId(Integer productId) {
List<ShopProudictBookEntity> spbs = this.list(new QueryWrapper<ShopProudictBookEntity>().eq("del_flag",0).eq("proudict_id",productId));
List<ShopProudictBookEntity> spbs = this.list(new QueryWrapper<ShopProudictBookEntity>().eq("del_flag", 0).eq("proudict_id", productId));
List<Integer> ids = new ArrayList();
for (ShopProudictBookEntity s : spbs){
for (ShopProudictBookEntity s : spbs) {
ids.add(s.getBookId());
}
return ids;
@@ -86,21 +90,21 @@ public class ShopProudictBookServiceImpl extends ServiceImpl<ShopProudictBookDa
@Override
public Integer getProductByBookId(Integer bookId) {
LambdaQueryWrapper<ShopProudictBookEntity> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ShopProudictBookEntity::getBookId,bookId);
wrapper.eq(ShopProudictBookEntity::getDelFlag,0);
wrapper.eq(ShopProudictBookEntity::getBookId, bookId);
wrapper.eq(ShopProudictBookEntity::getDelFlag, 0);
wrapper.groupBy(ShopProudictBookEntity::getProudictId);
List<ShopProudictBookEntity> shopProudictBookEntities = this.getBaseMapper().selectList(wrapper);
List ids = new ArrayList();
for (ShopProudictBookEntity s : shopProudictBookEntities){
for (ShopProudictBookEntity s : shopProudictBookEntities) {
ids.add(s.getProudictId());
}
if(ids.size()==0){
if (ids.size() == 0) {
return null;
}
LambdaQueryWrapper<ShopProductEntity> wrapper1 = new LambdaQueryWrapper<>();
wrapper1.eq(ShopProductEntity::getDelFlag,0);
wrapper1.in(ShopProductEntity::getProductId,ids);
wrapper1.eq(ShopProductEntity::getDelFlag, 0);
wrapper1.in(ShopProductEntity::getProductId, ids);
wrapper1.orderByAsc(ShopProductEntity::getPrice);
wrapper1.last("limit 1");
List<ShopProductEntity> shopProductEntities = shopProductService.getBaseMapper().selectList(wrapper1);
@@ -108,5 +112,10 @@ public class ShopProudictBookServiceImpl extends ServiceImpl<ShopProudictBookDa
return shopProductEntity.getProductId();
}
@Override
public List<Integer> getOrderBookId(String orderSn) {
return shopProudictBookDao.getOrderBookId(orderSn);
}
}

View File

@@ -1,30 +1,32 @@
package com.peanut.modules.book.service.impl;
import com.peanut.modules.book.entity.BuyOrderEntity;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.peanut.common.utils.PageUtils;
import com.peanut.common.utils.Query;
import com.peanut.modules.book.dao.UserEbookBuyDao;
import com.peanut.modules.book.entity.UserEbookBuyEntity;
import com.peanut.modules.book.service.UserEbookBuyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service("userEbookBuyService")
public class UserEbookBuyServiceImpl extends ServiceImpl<UserEbookBuyDao, UserEbookBuyEntity> implements UserEbookBuyService {
@Autowired
private UserEbookBuyDao userEbookBuyDao;
@Override
public PageUtils queryPage(Map<String, Object> params) {
String userId = (String) params.get("userId");
IPage<UserEbookBuyEntity> page = this.page(
new Query<UserEbookBuyEntity>().getPage(params),
new QueryWrapper<UserEbookBuyEntity>().eq("user_id",userId)
new QueryWrapper<UserEbookBuyEntity>().eq("user_id", userId)
);
return new PageUtils(page);
@@ -36,7 +38,7 @@ public class UserEbookBuyServiceImpl extends ServiceImpl<UserEbookBuyDao, UserEb
IPage<UserEbookBuyEntity> page = this.page(
new Query<UserEbookBuyEntity>().getPage(params),
new QueryWrapper<UserEbookBuyEntity>()
.eq("user_id",userid)
.eq("user_id", userid)
);
@@ -44,24 +46,10 @@ public class UserEbookBuyServiceImpl extends ServiceImpl<UserEbookBuyDao, UserEb
return new PageUtils(page);
}
@Override
public List<Integer> getUserBookId(Integer userId) {
return userEbookBuyDao.getUserBookId(userId);
}
}

View File

@@ -1,4 +1,5 @@
package com.peanut.modules.pay.weChatPay.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
@@ -6,10 +7,9 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.peanut.common.utils.R;
import com.peanut.modules.book.entity.*;
import com.peanut.modules.book.service.*;
import com.peanut.modules.pay.weChatPay.dto.WechatDto;
import com.peanut.modules.pay.weChatPay.config.WechatPayConfig;
import com.peanut.modules.pay.weChatPay.dto.WechatDto;
import com.peanut.modules.pay.weChatPay.util.HttpUtils;
import com.peanut.modules.book.entity.BookBuyConfigEntity;
import com.peanut.modules.pay.weChatPay.util.WechatPayValidator;
import com.peanut.modules.pay.weChatPay.util.WxPayUtil;
import lombok.extern.slf4j.Slf4j;
@@ -24,10 +24,9 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.soap.Text;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
@@ -37,14 +36,7 @@ import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j
@RestController
@@ -53,9 +45,11 @@ import java.util.concurrent.locks.ReentrantLock;
@Configuration
public class WeChatPayController {
@Autowired private MyUserService userService;
@Autowired
private MyUserService userService;
@Autowired private BuyOrderService buyOrderService;
@Autowired
private BuyOrderService buyOrderService;
@Autowired
@Lazy
@@ -74,17 +68,18 @@ public class WeChatPayController {
private TransactionDetailsService transactionDetailsService;
@Autowired
private BuyOrderDetailService buyOrderDetailService;
private ShopProudictBookService shopProudictBookService;
@Autowired
private CloseableHttpClient wxPayNoSignClient; //无需应答签名
private UserEbookBuyService userEbookBuyService;
//无需应答签名
@Autowired
private CloseableHttpClient wxPayClient;
@Autowired
private WxPayUtil wxPayUtil;
private final ReentrantLock lock = new ReentrantLock();
// 由微信生成的应用ID全局唯一。
public static final String appId= "wx47134a8f15083734";
public static final String appId = "wx47134a8f15083734";
// 直连商户的商户号,由微信支付生成并下发。
public static final String mchId = "1612860909";
// 商户证书序列号 7B5676E3CDF56680D0414A009CE501C844DBE2D6 679AECB2F7AC4183033F713828892BA640E4EEE3
@@ -102,78 +97,76 @@ public class WeChatPayController {
@RequestMapping(value = "/placeAnOrder/app")
@Transactional(rollbackFor = Exception.class)
public R pay(@RequestBody WechatDto dto ) throws Exception{
public R pay(@RequestBody WechatDto dto) throws Exception {
log.info("微信生成订单");
List<BuyOrderEntity> one = this.buyOrderService.getBaseMapper().selectList(new QueryWrapper<BuyOrderEntity>().eq("order_sn", dto.getOrderSn()));
BuyOrderEntity order = one.get(0);
// 获取订单
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("appid",appId);
paramMap.put("mchid",mchId);
paramMap.put("description","微信充值");
// 订单编号
paramMap.put("out_trade_no",order.getOrderSn());
// paramMap.put("attach",""); //自定义数据 支付完成后才能显示 在查询API和支付通知中原样返回可作为自定义参数使用
paramMap.put("notify_url",wechatPayConfig.getNotifyUrl());
// 获取订单
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("appid", appId);
paramMap.put("mchid", mchId);
paramMap.put("description", "微信充值");
// 订单编号
paramMap.put("out_trade_no", order.getOrderSn());
// paramMap.put("attach",""); //自定义数据 支付完成后才能显示 在查询API和支付通知中原样返回可作为自定义参数使用
paramMap.put("notify_url", wechatPayConfig.getNotifyUrl());
// paramMap.put("time_expire",afterString);
// 实收金额0.38乘100=38
BigDecimal realsmoney= order.getRealMoney();
BigDecimal hand=new BigDecimal("100");
realsmoney =realsmoney.multiply(hand) ;
Map<String,Object> amountMap = new HashMap<>();
amountMap.put("total",realsmoney);
amountMap.put("currency","CNY");
// paramMap.put("time_expire",afterString);
// 实收金额0.38乘100=38
BigDecimal realsmoney = order.getRealMoney();
BigDecimal hand = new BigDecimal("100");
realsmoney = realsmoney.multiply(hand);
Map<String, Object> amountMap = new HashMap<>();
amountMap.put("total", realsmoney);
amountMap.put("currency", "CNY");
BigDecimal money= order.getRealMoney();
BigDecimal han=new BigDecimal("100");
realsmoney =realsmoney.multiply(han) ;
Map<String,Object> amount = new HashMap<>();
amount.put("total",realsmoney);
amount.put("currency","CNY");
BigDecimal money = order.getRealMoney();
BigDecimal han = new BigDecimal("100");
realsmoney = realsmoney.multiply(han);
Map<String, Object> amount = new HashMap<>();
amount.put("total", realsmoney);
amount.put("currency", "CNY");
if (dto.getTotalAmount()!=order.getRealMoney()) {
if (dto.getTotalAmount() != order.getRealMoney()) {
}
paramMap.put("amount",amountMap);
paramMap.put("amount", amountMap);
JSONObject json = JSONObject.parseObject(JSON.toJSONString(paramMap));
log.info("请求参数"+paramMap);
log.info("请求参数" + paramMap);
com.alibaba.fastjson.JSONObject jsonObject1 = wxPayUtil.doPostWexinV3("https://api.mch.weixin.qq.com/v3/pay/transactions/app", json.toJSONString());
String prepayid = jsonObject1.getString("prepay_id");
// 传入参数 payUrl 发送post请求
// 传入参数 payUrl 发送post请求
HttpPost httpPost = new HttpPost(payUrl);
// 将json数据转换成字符串
StringEntity entity = new StringEntity(json.toString(),"utf-8");
// 设置该请求的Content-Type为application/json 都是json格式
// 将json数据转换成字符串
StringEntity entity = new StringEntity(json.toString(), "utf-8");
// 设置该请求的Content-Type为application/json 都是json格式
entity.setContentType("application/json");
// 将实体对象设置到HttpPost表示要传递该数据到服务器端。
// 将实体对象设置到HttpPost表示要传递该数据到服务器端。
httpPost.setEntity(entity);
// 设置请求头部的Accept属性为"application/json"表示客户端希望接收的为json。
// 设置请求头部的Accept属性为"application/json"表示客户端希望接收的为json。
httpPost.setHeader("Accept", "application/json");
CloseableHttpResponse response = wxPayClient.execute(httpPost);
// 向微信支付平台发送请求,处理响应结果,并将订单信息保存到数据库中。
// 向微信支付平台发送请求,处理响应结果,并将订单信息保存到数据库中。
String bodyAsString = EntityUtils.toString(response.getEntity());//响应体
// 时间戳
Long timestamp = System.currentTimeMillis()/1000;
// 随机串
String nonceStr = UUID.randomUUID().toString().replace("-","");
// 时间戳
Long timestamp = System.currentTimeMillis() / 1000;
// 随机串
String nonceStr = UUID.randomUUID().toString().replace("-", "");
String sign = wxPayUtil.getSign(WxPayUtil.appId,timestamp,nonceStr,prepayid);
log.info("签名:"+sign);
String sign = wxPayUtil.getSign(WxPayUtil.appId, timestamp, nonceStr, prepayid);
log.info("签名:" + sign);
Map Map = new HashMap();
Map.put("prepayid",prepayid);
Map.put("timestamp",timestamp+"");
Map.put("noncestr",nonceStr);
Map.put("sign",sign);
Map.put("appid",appId);
Map.put("package","Sign=WXPay");
Map.put("extData","sign");
Map.put("partnerid",mchId);
Map.put("prepayid", prepayid);
Map.put("timestamp", timestamp + "");
Map.put("noncestr", nonceStr);
Map.put("sign", sign);
Map.put("appid", appId);
Map.put("package", "Sign=WXPay");
Map.put("extData", "sign");
Map.put("partnerid", mchId);
try {
int statusCode = response.getStatusLine().getStatusCode(); //响应状态码
if (statusCode == 200) { //处理成功
@@ -198,13 +191,14 @@ public class WeChatPayController {
System.out.println("下单失败 = " + statusCode + ",返回结果 = " + bodyAsString);
throw new IOException("request failed");
}
}finally {
} finally {
response.close();
}
// 返回url和订单号
return R.ok().put("paramMap" ,paramMap).put("Map",Map);
return R.ok().put("paramMap", paramMap).put("Map", Map);
}
/**
* 获取私钥。
*
@@ -227,8 +221,8 @@ public class WeChatPayController {
throw new RuntimeException("无效的密钥格式");
}
}
/**
*
* 微信支付回调
*
* @param request
@@ -236,58 +230,68 @@ public class WeChatPayController {
* @return
*/
@PostMapping("/payNotify")
@Transactional
public R payNotify(HttpServletRequest request, HttpServletResponse response) {
log.info("##############################微信支付回调#######################");
// 处理通知参数
Map<String,Object> bodyMap = getNotifyBody(request);
if(bodyMap==null){
log.info("微信支付回调");
// 处理通知参数
Map<String, Object> bodyMap = getNotifyBody(request);
if (bodyMap == null) {
return null;
}
if(lock.tryLock()) {
try {
// 解密resource中的通知数据
// 解密resource中的通知数据
String resource = bodyMap.get("resource").toString();
Map<String, Object> resourceMap = WechatPayValidator.decryptFromResource(resource, wechatPayConfig.getApiV3Key(),1);
Map<String, Object> resourceMap = WechatPayValidator.decryptFromResource(resource, wechatPayConfig.getApiV3Key(), 1);
String orderNo = resourceMap.get("out_trade_no").toString();
String transactionId = resourceMap.get("transaction_id").toString();
// 根据订单号,做幂等处理,并且在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱
// 根据订单号,做幂等处理,并且在对业务数据进行状态检查和处理之前,要采用数据锁进行并发控制,以避免函数重入造成的数据混乱
BuyOrderEntity order = this.buyOrderService.getOne(new QueryWrapper<BuyOrderEntity>().eq("order_sn", orderNo));
PayWechatOrderEntity wechatEntity = new PayWechatOrderEntity();
if(!ObjectUtils.isEmpty(order)){
PayWechatOrderEntity wechatEntity;
if (!ObjectUtils.isEmpty(order)) {
wechatEntity = this.payWechatOrderService.getOne(new QueryWrapper<PayWechatOrderEntity>().eq("order_sn", order.getOrderSn()));
}else{
} else {
log.error("无效订单!");
return R.error(500,"无效订单!");
return R.error(500, "无效订单!");
}
// 1.根据订单id获取订单信息
if("order".equals(order.getOrderType())){
// 1.根据订单id获取订单信息
if ("order".equals(order.getOrderType())) {
BuyOrderEntity orderEntity = buyOrderService.getBaseMapper().selectOne(new QueryWrapper<BuyOrderEntity>().eq("order_sn", wechatEntity.getOrderSn()));
BigDecimal realMoney = orderEntity.getRealMoney();
//更新 订单 记录
// 1. 根据订单 ID 查询订单详情
// 2. 由订单详情获取商品信息
// 3. 查询商品信息得到 book_id
// 4. 查询用户的所有 book_id
// 5. 取差集
/*
list1.removeAll(list2)
*/
// 6. 为用户添加书籍
System.out.println("=========== 获取到 orderSn==================" + order.getOrderSn());
// 查询订单的所有 book_id
List<Integer> orderBookIdList = shopProudictBookService.getOrderBookId(order.getOrderSn());
System.out.println("=========== 获取到 orderBookIdList==========" + orderBookIdList);
// 去重
Set<Integer> set = new HashSet<>(orderBookIdList);
orderBookIdList.clear();
orderBookIdList.addAll(set);
// 查询用户的所有 book_id
System.out.println("==============去重后orderBookIdList=========" + orderBookIdList);
List<Integer> userBookIdList = userEbookBuyService.getUserBookId(order.getUserId());
System.out.println("==============userBookIdList===============" + userBookIdList);
// 取差集
orderBookIdList.removeAll(userBookIdList);
System.out.println("============== 差集========================" + orderBookIdList);
// 为用户添加书籍
List<UserEbookBuyEntity> userEbookBuyEntities = new ArrayList<>();
for (Integer bookId : orderBookIdList) {
UserEbookBuyEntity entity = new UserEbookBuyEntity();
entity.setUserId(order.getUserId());
entity.setBookId(bookId);
userEbookBuyEntities.add(entity);
}
System.out.println("============userEbookBuyEntities===========" + userEbookBuyEntities);
boolean b = userEbookBuyService.saveBatch(userEbookBuyEntities);
System.out.println("============result========================" + b);
if (wechatEntity.getTotalAmount().compareTo(realMoney) == 0) {
buyOrderService.updateOrderStatus(Integer.valueOf(order.getUserId()),order.getOrderSn(),"0");
buyOrderService.updateOrderStatus(order.getUserId(), order.getOrderSn(), "0");
}
}
if("point".equals(order.getOrderType())){
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();
Integer buyorder = buy_order_id.getBuyOrderId();
BookBuyConfigEntity bookBuyConfigEntity = bookBuyConfigService.getById(buyorder);
String realMoney =bookBuyConfigEntity.getRealMoney();
Integer money = Integer.valueOf(realMoney);
userService.rechargeHSPoint(Integer.valueOf(order.getUserId()),money);
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));
@@ -295,15 +299,15 @@ public class WeChatPayController {
transactionDetailsEntity.setRelationId(buy_order_id.getId().intValue());
transactionDetailsEntity.setRemark("充值");
MyUserEntity user = userService.getById(Integer.valueOf(order.getUserId()));
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(Integer.valueOf(order.getUserId()));
payPaymentOrderEntity.setUserId(order.getUserId());
payPaymentOrderEntity.setOrderId(String.valueOf(buy_order_id.getId()));
payPaymentOrderEntity.setRealAmount(new BigDecimal(bookBuyConfigEntity.getRealMoney()));
payPaymentOrderEntity.setRechargeAmount(new BigDecimal(bookBuyConfigEntity.getMoney()));
@@ -313,44 +317,32 @@ public class WeChatPayController {
payPaymentOrderEntity.setUserName(user.getNickname());
payPaymentOrderEntity.setTel(user.getTel());
payPaymentOrderService.save(payPaymentOrderEntity);
buyOrderService.updateOrderStatus(Integer.valueOf(order.getUserId()),order.getOrderSn(),"2");
buyOrderService.updateOrderStatus(order.getUserId(), order.getOrderSn(), "2");
}
} finally {
// 要主动释放锁
lock.unlock();
}
}
// 成功应答
// 成功应答
return R.ok();
}
private Map<String,Object> getNotifyBody(HttpServletRequest request ){
// 处理通知参数
private Map<String, Object> getNotifyBody(HttpServletRequest request) {
// 处理通知参数
String body = HttpUtils.readData(request);
log.info("zhifu回调参数:{}",body);
// 转换为Map
Map<String, Object> bodyMap = JSONObject.parseObject(body, new TypeReference<Map<String, Object>>(){});
// 微信的通知ID通知的唯一ID
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)){
WechatPayValidator wechatPayValidator = new WechatPayValidator(wechatPayConfig.getVerifier(), notifyId, body);
if (!wechatPayValidator.validate(request)) {
log.error("通知验签失败");
return null;
}
log.info("通知验签成功");
}catch (Exception e) {
} catch (Exception e) {
log.error(e.getMessage());
}
return bodyMap;
}
@@ -358,66 +350,58 @@ public class WeChatPayController {
@RequestMapping(value = "/placeAnOrder/shoppingpay")
@Transactional(rollbackFor = Exception.class)
public R shoppingpay(@RequestBody WechatDto dto ) throws Exception{
public R shoppingpay(@RequestBody WechatDto dto) throws Exception {
log.info("生成订单");
List<BuyOrderEntity> one = this.buyOrderService.getBaseMapper().selectList(new QueryWrapper<BuyOrderEntity>().eq("order_sn", dto.getOrderSn()));
BuyOrderEntity order = one.get(0);
// 获取订单
Map<String,Object> paramMap = new HashMap<>();
paramMap.put("appid",appId);
paramMap.put("mchid",mchId);
paramMap.put("description","微信充值");
// 订单编号
paramMap.put("out_trade_no",order.getOrderSn());
// paramMap.put("attach",""); //自定义数据 支付完成后才能显示 在查询API和支付通知中原样返回可作为自定义参数使用
paramMap.put("notify_url",wechatPayConfig.getNotifyUrl());
BigDecimal realsmoney= dto.getTotalAmount();
BigDecimal hand=new BigDecimal("100");
realsmoney =realsmoney.multiply(hand) ;
Map<String,Object> amountMap = new HashMap<>();
amountMap.put("total",realsmoney);
amountMap.put("currency","CNY");
paramMap.put("amount",amountMap);
// 获取订单
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("appid", appId);
paramMap.put("mchid", mchId);
paramMap.put("description", "微信充值");
// 订单编号
paramMap.put("out_trade_no", order.getOrderSn());
paramMap.put("notify_url", wechatPayConfig.getNotifyUrl());
BigDecimal realsmoney = dto.getTotalAmount();
BigDecimal hand = new BigDecimal("100");
realsmoney = realsmoney.multiply(hand);
Map<String, Object> amountMap = new HashMap<>();
amountMap.put("total", realsmoney);
amountMap.put("currency", "CNY");
paramMap.put("amount", amountMap);
JSONObject json = JSONObject.parseObject(JSON.toJSONString(paramMap));
log.info("请求参数"+paramMap);
log.info("请求参数" + paramMap);
com.alibaba.fastjson.JSONObject jsonObject1 = wxPayUtil.doPostWexinV3("https://api.mch.weixin.qq.com/v3/pay/transactions/app", json.toJSONString());
String prepayid = jsonObject1.getString("prepay_id");
// 传入参数 payUrl 发送post请求
// 传入参数 payUrl 发送post请求
HttpPost httpPost = new HttpPost(payUrl);
// 将json数据转换成字符串
StringEntity entity = new StringEntity(json.toString(),"utf-8");
// 设置该请求的Content-Type为application/json 都是json格式
// 将json数据转换成字符串
StringEntity entity = new StringEntity(json.toString(), "utf-8");
// 设置该请求的Content-Type为application/json 都是json格式
entity.setContentType("application/json");
// 将实体对象设置到HttpPost表示要传递该数据到服务器端。
// 将实体对象设置到HttpPost表示要传递该数据到服务器端。
httpPost.setEntity(entity);
// 设置请求头部的Accept属性为"application/json"表示客户端希望接收的为json。
// 设置请求头部的Accept属性为"application/json"表示客户端希望接收的为json。
httpPost.setHeader("Accept", "application/json");
CloseableHttpResponse response = wxPayClient.execute(httpPost);
// 向微信支付平台发送请求,处理响应结果,并将订单信息保存到数据库中。
// 向微信支付平台发送请求,处理响应结果,并将订单信息保存到数据库中。
String bodyAsString = EntityUtils.toString(response.getEntity());//响应体
// 时间戳
Long timestamp = System.currentTimeMillis()/1000;
// 随机串
String nonceStr = UUID.randomUUID().toString().replace("-","");
String sign = wxPayUtil.getSign(WxPayUtil.appId,timestamp,nonceStr,prepayid);
log.info("签名:"+sign);
Map Map = new HashMap();
Map.put("prepayid",prepayid);
Map.put("timestamp",timestamp+"");
Map.put("noncestr",nonceStr);
Map.put("sign",sign);
Map.put("appid",appId);
Map.put("package","Sign=WXPay");
Map.put("extData","sign");
Map.put("partnerid",mchId);
// 时间戳
long timestamp = System.currentTimeMillis() / 1000;
// 随机串
String nonceStr = UUID.randomUUID().toString().replace("-", "");
String sign = wxPayUtil.getSign(WxPayUtil.appId, timestamp, nonceStr, prepayid);
log.info("签名:" + sign);
Map<String, Object> map = new HashMap<>();
map.put("prepayid", prepayid);
map.put("timestamp", timestamp + "");
map.put("noncestr", nonceStr);
map.put("sign", sign);
map.put("appid", appId);
map.put("package", "Sign=WXPay");
map.put("extData", "sign");
map.put("partnerid", mchId);
try {
int statusCode = response.getStatusLine().getStatusCode(); //响应状态码
if (statusCode == 200) { //处理成功
@@ -433,22 +417,17 @@ public class WeChatPayController {
wechat.setPayType(order.getOrderType()); //交易类型
wechat.setOrderId(order.getOrderSn()); //订单号
wechat.setBuyOrderId(dto.getBuyOrderId()); //购买配置id
// wechat.setEndtime(after);
this.payWechatOrderService.save(wechat); //微信订单表拿到数据保存数据库
} else if (statusCode == 204) { //处理成功无返回Body
System.out.println("成功");
} else {
System.out.println("下单失败 = " + statusCode + ",返回结果 = " + bodyAsString);
throw new IOException("request failed");
}
}finally {
} finally {
response.close();
}
// 返回url和订单号
return R.ok().put("paramMap" ,paramMap).put("Map",Map);
// 返回url和订单号
return R.ok().put("paramMap", paramMap).put("Map", map);
}
}

View File

@@ -32,12 +32,12 @@ import java.util.Base64;
public static final String apiV3Key = "4aYFklzaULeGlr7oJPZ6rHWKcxjihZUF"; // apiV3秘钥
//商户私钥路径
public static final String privateKeyUrl = "/usr/local/hs/peanut_book/target/classes/cent/apiclient_key.pem";
// public static final String privateKeyUrl = "C:/Users/Administrator/IdeaProjects/peanut_book/src/main/resources/cent/apiclient_key.pem";
// public static final String privateKeyUrl = "/usr/local/hs/peanut_book/target/classes/cent/apiclient_key.pem";
public static final String privateKeyUrl = "C:/Users/Cauchy/IdeaProjects/nuttyreading-java/src/main/resources/cent/apiclient_key.pem";
//平台证书路径
public static final String wechatPayCertificateUrl = "/usr/local/hs/peanut_book/target/classes/cent/wechatpay_7B5676E3CDF56680D0414A009CE501C844DBE2D6.pem";
// public static final String wechatPayCertificateUrl = "C:/Users/Administrator/IdeaProjects/peanut_book/src/main/resources/cent/wechatpay_7B5676E3CDF56680D0414A009CE501C844DBE2D6.pem";
// public static final String wechatPayCertificateUrl = "/usr/local/hs/peanut_book/target/classes/cent/wechatpay_7B5676E3CDF56680D0414A009CE501C844DBE2D6.pem";
public static final String wechatPayCertificateUrl = "C:/Users/Cauchy/IdeaProjects/nuttyreading-java/src/main/resources/cent/wechatpay_7B5676E3CDF56680D0414A009CE501C844DBE2D6.pem";
//第一步申请完证书后在API证书哪里点击管理证书就能看到
public static final String mchSerialNo = "679AECB2F7AC4183033F713828892BA640E4EEE3"; // 商户证书序列号

View File

@@ -3,7 +3,7 @@ spring:
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
# url: jdbc:mysql://59.110.212.44:3306/e_book?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
# url: jdbc:mysql://59.110.212.44:3306/e_book?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
url: jdbc:mysql://59.110.212.44:3306/e_book_test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: HSXY1234hsxy

View File

@@ -12,7 +12,7 @@ connection-timeout: 6000000ms
spring:
# 环境 dev|test|prod
profiles:
active: dev
active: prod
# jackson时间格式化
jackson:
time-zone: GMT+8

View File

@@ -13,18 +13,13 @@
<result property="bookdIds" column="book_ids"/>
</resultMap>
<!--
SELECT
spb.*
FROM
shop_proudict_book spb
<select id="getOrderBookId" parameterType="string" resultType="int">
SELECT spb.book_id
FROM shop_proudict_book spb
LEFT JOIN buy_order_detail bod ON spb.proudict_id = bod.product_id
LEFT JOIN buy_order bo ON bo.order_id = bod.order_id
WHERE
bo.order_sn = '202305291720149121663113008012001282'
-->
WHERE bo.order_sn = #{orderSn}
</select>
</mapper>

View File

@@ -16,9 +16,9 @@
<result property="author" column="author"/>
</resultMap>
<!--
select book_id from user_ebook_buy where user_id = '10169'
-->
<select id="getUserBookId" parameterType="int" resultType="int">
SELECT book_id
FROM user_ebook_buy
WHERE user_id = #{userId}
</select>
</mapper>

View File

@@ -1,50 +1,48 @@
wxpay:
#应用编号
# ????
wxpay.appId: wx47134a8f15083734
#商户号
# ???
wxpay.mchId: 1612860909
# APIv3密钥
# API v3 ??
wxpay.apiV3Key: 4aYFklzaULeGlr7oJPZ6rHWKcxjihZUF
# 微信支付V3-url前缀
# v3 - url
wxpay.baseUrl: https://api.mch.weixin.qq.com/v3
#po9k1ezoyexk.ngrok.xiaomiqiu123.top 内网穿透地址 测试ok 正式环境下切换服务器地址
#po9k1ezoyexk.ngrok.xiaomiqiu123.top # ????????
#wxpay.notifyUrl: http://101.201.146.165:9100
wxpay.notifyUrl: http://59.110.212.44:9100/pb/pay/payNotify
# 退款通知回调, pjm6m9.natappfree.cc 为内网穿透地址
# ??????
wxpay.refundNotifyUrl: http://pjm6m9.natappfree.cc/pay/refundNotify
# 密钥路径,resources下 /usr/local/hs/peanut_book/target/classes/cent/apiclient_key.pem
# ???? /usr/local/hs/peanut_book/target/classes/cent/apiclient_key.pem
wxpay.keyPemPath:C:/Users/Administrator/IdeaProjects/peanut_book/src/main/resources/cent/apiclient_key.pem
wxpay.keyPemPath:C:/Users/Cauchy/IdeaProjects/nuttyreading-java/src/main/resources/cent/apiclient_key.pem
#wxpay.keyPemPath:D:/hs/nuttyreading-java/src/main/resources/cent/apiclient_key.pem
#商户证书序列号
#???????
wxpay.serialNo: 679AECB2F7AC4183033F713828892BA640E4EEE3
#微信服务器地址
#???????
wxpay.domain: https://api.mch.weixin.qq.com
#wxpay:
##应用编号
##????
#wxpay.appId: wx47134a8f15083734
##商户号
##???
#wxpay.mchId: 1612860909
## APIv3密钥
## APIv3??
#wxpay.apiV3Key: 4aYFklzaULeGlr7oJPZ6rHWKcxjihZUF
## 微信支付V3-url前缀
## ????V3-url??
#wxpay.baseUrl: https://api.mch.weixin.qq.com/v3
##po9k1ezoyexk.ngrok.xiaomiqiu123.top 内网穿透地址 测试ok 正式环境下切换服务器地址
##po9k1ezoyexk.ngrok.xiaomiqiu123.top ?????? ??ok ????????????
#
##wxpay.notifyUrl: http://101.201.146.165:9100
#
#wxpay.notifyUrl: http://59.110.212.44:9100/pb/pay/payNotify
#
## 退款通知回调, pjm6m9.natappfree.cc 为内网穿透地址
## ??????, pjm6m9.natappfree.cc ???????
#wxpay.refundNotifyUrl: http://pjm6m9.natappfree.cc/pay/refundNotify
## 密钥路径,resources /usr/local/hs/peanut_book/target/classes/cent/apiclient_key.pem
## ????,resources? /usr/local/hs/peanut_book/target/classes/cent/apiclient_key.pem
#
#wxpay.keyPemPath:/usr/local/hs/peanut_book/target/classes/cent/apiclient_key.pem
##商户证书序列号
##???????
#wxpay.serialNo: 679AECB2F7AC4183033F713828892BA640E4EEE3
##微信服务器地址
##???????
#wxpay.domain: https://api.mch.weixin.qq.com