优化
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
package cn.iocoder.yudao.module.pay.controller.admin.notify;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||
@ -10,6 +11,8 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
|
||||
import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
|
||||
import cn.iocoder.yudao.framework.pay.core.enums.divide.PayDivideRefundStatusRespEnum;
|
||||
import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum;
|
||||
import cn.iocoder.yudao.module.member.api.activitypay.ActivityApi;
|
||||
import cn.iocoder.yudao.module.member.api.activitypay.dto.ActivityPayDTO;
|
||||
import cn.iocoder.yudao.module.member.api.card.CardApi;
|
||||
import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskDetailRespVO;
|
||||
import cn.iocoder.yudao.module.pay.controller.admin.notify.vo.PayNotifyTaskPageReqVO;
|
||||
@ -38,18 +41,14 @@ import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.annotation.security.PermitAll;
|
||||
import javax.validation.Valid;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -87,6 +86,8 @@ public class PayNotifyController {
|
||||
private StringRedisTemplate notifyRedisTemplate;
|
||||
@Resource
|
||||
private CardApi cardApi;
|
||||
@Resource
|
||||
private ActivityApi activityApi;
|
||||
|
||||
@PostMapping(value = "/order/{channelId}")
|
||||
@Operation(summary = "支付渠道的统一【支付】回调")
|
||||
@ -117,6 +118,45 @@ public class PayNotifyController {
|
||||
return "success";
|
||||
}
|
||||
|
||||
@PostMapping(value = "/reserved/{channelId}")
|
||||
@Operation(summary = "支付渠道的统一【支付】回调")
|
||||
@PermitAll
|
||||
@OperateLog(enable = false) // 回调地址,无需记录操作日志
|
||||
public String reservedNotifyOrder(@PathVariable("channelId") Long channelId,
|
||||
@RequestParam(required = false) Map<String, String> params,
|
||||
@RequestBody(required = false) String body) {
|
||||
log.info("[notifyOrder][channelId({}) 回调数据({}/{})]", channelId, params, body);
|
||||
// 1. 校验支付渠道是否存在
|
||||
PayClient payClient = channelService.getPayClient(channelId);
|
||||
if (payClient == null) {
|
||||
log.error("[notifyCallback][渠道编号({}) 找不到对应的支付客户端]", channelId);
|
||||
throw exception(CHANNEL_NOT_FOUND);
|
||||
}
|
||||
|
||||
// 2. 解析通知数据
|
||||
PayOrderRespDTO notify = payClient.parseOrderNotify(params, body);
|
||||
orderService.notifyOrder(channelId, notify);
|
||||
String re = notifyRedisTemplate.opsForValue().get("RESERVED" + notify.getOutTradeNo());
|
||||
if(StringUtils.isNotBlank(re) ){
|
||||
log.info("开始进行订单记录增加,获取的数据:{}", re);
|
||||
HashMap<String, String> deserializedMap = JSONUtil.toBean(re, HashMap.class);
|
||||
|
||||
ActivityPayDTO activityPayDTO = new ActivityPayDTO();
|
||||
activityPayDTO.setActivityId(Long.valueOf(deserializedMap.get("activityId")));
|
||||
activityPayDTO.setSerialNumbers(deserializedMap.get("serialNumbers"));
|
||||
activityPayDTO.setPrice(new BigDecimal(deserializedMap.get("price")).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP));
|
||||
activityPayDTO.setUserId(Long.valueOf(deserializedMap.get("userId")));
|
||||
activityPayDTO.setStatus(deserializedMap.get("status"));
|
||||
activityPayDTO.setReserveTime(deserializedMap.get("reserveTime"));
|
||||
activityPayDTO.setDish( deserializedMap.get("dish"));
|
||||
activityPayDTO.setDiningPeriod( deserializedMap.get("diningPeriod"));
|
||||
|
||||
activityApi.createActivityPay(activityPayDTO);
|
||||
notifyRedisTemplate.delete("RESERVED" + notify.getOutTradeNo());
|
||||
}
|
||||
return "success";
|
||||
}
|
||||
|
||||
@PostMapping(value = "/refund/{channelId}")
|
||||
@Operation(summary = "支付渠道的统一【退款】回调")
|
||||
@PermitAll
|
||||
|
@ -30,4 +30,17 @@ public class PayOrderSubmitReqVO {
|
||||
@URL(message = "回跳地址的格式必须是 URL")
|
||||
private String returnUrl;
|
||||
|
||||
private String serialNumbers;
|
||||
|
||||
private Long activityId;
|
||||
|
||||
private Long userId;
|
||||
|
||||
private String status;
|
||||
|
||||
private String reserveTime;
|
||||
|
||||
private String dish;
|
||||
|
||||
private String diningPeriod;
|
||||
}
|
||||
|
@ -18,6 +18,9 @@ public class AppPayWalletRechargeCreateReqVO {
|
||||
@Schema(description = "充值套餐编号", example = "1024")
|
||||
private Long packageId;
|
||||
|
||||
@Schema(description = "充值类型,1-充值 2-活动订餐", example = "1024")
|
||||
private String type;
|
||||
|
||||
@AssertTrue(message = "充值金额和充钱套餐不能同时为空")
|
||||
public boolean isValidPayPriceAndPackageId() {
|
||||
return Objects.nonNull(payPrice) || Objects.nonNull(packageId);
|
||||
|
@ -28,6 +28,11 @@ public class PayProperties {
|
||||
@URL(message = "支付回调地址的格式必须是 URL")
|
||||
private String orderNotifyUrl;
|
||||
|
||||
|
||||
@NotEmpty(message = "预定支付回调地址不能为空")
|
||||
@URL(message = "预定支付回调地址的格式必须是 URL")
|
||||
private String reservedNotifyUrl;
|
||||
|
||||
/**
|
||||
* 退款回调地址
|
||||
*
|
||||
|
@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.number.MoneyUtils;
|
||||
@ -43,10 +44,7 @@ import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
|
||||
@ -174,10 +172,28 @@ public class PayOrderServiceImpl implements PayOrderService {
|
||||
.setReturnUrl(reqVO.getReturnUrl())
|
||||
// 订单相关字段
|
||||
.setPrice(order.getPrice()).setExpireTime(order.getExpireTime());
|
||||
if (reqVO.getActivityId()!=null){
|
||||
unifiedOrderReqDTO.setNotifyUrl(genChannelReservedNotifyUrl(channel));
|
||||
|
||||
HashMap<String, String> stringStringHashMap = new HashMap<>();
|
||||
stringStringHashMap.put("activityId",reqVO.getActivityId().toString());
|
||||
stringStringHashMap.put("userId",getLoginUserId().toString());
|
||||
stringStringHashMap.put("serialNumbers",reqVO.getSerialNumbers());
|
||||
stringStringHashMap.put("price",unifiedOrderReqDTO.getPrice().toString());
|
||||
stringStringHashMap.put("status",reqVO.getStatus());
|
||||
stringStringHashMap.put("reserveTime",reqVO.getReserveTime());
|
||||
stringStringHashMap.put("dish",reqVO.getDish());
|
||||
stringStringHashMap.put("diningPeriod",reqVO.getDiningPeriod());
|
||||
|
||||
payRedis.opsForValue().set("RESERVED"+unifiedOrderReqDTO.getOutTradeNo()
|
||||
, JSONUtil.toJsonStr(stringStringHashMap));
|
||||
log.info("REDIS_ID:RESERVED{} 总金额:{}", unifiedOrderReqDTO.getOutTradeNo(), unifiedOrderReqDTO.getPrice().toString());
|
||||
}else{
|
||||
payRedis.opsForValue().set("ADD"+unifiedOrderReqDTO.getOutTradeNo()
|
||||
,unifiedOrderReqDTO.getPrice().toString()+"-"+getLoginUserId());
|
||||
log.info("REDIS_ID:ADD{} 总金额:{}", unifiedOrderReqDTO.getOutTradeNo(), unifiedOrderReqDTO.getPrice().toString());
|
||||
}
|
||||
PayOrderRespDTO unifiedOrderResp = client.unifiedOrder(unifiedOrderReqDTO);
|
||||
payRedis.opsForValue().set("ADD"+unifiedOrderReqDTO.getOutTradeNo()
|
||||
,unifiedOrderReqDTO.getPrice().toString()+"-"+getLoginUserId());
|
||||
log.info("REDISID:"+"ADD"+unifiedOrderReqDTO.getOutTradeNo()+" 总金额:"+unifiedOrderReqDTO.getPrice().toString());
|
||||
// 4. 如果调用直接支付成功,则直接更新支付单状态为成功。例如说:付款码支付,免密支付时,就直接验证支付成功
|
||||
if (unifiedOrderResp != null) {
|
||||
getSelf().notifyOrder(channel, unifiedOrderResp);
|
||||
@ -265,6 +281,10 @@ public class PayOrderServiceImpl implements PayOrderService {
|
||||
return payProperties.getOrderNotifyUrl() + "/" + channel.getId();
|
||||
}
|
||||
|
||||
private String genChannelReservedNotifyUrl(PayChannelDO channel) {
|
||||
return payProperties.getReservedNotifyUrl() + "/" + channel.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifyOrder(Long channelId, PayOrderRespDTO notify) {
|
||||
// 校验支付渠道是否有效
|
||||
|
@ -82,10 +82,15 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
|
||||
walletRechargeMapper.insert(recharge);
|
||||
|
||||
// 2.1 创建支付单
|
||||
String subject = WALLET_RECHARGE_ORDER_SUBJECT;
|
||||
if("2".equals(reqVO.getType())){
|
||||
subject = "活动订餐";
|
||||
}
|
||||
Long payOrderId = payOrderService.createOrder(new PayOrderCreateReqDTO()
|
||||
.setAppId(WALLET_PAY_APP_ID).setUserIp(userIp)
|
||||
.setMerchantOrderId(recharge.getId().toString()) // 业务的订单编号
|
||||
.setSubject(WALLET_RECHARGE_ORDER_SUBJECT).setBody("")
|
||||
.setSubject(subject)
|
||||
.setBody("")
|
||||
.setPrice(recharge.getPayPrice())
|
||||
.setExpireTime(addTime(Duration.ofHours(2L)))); // TODO @芋艿:支付超时时间
|
||||
// 2.2 更新钱包充值记录中支付订单
|
||||
|
Reference in New Issue
Block a user