支付 回调 处理 以及 订单状态 修改

This commit is contained in:
2025-02-15 15:12:57 +08:00
parent faa6f448c0
commit 5fd691f71b
15 changed files with 285 additions and 67 deletions

View File

@@ -3,7 +3,9 @@ package com.czg.controller;
import com.alibaba.fastjson2.JSONObject;
import com.czg.CzgPayUtils;
import com.czg.entity.CzgBaseRespParams;
import com.czg.entity.notify.CzgPayNotifyDTO;
import com.czg.order.service.OrderInfoService;
import com.czg.utils.AssertUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -17,14 +19,16 @@ import org.springframework.web.bind.annotation.RequestMapping;
public class NotifyController {
private static final String SUCCESS = "SUCCESS";
// @Resource
// private PayService payService;
@Resource
private OrderInfoService orderInfoService;
@PostMapping("payCallBack")
public String notifyfstCallBack(CzgBaseRespParams respParams) {
CzgPayNotifyDTO czg = CzgPayUtils.getCzg(respParams, CzgPayNotifyDTO.class);
log.info("支付回调数据为"+ JSONObject.toJSONString(czg));
public String notifyCZGCallBack(CzgBaseRespParams respParams) {
JSONObject czg = CzgPayUtils.getCzg(respParams);
AssertUtil.isNull(czg, "回调数据为");
log.info("支付回调数据为:{}", czg);
orderInfoService.payCallBackOrder(czg.getString("mchOrderNo"), czg);
return SUCCESS;
}

View File

@@ -60,7 +60,7 @@ public class SaTokenConfigure implements WebMvcConfigurer {
// .match("/**")
.notMatch("/user/**")
.notMatch("/admin/auth/**")
.notMatch("/admin/feign/**")
.notMatch("/notify/**")
.check(r -> StpKit.USER.checkManager());
})).addPathPatterns("/**");

View File

@@ -0,0 +1,93 @@
package com.czg.order.entity;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.io.Serial;
import jakarta.validation.constraints.NotBlank;
import lombok.*;
/**
* 支付详情 实体类。
*
* @author ww
* @since 2025-02-15
*/
@Data
@Table("tb_order_payment")
public class OrderPayment implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@Id(keyType = KeyType.Auto)
private Long id;
/**
* 店铺Id
*/
private Long shopId;
/**
* 来源Id 订单Id或充值id
*/
private Long sourceId;
/**
* 支付方式order,refund, memberIn,memberRefund
*/
private String payType;
/**
* 支付单号 唯一 自己系统的 mchOrderNo
*/
private String orderNo;
/**
* 微信或支付宝支付条码
*/
private String authCode;
/**
* 金额
*/
private BigDecimal amount;
/**
* 三方支付单号 返回结果的 payOrderId
*/
private String tradeNumber;
@Column(onInsertValue = "now()")
private LocalDateTime payTime;
/**
* 支付相应结果 json
*/
private String respJson;
@Column(onInsertValue = "now()")
private LocalDateTime createTime;
@Column(onInsertValue = "now()", onUpdateValue = "now()")
private LocalDateTime updateTime;
public OrderPayment(@NonNull Long shopId, @NonNull Long sourceId, @NotBlank String payType, @NotBlank String orderNo,
String authCode,@NonNull BigDecimal amount) {
this.shopId = shopId;
this.sourceId = sourceId;
this.payType = payType;
this.orderNo = orderNo;
this.authCode = authCode;
this.amount = amount;
}
}

View File

@@ -1,5 +1,6 @@
package com.czg.order.service;
import com.alibaba.fastjson2.JSONObject;
import com.czg.order.dto.OrderInfoQueryDTO;
import com.czg.order.entity.OrderInfo;
import com.czg.order.vo.OrderInfoVo;
@@ -15,4 +16,6 @@ import com.mybatisflex.core.service.IService;
public interface OrderInfoService extends IService<OrderInfo> {
Page<OrderInfoVo> getOrderByPage(OrderInfoQueryDTO param);
void payCallBackOrder(String orderNo, JSONObject resultJson);
void refundCallBackOrder();
}

View File

@@ -0,0 +1,14 @@
package com.czg.order.service;
import com.mybatisflex.core.service.IService;
import com.czg.order.entity.OrderPayment;
/**
* 支付详情 服务层。
*
* @author ww
* @since 2025-02-15
*/
public interface OrderPaymentService extends IService<OrderPayment> {
}

View File

@@ -155,9 +155,8 @@ public class CzgPayUtils {
}
public static <T> T getCzg(CzgBaseRespParams respParams, Class<T> clazz) {
public static JSONObject getCzg(CzgBaseRespParams respParams) {
AssertUtil.isNull(respParams, "超掌柜交易 回调数据为空");
// CzgBaseRespParams respParams = JSONObject.parseObject(dataJsonStr, CzgBaseRespParams.class);
log.info("超掌柜交易请求响应,{}", respParams);
if (!"000000".equals(respParams.getCode())) {
log.error("超掌柜回调响应失败,{}", respParams);
@@ -168,7 +167,7 @@ public class CzgPayUtils {
log.error("超掌柜回调 验签失败,{}", respParams);
}
}
return JSONObject.parseObject(respParams.getBizData(), clazz);
return JSONObject.parse(respParams.getBizData());
}
@@ -249,4 +248,28 @@ public class CzgPayUtils {
}
return sortParam;
}
// public static void main(String[] args) {
// CzgResult<Object> result = CzgResult.success();
// CzgBaseRespParams respParams = new CzgBaseRespParams();
// respParams.setCode("000000");
// respParams.setMsg("成功");
// respParams.setSign("6c0f1e11b0d3a16298c2dfeee8c1491a");
// respParams.setBizData("{\"amount\":500,\"currency\":\"cny\",\"ifCode\":\"lklspay\",\"mchOrderNo\":\"WX1889977729515615615\",\"mercNo\":\"B240612563201\",\"note\":\"成功\",\"payOrderId\":\"202502151890598483156443138V6W\",\"payType\":\"WECHAT\",\"settlementType\":\"D1\",\"state\":\"TRADE_SUCCESS\",\"storeId\":\"S2406125309\",\"subject\":\"超掌柜\",\"tradeFee\":2}");
// respParams.setTimestamp("20250215110620");
// log.info("超掌柜交易请求响应,{}", respParams);
//
// result.setCode("000000".equals(respParams.getCode()) ? 200 : Integer.parseInt(respParams.getCode()));
// result.setMsg(respParams.getMsg());
// if ("000000".equals(respParams.getCode()) && StrUtil.isNotBlank(respParams.getSign())) {
// if (validateSign(respParams.getSign(), JSONObject.toJSONString(respParams))) {
// log.info("验签失败");
// }
// result.setData(JSONObject.parseObject(respParams.getBizData(), CzgMicroPayResp.class));
// }
// System.out.println(JSONObject.toJSONString(result));
// }
}

View File

@@ -0,0 +1,30 @@
package com.czg.service.order.enums;
import lombok.Getter;
/**
* 订单状态枚举类
*/
@Getter
public enum OrderStatusEnums {
UNPAID("unpaid", "待支付"),
IN_PRODUCTION("in_production", "制作中"),
WAIT_OUT("wait_out", "待取餐"),
DONE("done", "订单完成"),
REFUNDING("refunding", "申请退单"),
REFUND("refund", "退单"),
PART_REFUND("part_refund", "部分退单"),
CANCELLED("cancelled", "取消订单");
private final String code;
private final String msg;
OrderStatusEnums(String code, String msg) {
this.code = code;
this.msg = msg;
}
}

View File

@@ -0,0 +1,14 @@
package com.czg.service.order.mapper;
import com.mybatisflex.core.BaseMapper;
import com.czg.order.entity.OrderPayment;
/**
* 支付详情 映射层。
*
* @author ww
* @since 2025-02-15
*/
public interface OrderPaymentMapper extends BaseMapper<OrderPayment> {
}

View File

@@ -61,19 +61,4 @@ public interface PayService {
* @param refundOrderId 平台退款订单号 二选一
*/
CzgResult<CzgRefundResp> queryRefund(Long shopId, String mchRefundNo, String refundOrderId);
/**
* 支付回调数据处理
*
* @param dataJsonStr 带解析数据
*/
CzgPayNotifyDTO getPayNotifyData(String dataJsonStr);
/**
* 退款回调数据处理
*
* @param dataJsonStr 带解析数据
*/
CzgRefundNotifyDTO getRefundNotifyData(String dataJsonStr);
}

View File

@@ -1,21 +1,29 @@
package com.czg.service.order.service.impl;
import cn.hutool.core.util.StrUtil;
import com.czg.order.entity.OrderDetail;
import com.czg.order.service.OrderDetailService;
import com.alibaba.fastjson2.JSONObject;
import com.czg.entity.notify.CzgPayNotifyDTO;
import com.czg.order.dto.OrderInfoQueryDTO;
import com.czg.order.entity.OrderDetail;
import com.czg.order.entity.OrderInfo;
import com.czg.order.entity.OrderPayment;
import com.czg.order.service.OrderDetailService;
import com.czg.order.service.OrderInfoService;
import com.czg.order.service.OrderPaymentService;
import com.czg.order.vo.OrderDetailSmallVO;
import com.czg.order.vo.OrderInfoVo;
import com.czg.service.order.enums.OrderStatusEnums;
import com.czg.service.order.mapper.OrderInfoMapper;
import com.czg.utils.PageUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.czg.order.entity.OrderInfo;
import com.czg.order.service.OrderInfoService;
import com.czg.service.order.mapper.OrderInfoMapper;
import jakarta.annotation.Resource;
import jakarta.validation.constraints.NotBlank;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.List;
/**
@@ -30,6 +38,9 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
@Resource
private OrderDetailService orderDetailService;
@Resource
private OrderPaymentService paymentService;
@Override
public Page<OrderInfoVo> getOrderByPage(OrderInfoQueryDTO param) {
String productName = param.getProductName();
@@ -59,4 +70,34 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
});
return orderInfoVoPage;
}
@Override
@Transactional
public void payCallBackOrder(@NotBlank String orderNo, @NotBlank JSONObject resultJson) {
CzgPayNotifyDTO czgCallBackDto = JSONObject.parseObject(resultJson.toString(), CzgPayNotifyDTO.class);
OrderPayment payment = paymentService.queryChain().eq(OrderPayment::getOrderNo, orderNo).one();
paymentService.updateChain().of(OrderPayment.class)
.set(OrderPayment::getTradeNumber, czgCallBackDto.getPayOrderId())
.set(OrderPayment::getRespJson, resultJson.toString())
.where(OrderPayment::getId).eq(payment.getId())
.update();
if ("TRADE_SUCCESS" .equals(czgCallBackDto.getState())) {
if ("order" .equals(payment.getPayType())) {
updateChain().of(OrderInfo.class)
.set(OrderInfo::getPayAmount, new BigDecimal(czgCallBackDto.getAmount() / 100L))
.set(OrderInfo::getStatus, OrderStatusEnums.DONE.getCode())
.where(OrderInfo::getId).eq(payment.getSourceId())
.update();
//发送打票信息
}
} else {
}
}
@Override
public void refundCallBackOrder() {
}
}

View File

@@ -0,0 +1,18 @@
package com.czg.service.order.service.impl;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.czg.order.entity.OrderPayment;
import com.czg.order.service.OrderPaymentService;
import com.czg.service.order.mapper.OrderPaymentMapper;
import org.springframework.stereotype.Service;
/**
* 支付详情 服务层实现。
*
* @author ww
* @since 2025-02-15
*/
@Service
public class OrderPaymentServiceImpl extends ServiceImpl<OrderPaymentMapper, OrderPayment> implements OrderPaymentService{
}

View File

@@ -1,5 +1,6 @@
package com.czg.service.order.service.impl;
import cn.hutool.core.util.IdUtil;
import com.czg.account.entity.ShopMerchant;
import com.czg.account.service.ShopMerchantService;
import com.czg.entity.notify.CzgPayNotifyDTO;
@@ -7,7 +8,9 @@ import com.czg.entity.notify.CzgRefundNotifyDTO;
import com.czg.entity.req.*;
import com.czg.entity.resp.*;
import com.czg.order.entity.OrderInfo;
import com.czg.order.entity.OrderPayment;
import com.czg.order.service.OrderInfoService;
import com.czg.order.service.OrderPaymentService;
import com.czg.resp.CzgResult;
import com.czg.service.CzgPayService;
import com.czg.service.order.dto.OrderPayParamDTO;
@@ -37,6 +40,8 @@ public class PayServiceImpl implements PayService {
private CzgPayService czgPayService;
@Resource
private OrderInfoService orderInfoService;
@Resource
private OrderPaymentService paymentService;
private final BigDecimal MONEY_RATE = new BigDecimal("100");
private final String payJsonExtParam = "{\"payType\":\"1\"}";
@@ -46,7 +51,9 @@ public class PayServiceImpl implements PayService {
public CzgResult<CzgH5PayResp> h5PayOrder(@NonNull String clintIp, OrderPayParamDTO payParam) {
OrderInfo orderInfo = orderInfoService.getById(payParam.getOrderId());
AssertUtil.isNull(orderInfo, "订单不存在");
return h5Pay(payParam.getShopId(), new CzgH5PayReq(orderInfo.getOrderNo(), orderInfo.getPayAmount().multiply(MONEY_RATE).longValue(),
String payOrderNO = orderInfo.getPlatformType() + IdUtil.getSnowflakeNextId();
initOrderPayment(new OrderPayment(payParam.getShopId(), payParam.getOrderId(), "order", payOrderNO, "", orderInfo.getOrderAmount()));
return h5Pay(payParam.getShopId(), new CzgH5PayReq(payOrderNO, orderInfo.getOrderAmount().multiply(MONEY_RATE).longValue(),
"点餐支付", clintIp, payParam.getReturnUrl(), payParam.getBuyerRemark(), payJsonExtParam));
}
@@ -55,7 +62,9 @@ public class PayServiceImpl implements PayService {
public CzgResult<CzgJsPayResp> jsPayOrder(@NonNull String clintIp, OrderPayParamDTO payParam) {
OrderInfo orderInfo = orderInfoService.getById(payParam.getOrderId());
AssertUtil.isNull(orderInfo, "订单不存在");
return jsPay(payParam.getShopId(), payParam.getPayType(), new CzgJsPayReq(orderInfo.getOrderNo(), orderInfo.getPayAmount().multiply(MONEY_RATE).longValue(),
String payOrderNO = orderInfo.getPlatformType() + IdUtil.getSnowflakeNextId();
initOrderPayment(new OrderPayment(payParam.getShopId(), payParam.getOrderId(), "order", payOrderNO, "", orderInfo.getOrderAmount()));
return jsPay(payParam.getShopId(), payParam.getPayType(), new CzgJsPayReq(payOrderNO, orderInfo.getOrderAmount().multiply(MONEY_RATE).longValue(),
"点餐支付", payParam.getOpenId(), clintIp, payParam.getReturnUrl(), payParam.getBuyerRemark(), payJsonExtParam));
}
@@ -63,7 +72,9 @@ public class PayServiceImpl implements PayService {
public CzgResult<CzgLtPayResp> ltPayOrder(@NonNull String clintIp, OrderPayParamDTO payParam) {
OrderInfo orderInfo = orderInfoService.getById(payParam.getOrderId());
AssertUtil.isNull(orderInfo, "订单不存在");
return ltPay(payParam.getShopId(), payParam.getPayType(), new CzgLtPayReq(orderInfo.getOrderNo(), orderInfo.getPayAmount().multiply(MONEY_RATE).longValue(),
String payOrderNO = orderInfo.getPlatformType() + IdUtil.getSnowflakeNextId();
initOrderPayment(new OrderPayment(payParam.getShopId(), payParam.getOrderId(), "order", payOrderNO, "", orderInfo.getOrderAmount()));
return ltPay(payParam.getShopId(), payParam.getPayType(), new CzgLtPayReq(payOrderNO, orderInfo.getOrderAmount().multiply(MONEY_RATE).longValue(),
"点餐支付", payParam.getOpenId(), clintIp, payParam.getReturnUrl(), payParam.getBuyerRemark(), payJsonExtParam));
}
@@ -71,7 +82,9 @@ public class PayServiceImpl implements PayService {
public CzgResult<CzgScanPayResp> scanPayOrder(@NonNull String clintIp, OrderPayParamDTO payParam) {
OrderInfo orderInfo = orderInfoService.getById(payParam.getOrderId());
AssertUtil.isNull(orderInfo, "订单不存在");
return scanPay(payParam.getShopId(), new CzgScanPayReq(orderInfo.getOrderNo(), orderInfo.getPayAmount().multiply(MONEY_RATE).longValue(),
String payOrderNO = orderInfo.getPlatformType() + IdUtil.getSnowflakeNextId();
initOrderPayment(new OrderPayment(payParam.getShopId(), payParam.getOrderId(), "order", payOrderNO, "", orderInfo.getOrderAmount()));
return scanPay(payParam.getShopId(), new CzgScanPayReq(payOrderNO, orderInfo.getOrderAmount().multiply(MONEY_RATE).longValue(),
"点餐支付", clintIp, payParam.getReturnUrl(), payParam.getBuyerRemark(), payJsonExtParam));
}
@@ -79,7 +92,9 @@ public class PayServiceImpl implements PayService {
public CzgResult<CzgMicroPayResp> microPayOrder(OrderPayParamDTO payParam) {
OrderInfo orderInfo = orderInfoService.getById(payParam.getOrderId());
AssertUtil.isNull(orderInfo, "订单不存在");
return microPay(payParam.getShopId(), new CzgMicroPayReq(orderInfo.getOrderNo(), orderInfo.getPayAmount().multiply(MONEY_RATE).longValue(),
String payOrderNO = orderInfo.getPlatformType() + IdUtil.getSnowflakeNextId();
initOrderPayment(new OrderPayment(payParam.getShopId(), payParam.getOrderId(), "order", payOrderNO, payParam.getAuthCode(), orderInfo.getOrderAmount()));
return microPay(payParam.getShopId(), new CzgMicroPayReq(payOrderNO, orderInfo.getOrderAmount().multiply(MONEY_RATE).longValue(),
"点餐支付", payParam.getAuthCode(), payParam.getBuyerRemark(), payJsonExtParam));
}
@@ -104,14 +119,9 @@ public class PayServiceImpl implements PayService {
}
@Override
public CzgPayNotifyDTO getPayNotifyData(String dataJsonStr) {
return czgPayService.getPayNotifyData(dataJsonStr);
}
@Override
public CzgRefundNotifyDTO getRefundNotifyData(String dataJsonStr) {
return czgPayService.getRefundNotifyData(dataJsonStr);
private void initOrderPayment(OrderPayment payment) {
paymentService.save(payment);
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.czg.service.order.mapper.OrderPaymentMapper">
</mapper>

View File

@@ -84,18 +84,4 @@ public interface CzgPayService {
String mchRefundNo, String refundOrderId);
/**
* 支付回调数据处理
*
* @param dataJsonStr 带解析数据
*/
CzgPayNotifyDTO getPayNotifyData(String dataJsonStr);
/**
* 退款回调数据处理
*
* @param dataJsonStr 带解析数据
*/
CzgRefundNotifyDTO getRefundNotifyData(String dataJsonStr);
}

View File

@@ -60,17 +60,7 @@ public class CzgPayServiceImpl implements CzgPayService {
@Override
public CzgResult<CzgRefundResp> queryRefundOrder(@NonNull String appId, @NonNull String appSecret, String mchRefundNo, String refundOrderId) {
return CzgPayUtils.queryRefundOrder(sysParamsService.getSysParamValue(SysParamCodeEnum.PAY_CZG_DOMAIN.getCode()), appId, appSecret, mchRefundNo,refundOrderId);
}
@Override
public CzgPayNotifyDTO getPayNotifyData(String dataJsonStr) {
return CzgPayUtils.getCzg(dataJsonStr,CzgPayNotifyDTO.class);
}
@Override
public CzgRefundNotifyDTO getRefundNotifyData(String dataJsonStr) {
return CzgPayUtils.getCzg(dataJsonStr,CzgRefundNotifyDTO.class);
return CzgPayUtils.queryRefundOrder(sysParamsService.getSysParamValue(SysParamCodeEnum.PAY_CZG_DOMAIN.getCode()), appId, appSecret, mchRefundNo, refundOrderId);
}
}