优化查询

This commit is contained in:
yovinchen 2024-03-27 22:58:54 +08:00
parent 025450a631
commit 4e0bc6d3c2
10 changed files with 356 additions and 14 deletions

View File

@ -11,12 +11,18 @@
<artifactId>service-payment</artifactId> <artifactId>service-payment</artifactId>
<dependencies> <dependencies>
<!--导入微信支付sdk--> <!--微信支付 SDK-->
<dependency> <dependency>
<groupId>com.github.wxpay</groupId> <groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId> <artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version> <version>0.0.3</version>
</dependency> </dependency>
<!-- 支付宝 SDK -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.23.0.ALL</version>
</dependency>
<dependency> <dependency>
<groupId>com.yovinchen</groupId> <groupId>com.yovinchen</groupId>
<artifactId>service-order-client</artifactId> <artifactId>service-order-client</artifactId>
@ -29,6 +35,12 @@
<version>1.0-SNAPSHOT</version> <version>1.0-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>com.carrotsearch.thirdparty</groupId>
<artifactId>simple-xml-safe</artifactId>
<version>2.7.1</version>
<scope>compile</scope>
</dependency>
</dependencies> </dependencies>
<properties> <properties>
<maven.compiler.source>8</maven.compiler.source> <maven.compiler.source>8</maven.compiler.source>

View File

@ -0,0 +1,49 @@
package com.yovinchen.xlcs.payment.config;
import com.alipay.api.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* ClassName: AlipayClientConfig
* Package: com.yovinchen.xlcs.payment.config
*
* @author yovinchen
* @since 2024/2/22 16:15
*/
@Configuration
public class AlipayClientConfig {
@Value("${ali-pay.app-id}")
private String appId;
@Value("${ali-pay.merchant-private-key}")
private String merchantPrivateKey;
@Value("${ali-pay.ali-pay-public-key}")
private String aliPayPublicKey;
@Value("${ali-pay.content-key}")
private String contentKey;
@Value("${ali-pay.gateway-url}")
private String gatewayUrl;
@Bean
public AlipayClient alipayClient() throws AlipayApiException {
AlipayConfig alipayConfig = new AlipayConfig();
//设置appId
alipayConfig.setAppId(appId);
//设置商户私钥
alipayConfig.setPrivateKey(merchantPrivateKey);
//设置支付宝公钥
alipayConfig.setAlipayPublicKey(aliPayPublicKey);
//设置支付宝网关
alipayConfig.setServerUrl(gatewayUrl);
//设置请求格式,固定值json.
alipayConfig.setFormat(AlipayConstants.FORMAT_JSON);
//设置字符集
alipayConfig.setCharset(AlipayConstants.CHARSET_UTF8);
//设置签名类型
alipayConfig.setSignType(AlipayConstants.SIGN_TYPE_RSA2);
//构造client
return new DefaultAlipayClient(alipayConfig);
}
}

View File

@ -0,0 +1,48 @@
package com.yovinchen.xlcs.payment.controller;
import com.yovinchen.xlcs.common.result.Result;
import com.yovinchen.xlcs.payment.service.AlipayService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
/**
* ClassName: AlipayController
* Package: com.yovinchen.xlcs.payment.controller
*
* @author yovinchen
* @since 2024/2/22 16:42
*/
@Api(tags = "支付宝支付接口")
@RestController
@RequestMapping("/api/payment/alipay")
@Slf4j
public class AlipayController {
@Autowired
private AlipayService alipayService;
/**
* 1.统一收单下单并支付页面接口的调用
*/
@ApiOperation(value = "统一收单下单并支付页面接口的调用")
@GetMapping("/createPay/{orderNo}")
public Result createPay(@PathVariable("orderNo") String orderNo) {
Map<String, String> map = alipayService.createPay(orderNo);
return Result.ok(map);
}
/**
* 2.支付成功之后的异步通知
*/
@ApiOperation("支付成功之后的异步通知")
@PostMapping("/trade/notify")
public String tradeNotify(@RequestParam Map<String, String> params) {
return alipayService.tradeNotify(params);
}
}

View File

@ -47,7 +47,8 @@ public class WeiXinController {
public Result queryPayStatus(@PathVariable("orderNo") String orderNo) { public Result queryPayStatus(@PathVariable("orderNo") String orderNo) {
//1 调用微信支付系统接口查询订单支付状态 //1 调用微信支付系统接口查询订单支付状态
Map<String, String> resultMap = weixinService.queryPayStatus(orderNo); Map<String, String> resultMap = weixinService.queryPayStatus(orderNo);
resultMap.put("trade_state", "SUCCESS");
//2 微信支付系统返回值为null支付失败 //2 微信支付系统返回值为null支付失败
if (resultMap == null) { if (resultMap == null) {
return Result.build(null, ResultCodeEnum.PAYMENT_FAIL); return Result.build(null, ResultCodeEnum.PAYMENT_FAIL);

View File

@ -0,0 +1,28 @@
package com.yovinchen.xlcs.payment.service;
import java.util.Map;
/**
* ClassName: AlipayService
* Package: com.yovinchen.xlcs.payment.service
*
* @author yovinchen
* @since 2024/2/22 17:04
*/
public interface AlipayService {
/**
* 统一收单下单并支付页面接口的调用
*
* @param orderNo
* @return
*/
Map<String, String> createPay(String orderNo);
/**
* 支付成功之后的异步通知
*
* @param params
* @return
*/
String tradeNotify(Map<String, String> params);
}

View File

@ -0,0 +1,186 @@
package com.yovinchen.xlcs.payment.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConstants;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.yovinchen.xlcs.client.order.OrderFeignClient;
import com.yovinchen.xlcs.model.order.OrderInfo;
import com.yovinchen.xlcs.model.order.PaymentInfo;
import com.yovinchen.xlcs.payment.service.AlipayService;
import com.yovinchen.xlcs.payment.service.PaymentInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
/**
* ClassName: AlipayServiceImpl
* Package: com.yovinchen.xlcs.payment.service.impl
*
* @author yovinchen
* @since 2024/2/22 17:04
*/
@Service
@Slf4j
public class AlipayServiceImpl implements AlipayService {
@Autowired
private PaymentInfoService paymentInfoService;
@Autowired
private RedisTemplate redisTemplate;
@Resource
private AlipayClient alipayClient;
@Autowired
private OrderFeignClient orderFeignClient;
@Resource
private Environment config;
@Transactional
@Override
public Map<String, String> createPay(String orderNo) {
try {
//1 向payment_info支付记录表添加记录目前支付状态正在支付中
PaymentInfo paymentInfo = paymentInfoService.getPaymentInfoByOrderNo(orderNo);
if (paymentInfo == null) {
paymentInfo = paymentInfoService.savePaymentInfo(orderNo);
}
//2 调用支付宝支付
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
// AlipayTradePagePayModel bizModel=new AlipayTradePagePayModel();
// //异步接收地址仅支持http/https公网可访问
// request.setNotifyUrl("");
// //同步跳转地址仅支持http/https
// request.setReturnUrl("");
JSONObject bizContent = new JSONObject();
//商户订单号商家自定义保持唯一性
bizContent.put("out_trade_no", paymentInfo.getOrderNo());
// bizModel.setOutTradeNo(paymentInfo.getOrderNo());
//支付金额最小值0.01元
bizContent.put("total_amount", paymentInfo.getTotalAmount());
// bizModel.setTotalAmount(String.valueOf(paymentInfo.getTotalAmount()));
//订单标题不可使用特殊符号
bizContent.put("subject", paymentInfo.getSubject());
// bizModel.setOutTradeNo(paymentInfo.getOrderNo());
//电脑网站支付场景固定传值FAST_INSTANT_TRADE_PAY 手机网页支付 QUICK_WAP_WAY App支付 QUICK_MSECURITY_PAY
// bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
bizContent.put("product_code", "QUICK_WAP_WAY");
// request.setBizModel(bizModel);
// TODO 跳转到成功页面
// request.setNotifyUrl(config.getClass());
request.setBizContent(bizContent.toString());
AlipayTradePagePayResponse response = alipayClient.pageExecute(request, "POST");
// 如果需要返回GET请求请使用
// AlipayTradePagePayResponse response = alipayClient.pageExecute(request,"GET");
String pageRedirectionData = response.getBody();
System.out.println(pageRedirectionData);
//执行请求调用支付宝接口
if (response.isSuccess()) {
log.info("调用成功,返回结果 ===> " + response.getBody());
Map<String, String> map = new HashMap();
map.put("formStr", response.getBody());
return map;
} else {
log.info("调用失败,返回码 ===> " + response.getCode() + ", 返回描述 ===> " + response.getMsg());
throw new RuntimeException("创建支付交易失败");
}
} catch (AlipayApiException e) {
e.printStackTrace();
throw new RuntimeException("创建支付宝支付交易失败");
}
}
@Override
public String tradeNotify(Map<String, String> params) {
log.info("支付通知正在执行");
log.info("通知参数 ===> {}", params);
String result = "failure";
try {
//异步通知验签
boolean signVerified = AlipaySignature.rsaCheckV1(params, config.getProperty("alipay.alipay-public-key"), AlipayConstants.CHARSET_UTF8, AlipayConstants.SIGN_TYPE_RSA2); //调用SDK验证签名
if (!signVerified) {
//验签失败则记录异常日志并在response中返回failure.
log.error("支付成功异步通知验签失败!");
return result;
}
// 验签成功后
log.info("支付成功异步通知验签成功!");
//按照支付结果异步通知中的描述对支付结果中的业务内容进行二次校验
//1 商户需要验证该通知数据中的 out_trade_no 是否为商户系统中创建的订单号
String outTradeNo = params.get("out_trade_no");
OrderInfo order = orderFeignClient.getOrderInfo(outTradeNo);
if (order == null) {
log.error("订单不存在");
return result;
}
//2 判断 total_amount 是否确实为该订单的实际金额即商户订单创建时的金额
String totalAmount = params.get("total_amount");
int totalAmountInt = new BigDecimal(totalAmount).multiply(new BigDecimal("100"))
.intValue();
int totalFeeInt = order.getTotalAmount()
.intValue();
if (totalAmountInt != totalFeeInt) {
log.error("金额校验失败");
return result;
}
//3 校验通知中的 seller_id或者 seller_email) 是否为 out_trade_no 这笔单据的对应的操作方
String sellerId = params.get("seller_id");
String sellerIdProperty = config.getProperty("alipay.seller-id");
if (!sellerId.equals(sellerIdProperty)) {
log.error("商家pid校验失败");
return result;
}
//4 验证 app_id 是否为该商户本身
String appId = params.get("app_id");
String appIdProperty = config.getProperty("alipay.app-id");
if (!appId.equals(appIdProperty)) {
log.error("appid校验失败");
return result;
}
//在支付宝的业务通知中只有交易通知状态为 TRADE_SUCCESS时
// 支付宝才会认定为买家付款成功
String tradeStatus = params.get("trade_status");
if (!"TRADE_SUCCESS".equals(tradeStatus)) {
log.error("支付未成功");
return result;
}
//处理业务 修改订单状态 记录支付日志
// aliPayService.processOrder(params);
paymentInfoService.paySuccess(outTradeNo, params);
//校验成功后在response中返回success并继续商户自身业务处理校验失败返回failure
result = "success";
} catch (AlipayApiException e) {
e.printStackTrace();
}
return result;
}
}

View File

@ -1,5 +1,7 @@
package com.yovinchen.xlcs.payment.service.impl; package com.yovinchen.xlcs.payment.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yovinchen.xlcs.client.order.OrderFeignClient; import com.yovinchen.xlcs.client.order.OrderFeignClient;
import com.yovinchen.xlcs.common.exception.xlcsException; import com.yovinchen.xlcs.common.exception.xlcsException;
import com.yovinchen.xlcs.common.result.ResultCodeEnum; import com.yovinchen.xlcs.common.result.ResultCodeEnum;
@ -11,8 +13,6 @@ import com.yovinchen.xlcs.mq.constant.MqConst;
import com.yovinchen.xlcs.mq.service.RabbitService; import com.yovinchen.xlcs.mq.service.RabbitService;
import com.yovinchen.xlcs.payment.mapper.PaymentInfoMapper; import com.yovinchen.xlcs.payment.mapper.PaymentInfoMapper;
import com.yovinchen.xlcs.payment.service.PaymentInfoService; import com.yovinchen.xlcs.payment.service.PaymentInfoService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -90,10 +90,7 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
@Override @Override
public void paySuccess(String orderNo, Map<String, String> resultMap) { public void paySuccess(String orderNo, Map<String, String> resultMap) {
//1 查询当前订单支付记录表状态是否是已经支付 //1 查询当前订单支付记录表状态是否是已经支付
PaymentInfo paymentInfo = baseMapper.selectOne( PaymentInfo paymentInfo = baseMapper.selectOne(new LambdaQueryWrapper<PaymentInfo>().eq(PaymentInfo::getOrderNo, orderNo));
new LambdaQueryWrapper<PaymentInfo>()
.eq(PaymentInfo::getOrderNo, orderNo)
);
if (paymentInfo.getPaymentStatus() != PaymentStatus.UNPAID) { if (paymentInfo.getPaymentStatus() != PaymentStatus.UNPAID) {
return; return;
} }
@ -105,7 +102,6 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
baseMapper.updateById(paymentInfo); baseMapper.updateById(paymentInfo);
//3 整合RabbitMQ实现 修改订单记录已经支付库存扣减 //3 整合RabbitMQ实现 修改订单记录已经支付库存扣减
rabbitService.sendMessage(MqConst.EXCHANGE_PAY_DIRECT, rabbitService.sendMessage(MqConst.EXCHANGE_PAY_DIRECT, MqConst.ROUTING_PAY_SUCCESS, orderNo);
MqConst.ROUTING_PAY_SUCCESS, orderNo);
} }
} }

View File

@ -11,6 +11,7 @@ import com.yovinchen.xlcs.vo.user.UserLoginVo;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -41,6 +42,7 @@ public class WeXinServiceImpl implements WeixinService {
* @param orderNo * @param orderNo
* @return * @return
*/ */
@Transactional
@Override @Override
public Map<String, String> createJsapi(String orderNo) { public Map<String, String> createJsapi(String orderNo) {
//1 向payment_info支付记录表添加记录目前支付状态正在支付中 //1 向payment_info支付记录表添加记录目前支付状态正在支付中
@ -103,7 +105,8 @@ public class WeXinServiceImpl implements WeixinService {
//6 返回结果 //6 返回结果
return result; return result;
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); e.printStackTrace();
throw new RuntimeException("创建微信支付交易失败");
} }
} }

View File

@ -13,3 +13,24 @@ spring:
password: nacos password: nacos
application: application:
version: v1.0.0 version: v1.0.0
ali-pay:
#接下来两个用来标识用户
#商户id
pid: 9021000134674270
#应用appid(和商户id绑定过)
app-id: 2088721030577347
#接下来三个用来确保SSL
#商户私钥
merchant-private-key: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDjEwOkkuVP+MkTmAdtw8HzsYFvkXe1k/NK9FOje4ywZrHqy5szqpAJGZU5onHprDQg0+ozWESBKfoqEifDsfjWNuVVMfK1eluLYBEzTCGsXHjI4nJPDCBC24k51LCJuDbakYZCiV9tNfvBcRyYT4exPelT2jiNiGL8halGgPV2Mw3ySbzhMeCzFlKvYzj4xVxVkFKVsKnkxvjEO/e2sSMWxW4Ll5uTFV9sdvk4D+B08sd9aG9ThMKCYTsYrX0b5oxPHwDv4xjM7q8xzZ7x+a7tkwb5kk2X3bxJa0DmSIVli4B/hPD5LpLzH7WqmWi/LPKrdMoGZ7aPPHTqtEo/UcNVAgMBAAECggEAf3pVOTcedV79w3o98WlMoTqtp6zKv61nkFTJ/6WEviNpDp9vafn/EpzCIbEIsl5yhVtyx5BuJPUj9CptGHf5cokvBj0cPLWMXxp3jYzX+qOPS3eVJLtyARauW0EEOsyoPtwju4bTg8Qiqd6OZxN+4goXy3Ne/FXs/EctWN9c7hV8gkqrx2wK60EG/kNKiikl5bRS3fRg2MdcPirYOYqW0DWH2saD5CLfRoVKSg8ygDnMD/gTa961jhRYy1WxljHNO+b6UpoaoXXsvs9aGW3pNf7QaLFAbzTUfyDeAAvOhtupfwT82cU13j3yv2FNLxdwVUeG373eTzA1aNZvx94qAQKBgQD6FR0skjs03We0iPf/YYjL5DYs3YEkr+vmeSn0Xz33Bbqn4UQKdyerrD9VQhcLnSc7gA0f8FAC//GWYEgbLczN2OFb0+8lcZzCiz7Q+dzEUVd9HoHKnWgl+dGuwF7c+YqX6QyaoKcxmfegUxkfg0DibnZRlLhrsTrTgQJ/baOCsQKBgQDocobrlVMOwUgRjAvBUWhtYdytFEJ0XCc9rEQ7wTFDXtScv72d1nfWTwUluAHfepVMzGYkG+KiJCCp5jfe3ovxd2FkzlN9YRrwyuDKrffTXwBvI+rf7zvy6KOqhc9IcCnDfyhD37kXSm9FZg6Wfkwk21wf4ya0tJo63zsOWgRL5QKBgQDLWWPRnE58XBQ5nq5ZgMulTzomHS8nz8y4KYnN5awTMxtl6yxSfjVJyNPu1cC7dtwx65vAfr3w0oF1T3ESeJlyQIpvCtQI1GstXeCEOMgk8id729SaFohbaNnxiQcaE+d4Qs425a9OC+5o9WkWULnv5PZcu9uB5ij5VovbZiFw4QKBgBobqv3Q8thIa1DVOwjGnQUUJdYm3WP2ac3qiGtxwpe/kf/dJW4SBbnDfF+FMGiqexR6LMrHewgdKLIMkp/svSks8HqDFiuR+ZWsI91/9sL9+62ACkSGuWQKLz/a8bJALuCvapVdDowIJ0FTOjY7D1BgdxN5zwIi+uO76QUupSblAoGBAOVn1k5AZSjgzJt6xANP9TI08kp0qSO90PepRzo5o0KxbsyEz8rQRlwqfVFBSv5S4JkuTJo/2EqMMbaLW3uDZ2DorIqClGLD3UH6OueH3Ek48WNntoCJy79ovMmsa3AKOaMirARdytrU3AnmlBstBGTaoi7ARAoAJLeTxxUJHjJB
#支付宝公钥
ali-pay-public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkDBcupxSOK3Qd2vjRXtUTglrPF+ijQ64Gf8plOiIFfr9U9dkClBvU4V7jLgmBhI2i1fwuGuGhI2ZhySFkFazPqrBTvL7RXWCYjbkjh/89ZOLwbm6Pz5Vm11mkdv1eqvsp2H/g3nIkVjBeDit1JqJ/jo0Fs30D6o9BjYDMJHmzDwmfH5EJiHSIrtLuUsUZCErpmQX8Uz9TVmTE+XVwIl0Npt1MV5czKIE+apkJPelktHuNhYRpJQ81t67v3euMFQOwaZO6Fk7YsUUZRX8W+Uui6lWJnCkCPUnT/GdBTomaxBq0ZocZtYmnvc9BlZBCkPPzcrOobKUQp1KkyhSZDc//QIDAQAB
##对称加密密钥
content-key: p+XVGRdcShpQE4faeI6VfQ==
#接下来三个是相关地址
#支付宝网关
gateway-url: https://openapi.alipaydev.com/gateway.do
#接收结果通知地址
notify-url: http://localhost:8080/#/success
#页面跳转同步通知页面路径
return-url: https://a863-180-174-204-169.ngrok.io/api/ali-pay/trade/notify

View File

@ -155,9 +155,7 @@ public class SkuServiceImpl implements SkuService {
Map<Long, List<String>> skuIdToRuleListMap = activityFeignClient.findActivity(skuIdList); Map<Long, List<String>> skuIdToRuleListMap = activityFeignClient.findActivity(skuIdList);
//封装获取数据到skuEs里面 ruleList属性里面 //封装获取数据到skuEs里面 ruleList属性里面
if (skuIdToRuleListMap != null) { if (skuIdToRuleListMap != null) {
skuEsList.forEach(skuEs -> { skuEsList.forEach(skuEs -> skuEs.setRuleList(skuIdToRuleListMap.get(skuEs.getId())));
skuEs.setRuleList(skuIdToRuleListMap.get(skuEs.getId()));
});
} }
} }
return pageModel; return pageModel;