在写这部分代码的时候可以参考支付模块中会出现的问题,怎么解决?
当中运用到redis的地方有很多,大家可以给redis做持久化和集群办证数据不丢失
调用支付宝后我这边根据实际情况做了一些更改
public void alipay() throws AlipayApiException {
String privateKey = "<-- 沙箱帐号的应用私钥 -->";
String alipayPublicKey = "<-- 沙箱帐号的支付宝公钥 -->";
AlipayConfig alipayConfig = new AlipayConfig();
alipayConfig.setServerUrl("https://openapi-sandbox.dl.alipaydev.com/gateway.do");
alipayConfig.setAppId("<-- 沙箱帐号的AppId -->");
alipayConfig.setPrivateKey(privateKey);
alipayConfig.setFormat("json");
alipayConfig.setAlipayPublicKey(alipayPublicKey);
alipayConfig.setCharset("UTF-8");
alipayConfig.setSignType("RSA2");
//redis获取房屋信息
HousesEntity housesEntity = JSONObject.parseObject(redisCache.getCacheObject(TokenConstants.TOKEN+"Houses"), HousesEntity.class);
AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
AlipayTradePagePayModel model = new AlipayTradePagePayModel();
//获取签名
String sign = housesEntity.getSign();
request.setNotifyUrl(sign);
String only = UUID.randomUUID().toString().replaceAll("-", "");
model.setOutTradeNo(only);
String housesPrice = String.valueOf(housesEntity.getHousesPrice());
model.setTotalAmount(housesPrice);
String housesName = housesEntity.getHousesName();
model.setSubject(housesName);
model.setProductCode("FAST_INSTANT_TRADE_PAY");
request.setBizModel(model);
//AlipayTradePagePayResponse response = alipayClient.pageExecute(request, "POST");
// 如果需要返回GET请求,请使用
AlipayTradePagePayResponse response = alipayClient.pageExecute(request, "GET");
String pageRedirectionData = response.getBody();
System.out.println(pageRedirectionData);
if (response.isSuccess()) {
System.out.println("调用成功");
//回调订单,将订单状态改为已支付
//设计幂等使用redis实现
//在将请求放入缓存之前,判断是否有相同的请求存在
if (redisCache.getCacheObject(TokenConstants.TOKEN+only) != null){
throw new RuntimeException("已支付");
}
//使用redis来存储和处理请求
redisCache.setCacheObject(TokenConstants.TOKEN+only,housesEntity,TokenConstants.EXPIRATION, TimeUnit.HOURS);
//回调接口安全问题
//通过发送者请求中的签名判断验证签名
//签名验证
boolean verify = AlipaySignature.rsaCheckV2(response.getParams(), alipayConfig.getAlipayPublicKey(), alipayConfig.getCharset(), alipayConfig.getSignType());
if (verify){
//更新订单状态
orderService.updateById(OrderEntity.builder()
.orderId(only)
.orderPayMoney(BigDecimal.valueOf(10))
.orderPayTime(new Date())
.orderStart(1)
.build());
}
} else {
System.out.println("调用失败");
// sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
// String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
// System.out.println(diagnosisUrl);
}
}
然后这里是我写下单并且支付的一个方法
@SneakyThrows
@Override
public Result releaseTwoHandHouses(HousesEntity housesEntity){
// 获取当前登录用户信息
UserInfoEntity info = this.info();
// 创建新的订单实体对象
OrderEntity orderEntity = new OrderEntity();
// 检查用户余额是否充足
if (info.getUserBalance().compareTo(BigDecimal.valueOf(10)) < 0) {
throw new RuntimeException("余额不足");
}
// 设置房屋类型和发布者ID
housesEntity.setHousesType("二手房");
housesEntity.setPublisherId(info.getUserId());
// 更新当前登录用户的余额
UserInfoEntity updatedUserInfo = userInfoService.getById(info.getUserId());
updatedUserInfo.setUserBalance(updatedUserInfo.getUserBalance().subtract(BigDecimal.valueOf(10)));
// 生成唯一用户Key并创建Token
String userKey = UUID.randomUUID().toString().replace("-", "");
HashMap<String, Object> tokenData = new HashMap<>();
tokenData.put(JwtConstants.USER_KEY, userKey);
String token = JwtUtils.createToken(tokenData);
// 将房屋实体存入Redis,并设置Token过期时间
redisCache.setCacheObject(TokenConstants.TOKEN + userKey, housesEntity, TokenConstants.EXPIRATION, TimeUnit.HOURS);
// 防止重复提交订单
if (redisCache.getCacheObject(TokenConstants.TOKEN + userKey) != null) {
throw new RuntimeException("订单已提交");
}
// 保存订单信息
orderEntity.builder()
.orderName("发布二手房")
.orderTel(info.getUserPhone())
.orderType("发布二手房")
.orderPayMoney(BigDecimal.valueOf(10))
.orderPayTime(new Date())
.orderUserId(info.getUserId())
.orderStart(2)
.build();
orderService.save(orderEntity);
//生成签名
// String sign = AlipaySignature.rsaSign(JSONObject.toJSONString(housesEntity), "RSA2", "utf-8", "RSA2");
String sign = "123456";
/**
* 发送方将需要传输的数据
* 使用预共享的密钥(如API密钥)和加密算法(如HMAC-SHA256)对数据进行签名,生成一个签名值
* 将签名值附加到请求数据中,一起发送给接收方。
*/
housesEntity.setSign(sign);
// 存储房屋信息到Redis
redisCache.setCacheObject(TokenConstants.TOKEN + "Houses", JSONObject.toJSONString(housesEntity), TokenConstants.EXPIRATION, TimeUnit.HOURS);
// 执行支付宝相关操作(假设这个方法用于处理支付逻辑)
this.alipay();
// 更新用户余额信息
userInfoService.updateById(updatedUserInfo);
// 保存房屋实体
this.save(housesEntity);
// 返回发布成功的响应结果
return Result.success("发布成功");
}
这整个过程中都是使用mybatis-plus进行数据库的更改(后续也会发布一个关于mybatis-plus的文章供大家参考)