|
@@ -23,9 +23,12 @@ import shop.alien.dining.strategy.payment.PaymentStrategy;
|
|
|
import shop.alien.dining.util.WXPayUtility;
|
|
import shop.alien.dining.util.WXPayUtility;
|
|
|
import shop.alien.dining.util.WeChatPayUtil;
|
|
import shop.alien.dining.util.WeChatPayUtil;
|
|
|
import shop.alien.entity.result.R;
|
|
import shop.alien.entity.result.R;
|
|
|
|
|
+import shop.alien.entity.store.LifeDiscountCouponUser;
|
|
|
import shop.alien.entity.store.StoreOrder;
|
|
import shop.alien.entity.store.StoreOrder;
|
|
|
import shop.alien.entity.store.StorePaymentConfig;
|
|
import shop.alien.entity.store.StorePaymentConfig;
|
|
|
|
|
+import shop.alien.mapper.LifeDiscountCouponUserMapper;
|
|
|
import shop.alien.mapper.StorePaymentConfigMapper;
|
|
import shop.alien.mapper.StorePaymentConfigMapper;
|
|
|
|
|
+import shop.alien.util.common.constant.DiscountCouponEnum;
|
|
|
import shop.alien.util.common.constant.PaymentEnum;
|
|
import shop.alien.util.common.constant.PaymentEnum;
|
|
|
|
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import javax.servlet.http.HttpServletRequest;
|
|
@@ -36,6 +39,7 @@ import java.security.PrivateKey;
|
|
|
import java.security.PublicKey;
|
|
import java.security.PublicKey;
|
|
|
import java.security.Signature;
|
|
import java.security.Signature;
|
|
|
import java.util.Base64;
|
|
import java.util.Base64;
|
|
|
|
|
+import java.util.Date;
|
|
|
import java.util.HashMap;
|
|
import java.util.HashMap;
|
|
|
import java.util.List;
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
@@ -85,6 +89,7 @@ public class WeChatPaymentMininProgramStrategyImpl implements PaymentStrategy {
|
|
|
|
|
|
|
|
private final StoreOrderService storeOrderService;
|
|
private final StoreOrderService storeOrderService;
|
|
|
private final StorePaymentConfigMapper storePaymentConfigMapper;
|
|
private final StorePaymentConfigMapper storePaymentConfigMapper;
|
|
|
|
|
+ private final LifeDiscountCouponUserMapper lifeDiscountCouponUserMapper;
|
|
|
private final ObjectMapper objectMapper;
|
|
private final ObjectMapper objectMapper;
|
|
|
|
|
|
|
|
private static String POSTMETHOD = "POST";
|
|
private static String POSTMETHOD = "POST";
|
|
@@ -153,7 +158,7 @@ public class WeChatPaymentMininProgramStrategyImpl implements PaymentStrategy {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- public R createPrePayOrder(String price, String subject, String payer, String orderNo, Integer storeId) throws Exception {
|
|
|
|
|
|
|
+ public R createPrePayOrder(String price, String subject, String payer, String orderNo, Integer storeId, Integer couponId, Integer payerId) throws Exception {
|
|
|
// 本系统调用:通过 storeId 从 MySQL 获取店铺支付配置
|
|
// 本系统调用:通过 storeId 从 MySQL 获取店铺支付配置
|
|
|
if (storeId == null) {
|
|
if (storeId == null) {
|
|
|
log.warn("createPrePayOrder 缺少 storeId,无法获取支付配置");
|
|
log.warn("createPrePayOrder 缺少 storeId,无法获取支付配置");
|
|
@@ -181,12 +186,52 @@ public class WeChatPaymentMininProgramStrategyImpl implements PaymentStrategy {
|
|
|
request.appid = appId;
|
|
request.appid = appId;
|
|
|
request.mchid = mchId;
|
|
request.mchid = mchId;
|
|
|
request.description = subject;
|
|
request.description = subject;
|
|
|
- request.outTradeNo = orderNo;
|
|
|
|
|
request.notifyUrl = prePayNotifyUrl;
|
|
request.notifyUrl = prePayNotifyUrl;
|
|
|
request.amount = new CommonAmountInfo();
|
|
request.amount = new CommonAmountInfo();
|
|
|
request.amount.total = Long.parseLong(price);
|
|
request.amount.total = Long.parseLong(price);
|
|
|
request.payer = new JsapiReqPayerInfo();
|
|
request.payer = new JsapiReqPayerInfo();
|
|
|
request.payer.openid = payer;
|
|
request.payer.openid = payer;
|
|
|
|
|
+
|
|
|
|
|
+ String wechatOutTradeNo = orderNo;
|
|
|
|
|
+ StoreOrder storeOrder = storeOrderService.getOrderByOrderNo(orderNo);
|
|
|
|
|
+ if (storeOrder != null && StringUtils.hasText(storeOrder.getPayTradeNo())) {
|
|
|
|
|
+ if (storeOrder.getPayStatus() != null && storeOrder.getPayStatus() == 1) {
|
|
|
|
|
+ return R.fail("订单已支付");
|
|
|
|
|
+ }
|
|
|
|
|
+ PublicKey publicKey = loadPublicKeyFromConfig(config);
|
|
|
|
|
+ if (publicKey == null) {
|
|
|
|
|
+ return R.fail("店铺微信支付公钥未配置或加载失败");
|
|
|
|
|
+ }
|
|
|
|
|
+ QueryByWxTradeNoRequest q = new QueryByWxTradeNoRequest();
|
|
|
|
|
+ q.transactionId = storeOrder.getPayTradeNo();
|
|
|
|
|
+ q.mchid = mchId;
|
|
|
|
|
+ try {
|
|
|
|
|
+ DirectAPIv3QueryResponse wxOrder = searchOrderRun(q, config, privateKey, publicKey);
|
|
|
|
|
+ if (wxOrder != null && "SUCCESS".equals(wxOrder.tradeState)) {
|
|
|
|
|
+ return R.fail("该支付单已在微信侧支付成功,请勿重复发起支付");
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (WXPayUtility.ApiException e) {
|
|
|
|
|
+ if (e.getStatusCode() != 404 && !"ORDER_NOT_EXIST".equals(e.getErrorCode())) {
|
|
|
|
|
+ log.error("预支付前查询微信订单失败 out_trade_no={}, status={}, code={}, msg={}",
|
|
|
|
|
+ storeOrder.getPayTradeNo(), e.getStatusCode(), e.getErrorCode(), e.getErrorMessage());
|
|
|
|
|
+ return R.fail("查询微信支付订单失败:" + (e.getErrorMessage() != null ? e.getErrorMessage() : e.getMessage()));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ String newPayTradeNo = "WX" + storeOrder.getId() + "_" + System.currentTimeMillis();
|
|
|
|
|
+ storeOrder.setPayTradeNo(newPayTradeNo);
|
|
|
|
|
+ wechatOutTradeNo = newPayTradeNo;
|
|
|
|
|
+ log.info("未支付场景已换新微信商户单号 orderNo={}, payTradeNo={}", orderNo, newPayTradeNo);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (storeOrder != null) {
|
|
|
|
|
+ storeOrder.setCouponId(couponId);
|
|
|
|
|
+ storeOrder.setPayUserId(payerId);
|
|
|
|
|
+ if (!storeOrderService.updateById(storeOrder)) {
|
|
|
|
|
+ log.error("更新订单失败 orderNo={}", orderNo);
|
|
|
|
|
+ return R.fail("更新订单失败");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ request.outTradeNo = wechatOutTradeNo;
|
|
|
|
|
+
|
|
|
try {
|
|
try {
|
|
|
DirectAPIv3JsapiPrepayResponse response = doCreatePrePayOrder(request, config, privateKey);
|
|
DirectAPIv3JsapiPrepayResponse response = doCreatePrePayOrder(request, config, privateKey);
|
|
|
log.info("微信预支付订单创建成功,预支付ID:{}", response.prepayId);
|
|
log.info("微信预支付订单创建成功,预支付ID:{}", response.prepayId);
|
|
@@ -296,11 +341,31 @@ public class WeChatPaymentMininProgramStrategyImpl implements PaymentStrategy {
|
|
|
if ("SUCCESS".equals(tradeState)) {
|
|
if ("SUCCESS".equals(tradeState)) {
|
|
|
String outTradeNo = jsonObject.getString("out_trade_no");
|
|
String outTradeNo = jsonObject.getString("out_trade_no");
|
|
|
StoreOrder storeOrder = storeOrderService.getOne(new QueryWrapper<StoreOrder>().eq("order_no", outTradeNo));
|
|
StoreOrder storeOrder = storeOrderService.getOne(new QueryWrapper<StoreOrder>().eq("order_no", outTradeNo));
|
|
|
|
|
+ if (storeOrder == null && StringUtils.hasText(outTradeNo)) {
|
|
|
|
|
+ storeOrder = storeOrderService.getOne(new QueryWrapper<StoreOrder>().eq("pay_trade_no", outTradeNo));
|
|
|
|
|
+ }
|
|
|
if (storeOrder != null && storeOrder.getPayStatus() != 1) {
|
|
if (storeOrder != null && storeOrder.getPayStatus() != 1) {
|
|
|
storeOrder.setPayStatus(1);
|
|
storeOrder.setPayStatus(1);
|
|
|
storeOrder.setOrderStatus(1);
|
|
storeOrder.setOrderStatus(1);
|
|
|
if (storeOrderService.updateById(storeOrder)) {
|
|
if (storeOrderService.updateById(storeOrder)) {
|
|
|
log.info("小程序更新订单成功,订单号outTradeNo:{}", outTradeNo);
|
|
log.info("小程序更新订单成功,订单号outTradeNo:{}", outTradeNo);
|
|
|
|
|
+ if (storeOrder.getCouponId() != null && storeOrder.getPayUserId() != null) {
|
|
|
|
|
+ LambdaQueryWrapper<LifeDiscountCouponUser> couponUserWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ couponUserWrapper.eq(LifeDiscountCouponUser::getUserId, storeOrder.getPayUserId());
|
|
|
|
|
+ couponUserWrapper.eq(LifeDiscountCouponUser::getCouponId, storeOrder.getCouponId());
|
|
|
|
|
+ couponUserWrapper.eq(LifeDiscountCouponUser::getStatus,
|
|
|
|
|
+ Integer.parseInt(DiscountCouponEnum.WAITING_USED.getValue()));
|
|
|
|
|
+ couponUserWrapper.eq(LifeDiscountCouponUser::getDeleteFlag, 0);
|
|
|
|
|
+ couponUserWrapper.orderByDesc(LifeDiscountCouponUser::getCreatedTime);
|
|
|
|
|
+ couponUserWrapper.last("LIMIT 1");
|
|
|
|
|
+ LifeDiscountCouponUser couponUser = lifeDiscountCouponUserMapper.selectOne(couponUserWrapper);
|
|
|
|
|
+ if (couponUser != null) {
|
|
|
|
|
+ couponUser.setStatus(Integer.parseInt(DiscountCouponEnum.HAVE_BEEN_USED.getValue()));
|
|
|
|
|
+ couponUser.setUseTime(new Date());
|
|
|
|
|
+ lifeDiscountCouponUserMapper.updateById(couponUser);
|
|
|
|
|
+ log.info("支付成功,已更新 life_discount_coupon_user 为已使用, id={}", couponUser.getId());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
// 支付完成后,清空购物车和重置餐桌状态(保留订单数据,不删除订单)
|
|
// 支付完成后,清空购物车和重置餐桌状态(保留订单数据,不删除订单)
|
|
|
try {
|
|
try {
|
|
|
storeOrderService.resetTableAfterPayment(storeOrder.getTableId());
|
|
storeOrderService.resetTableAfterPayment(storeOrder.getTableId());
|