diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AlipayController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AlipayController.java
new file mode 100644
index 000000000..dfa64eeb0
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AlipayController.java
@@ -0,0 +1,180 @@
+package com.ruoyi.web.controller.xkt;
+
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.internal.util.AlipaySignature;
+import com.ruoyi.common.core.controller.XktBaseController;
+import com.ruoyi.xkt.domain.AlipayCallback;
+import com.ruoyi.xkt.domain.StoreOrder;
+import com.ruoyi.xkt.enums.EProcessStatus;
+import com.ruoyi.xkt.manager.impl.AliPaymentMangerImpl;
+import com.ruoyi.xkt.service.IStoreOrderService;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * @author liangyq
+ * @date 2025-04-07 18:31
+ */
+@Api(tags = "支付宝回调接口")
+@RestController
+@RequestMapping("/rest/v1/alipay")
+public class AlipayController extends XktBaseController {
+
+ private static final String SUCCESS = "success";
+ private static final String FAILURE = "failure";
+
+ @Autowired
+ private IStoreOrderService storeOrderService;
+ @Autowired
+ private AliPaymentMangerImpl paymentManger;
+
+ /**
+ * 支付宝服务器异步通知
+ *
+ * 1. 在进行异步通知交互时,如果支付宝收到的应答不是 success ,支付宝会认为通知失败,会通过一定的策略定期重新发起通知。
+ * 通知的间隔频率为:4m、10m、10m、1h、2h、6h、15h。
+ * 2. 商家设置的异步地址(notify_url)需保证无任何字符,如空格、HTML 标签,且不能重定向。
+ * (如果重定向,支付宝会收不到 success 字符,会被支付宝服务器判定为该页面程序运行出现异常,而重发处理结果通知)
+ * 3. 支付宝是用 POST 方式发送通知信息,商户获取参数的方式如下:request.Form("out_trade_no")、$_POST['out_trade_no']。
+ * 4. 支付宝针对同一条异步通知重试时,异步通知参数中的 notify_id 是不变的。
+ *
+ * @param request
+ * @return
+ */
+ @PostMapping("/notify")
+ public String notify(HttpServletRequest request) {
+ Map params = getParamsMap(request);
+ boolean signVerified = false;
+ try {
+ //验证签名
+ signVerified = AlipaySignature.rsaCheckV1(params, paymentManger.getAlipayPublicKey(),
+ paymentManger.getCharset(), paymentManger.getSignType());
+ } catch (AlipayApiException e) {
+ logger.error("支付宝验签异常", e);
+ }
+ if (signVerified) {
+ AlipayCallback alipayCallback = trans2DO(params);
+ //需要严格按照如下描述校验通知数据的正确性:
+ //1. 商家需要验证该通知数据中的 out_trade_no 是否为商家系统中创建的订单号。
+ StoreOrder order = storeOrderService.getByOrderNo(alipayCallback.getOutTradeNo());
+ if (order == null) {
+ logger.info("支付宝回调订单匹配失败:{}", params);
+ return FAILURE;
+ }
+ //2. 判断 total_amount 是否确实为该订单的实际金额(即商家订单创建时的金额)。
+ if (!NumberUtil.equals(order.getTotalAmount(), alipayCallback.getTotalAmount())) {
+ logger.info("支付宝回调订单金额匹配失败:{}", params);
+ return FAILURE;
+ }
+ //3. 校验通知中的 seller_id(或者 seller_email)是否为 out_trade_no 这笔单据的对应的操作方
+ // (有的时候,一个商家可能有多个 seller_id/seller_email)。
+ //4. 验证 app_id 是否为该商家本身。
+ if (!StrUtil.equals(paymentManger.getAppId(), alipayCallback.getAppId())) {
+ logger.info("支付宝回调应用ID异常:{}", params);
+ return FAILURE;
+ }
+ //5. 处理支付宝回调信息
+ paymentManger.processAlipayCallback(alipayCallback);
+ return SUCCESS;
+ } else {
+ logger.info("支付宝验签未通过:{}", params);
+ return FAILURE;
+ }
+ }
+
+
+ /**
+ * 获取参数
+ *
+ * @param request
+ * @return
+ */
+ private Map getParamsMap(HttpServletRequest request) {
+ Map params = new HashMap<>();
+ Map requestParams = request.getParameterMap();
+ for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
+ String name = (String) iter.next();
+ String[] values = (String[]) requestParams.get(name);
+ String valueStr = "";
+ for (int i = 0; i < values.length; i++) {
+ valueStr = (i == values.length - 1) ? valueStr + values[i]
+ : valueStr + values[i] + ",";
+ }
+ params.put(name, valueStr);
+ }
+ return params;
+ }
+
+ /**
+ * 转换为do
+ *
+ * @param params
+ * @return
+ */
+ private AlipayCallback trans2DO(Map params) {
+ AlipayCallback alipayCallback = new AlipayCallback();
+ alipayCallback.setNotifyType(params.get("notify_type"));
+ alipayCallback.setNotifyId(params.get("notify_id"));
+ alipayCallback.setAppId(params.get("app_id"));
+ alipayCallback.setCharset(params.get("charset"));
+ alipayCallback.setVersion(params.get("version"));
+ alipayCallback.setSignType(params.get("sign_type"));
+ alipayCallback.setSign(params.get("sign"));
+ alipayCallback.setTradeNo(params.get("trade_no"));
+ alipayCallback.setOutTradeNo(params.get("out_trade_no"));
+ alipayCallback.setOutBizNo(params.get("out_biz_no"));
+ alipayCallback.setBuyerId(params.get("buyer_id"));
+ alipayCallback.setBuyerLogonId(params.get("buyer_logon_id"));
+ alipayCallback.setSellerId(params.get("seller_id"));
+ alipayCallback.setSellerEmail(params.get("seller_email"));
+ alipayCallback.setTradeStatus(params.get("trade_status"));
+ String totalAmountStr = params.get("total_amount");
+ alipayCallback.setTotalAmount(trans2BigDecimal(totalAmountStr));
+ String receiptAmountStr = params.get("receipt_amount");
+ alipayCallback.setReceiptAmount(trans2BigDecimal(receiptAmountStr));
+ String invoiceAmountStr = params.get("invoice_amount");
+ alipayCallback.setInvoiceAmount(trans2BigDecimal(invoiceAmountStr));
+ String buyerPayAmountStr = params.get("buyer_pay_amount");
+ alipayCallback.setBuyerPayAmount(trans2BigDecimal(buyerPayAmountStr));
+ String pointAmountStr = params.get("point_amount");
+ alipayCallback.setPointAmount(trans2BigDecimal(pointAmountStr));
+ String refundFeeStr = params.get("refund_fee");
+ alipayCallback.setRefundFee(trans2BigDecimal(refundFeeStr));
+ alipayCallback.setSubject(params.get("subject"));
+ alipayCallback.setBody(params.get("body"));
+ alipayCallback.setGmtCreate(params.get("gmt_create"));
+ alipayCallback.setGmtPayment(params.get("gmt_payment"));
+ alipayCallback.setGmtRefund(params.get("gmt_refund"));
+ alipayCallback.setGmtClose(params.get("gmt_close"));
+ alipayCallback.setFundBillList(params.get("fund_bill_list"));
+ alipayCallback.setPassbackParams(params.get("passback_params"));
+ alipayCallback.setVoucherDetailList(params.get("voucher_detail_list"));
+ alipayCallback.setProcessStatus(EProcessStatus.INIT.getValue());
+ return alipayCallback;
+ }
+
+ /**
+ * 转换为BigDecimal
+ *
+ * @param value
+ * @return
+ */
+ private BigDecimal trans2BigDecimal(String value) {
+ if (StrUtil.isBlank(value)) {
+ return BigDecimal.ZERO;
+ }
+ return new BigDecimal(value);
+ }
+
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
index be51d9036..6058fdb10 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java
@@ -188,6 +188,10 @@ public class Constants
public static final Integer SIZE_41 = 41;
public static final Integer SIZE_42 = 42;
public static final Integer SIZE_43 = 43;
+ /**
+ * 平台内部账户ID
+ */
+ public static final Long PLATFORM_INTERNAL_ACCOUNT_ID = 1L;
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
index 15ec7edd7..fca5d57b1 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
@@ -111,10 +111,12 @@ public class SecurityConfig
.authorizeHttpRequests((requests) -> {
permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());
// 对于登录login 注册register 验证码captchaImage 允许匿名访问
- requests.antMatchers("/login", "/register", "/captchaImage", "/xkt/test/execute").permitAll()
+ requests.antMatchers("/login", "/register", "/captchaImage").permitAll()
// 静态资源,可匿名访问
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
+ //支付宝回调
+ .antMatchers("/rest/v1/alipay-notify").permitAll()
// 除上面外的所有请求全部需要鉴权认证
.anyRequest().authenticated();
})
diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/payment/PaymentBillInfo.java b/xkt/src/main/java/com/ruoyi/xkt/dto/payment/PaymentBillInfo.java
new file mode 100644
index 000000000..e2febb621
--- /dev/null
+++ b/xkt/src/main/java/com/ruoyi/xkt/dto/payment/PaymentBillInfo.java
@@ -0,0 +1,23 @@
+package com.ruoyi.xkt.dto.payment;
+
+import com.ruoyi.xkt.domain.PaymentBill;
+import com.ruoyi.xkt.domain.PaymentBillDetail;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * @author liangyq
+ * @date 2025-04-08 21:18
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class PaymentBillInfo {
+
+ private PaymentBill paymentBill;
+
+ private List paymentBillDetails;
+}
diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/EProcessStatus.java b/xkt/src/main/java/com/ruoyi/xkt/enums/EProcessStatus.java
new file mode 100644
index 000000000..d421a81c5
--- /dev/null
+++ b/xkt/src/main/java/com/ruoyi/xkt/enums/EProcessStatus.java
@@ -0,0 +1,30 @@
+package com.ruoyi.xkt.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author liangyq
+ * @date 2025-04-07 23:42
+ */
+@Getter
+@AllArgsConstructor
+public enum EProcessStatus {
+
+ INIT(1, "初始"),
+ PROCESSING(2, "处理中"),
+ SUCCESS(3, "处理成功"),
+ FAILURE(4, "处理失败");
+
+ private final Integer value;
+ private final String label;
+
+ public static EProcessStatus of(Integer value) {
+ for (EProcessStatus e : EProcessStatus.values()) {
+ if (e.getValue().equals(value)) {
+ return e;
+ }
+ }
+ return null;
+ }
+}
diff --git a/xkt/src/main/java/com/ruoyi/xkt/manager/impl/AliPaymentMangerImpl.java b/xkt/src/main/java/com/ruoyi/xkt/manager/impl/AliPaymentMangerImpl.java
index 2de6b57c9..fd6a42b21 100644
--- a/xkt/src/main/java/com/ruoyi/xkt/manager/impl/AliPaymentMangerImpl.java
+++ b/xkt/src/main/java/com/ruoyi/xkt/manager/impl/AliPaymentMangerImpl.java
@@ -1,5 +1,6 @@
package com.ruoyi.xkt.manager.impl;
+import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson2.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
@@ -7,23 +8,29 @@ import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.xkt.domain.AlipayCallback;
import com.ruoyi.xkt.dto.order.StoreOrderInfo;
import com.ruoyi.xkt.dto.payment.AlipayReqDTO;
import com.ruoyi.xkt.enums.EPayChannel;
import com.ruoyi.xkt.enums.EPayFrom;
import com.ruoyi.xkt.manager.PaymentManager;
+import com.ruoyi.xkt.service.IAlipayCallbackService;
import com.ruoyi.xkt.service.IStoreOrderService;
import io.jsonwebtoken.lang.Assert;
+import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
+import java.math.BigDecimal;
+
/**
* @author liangyq
* @date 2025-04-06 19:36
*/
@Slf4j
+@Getter
@Component
public class AliPaymentMangerImpl implements PaymentManager {
/**
@@ -39,7 +46,7 @@ public class AliPaymentMangerImpl implements PaymentManager {
/**
* 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
*/
- @Value("${alipay.publicKey:MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkiTTeQLIkyVHnYiNmRKEtsdlwKftUySN1SLkrhn6CgmHl5ovjPeYteweZEZmsf2kt6wRnaLkODVP7xUQiRVC2cu6StdJyvDzyiYI00u72PvSOvaWHcpzgKqTFpGiQseJQlHnI8U3ob4PxfJylBy8RDQHG9fZwNY1WOCsnSb3m2ufV1EQIjndzTq13yQE6jCz639rO8atlAG3PtJW/QRiGUzyGaOuKsS4HRzPbbpmVtsXoN76+x+WLWkeqlTBEu35X4Hdbkf1C36wp3b68sI5fVyLksF6elRv/It4aUzjXSXbO/Dx+zvMIN01FgwaFV6nLh++k3qlmo87p4I+hvsGiQIDAQAB}")
+ @Value("${alipay.alipayPublicKey:MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkiTTeQLIkyVHnYiNmRKEtsdlwKftUySN1SLkrhn6CgmHl5ovjPeYteweZEZmsf2kt6wRnaLkODVP7xUQiRVC2cu6StdJyvDzyiYI00u72PvSOvaWHcpzgKqTFpGiQseJQlHnI8U3ob4PxfJylBy8RDQHG9fZwNY1WOCsnSb3m2ufV1EQIjndzTq13yQE6jCz639rO8atlAG3PtJW/QRiGUzyGaOuKsS4HRzPbbpmVtsXoN76+x+WLWkeqlTBEu35X4Hdbkf1C36wp3b68sI5fVyLksF6elRv/It4aUzjXSXbO/Dx+zvMIN01FgwaFV6nLh++k3qlmo87p4I+hvsGiQIDAQAB}")
private String alipayPublicKey;
/**
* 服务器异步通知页面路径
@@ -69,6 +76,8 @@ public class AliPaymentMangerImpl implements PaymentManager {
@Autowired
private IStoreOrderService storeOrderService;
+ @Autowired
+ private IAlipayCallbackService alipayCallbackService;
@Override
public EPayChannel channel() {
@@ -117,4 +126,19 @@ public class AliPaymentMangerImpl implements PaymentManager {
}
}
+ public void processAlipayCallback(AlipayCallback alipayCallback) {
+ AlipayCallback info = alipayCallbackService.getByNotifyId(alipayCallback.getNotifyId());
+ if (info == null) {
+ //保存到数据库
+ info = alipayCallback;
+ alipayCallbackService.insertAlipayCallback(info);
+ }
+ if (info.getRefundFee() != null &&
+ !NumberUtil.equals(info.getRefundFee(), BigDecimal.ZERO)) {
+ //如果有退款金额,可能是部分退款的回调,这里不做处理
+ return;
+ }
+ //TODO
+ }
+
}
diff --git a/xkt/src/main/java/com/ruoyi/xkt/mapper/InternalAccountMapper.java b/xkt/src/main/java/com/ruoyi/xkt/mapper/InternalAccountMapper.java
index 50320300c..be4ed4909 100644
--- a/xkt/src/main/java/com/ruoyi/xkt/mapper/InternalAccountMapper.java
+++ b/xkt/src/main/java/com/ruoyi/xkt/mapper/InternalAccountMapper.java
@@ -2,12 +2,31 @@ package com.ruoyi.xkt.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.xkt.domain.InternalAccount;
+import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
+import java.util.Collection;
+import java.util.List;
+
/**
* @author liangyq
* @date 2025-04-02 12:48
*/
@Repository
public interface InternalAccountMapper extends BaseMapper {
+ /**
+ * 获取内部账户(带锁)
+ *
+ * @param id
+ * @return
+ */
+ InternalAccount getForUpdate(@Param("id") Long id);
+
+ /**
+ * 获取内部账户列表(带锁)
+ *
+ * @param ids
+ * @return
+ */
+ List listForUpdate(@Param("ids") Collection ids);
}
diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IAlipayCallbackService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IAlipayCallbackService.java
new file mode 100644
index 000000000..c28aaaaf1
--- /dev/null
+++ b/xkt/src/main/java/com/ruoyi/xkt/service/IAlipayCallbackService.java
@@ -0,0 +1,27 @@
+package com.ruoyi.xkt.service;
+
+import com.ruoyi.xkt.domain.AlipayCallback;
+
+/**
+ * @author liangyq
+ * @date 2025-04-08 17:39
+ */
+public interface IAlipayCallbackService {
+
+ /**
+ * 通过通知ID获取回调信息
+ *
+ * @param notifyId
+ * @return
+ */
+ AlipayCallback getByNotifyId(String notifyId);
+
+ /**
+ * 保存回调信息
+ *
+ * @param alipayCallback
+ * @return
+ */
+ int insertAlipayCallback(AlipayCallback alipayCallback);
+
+}
diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IInternalAccountService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IInternalAccountService.java
new file mode 100644
index 000000000..d13d02f5e
--- /dev/null
+++ b/xkt/src/main/java/com/ruoyi/xkt/service/IInternalAccountService.java
@@ -0,0 +1,30 @@
+package com.ruoyi.xkt.service;
+
+import com.ruoyi.xkt.domain.InternalAccount;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author liangyq
+ * @date 2025-04-08 21:14
+ */
+public interface IInternalAccountService {
+
+ /**
+ * 获取内部账户(加锁)
+ *
+ * @param id
+ * @return
+ */
+ InternalAccount getWithLock(Long id);
+
+ /**
+ * 获取内部账户列表(加锁)
+ *
+ * @param ids
+ * @return
+ */
+ List listWithLock(Collection ids);
+
+}
diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IPaymentBillService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IPaymentBillService.java
new file mode 100644
index 000000000..63f4f2cb7
--- /dev/null
+++ b/xkt/src/main/java/com/ruoyi/xkt/service/IPaymentBillService.java
@@ -0,0 +1,18 @@
+package com.ruoyi.xkt.service;
+
+import com.ruoyi.xkt.dto.order.StoreOrderInfo;
+import com.ruoyi.xkt.dto.payment.PaymentBillInfo;
+
+/**
+ * @author liangyq
+ * @date 2025-04-08 21:14
+ */
+public interface IPaymentBillService {
+ /**
+ * 根据订单创建收款单
+ *
+ * @param orderInfo
+ * @return
+ */
+ PaymentBillInfo createCollectionBillByOrder(StoreOrderInfo orderInfo);
+}
diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java
index 18bc851e6..eda5fe1c9 100644
--- a/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java
+++ b/xkt/src/main/java/com/ruoyi/xkt/service/IStoreOrderService.java
@@ -1,5 +1,6 @@
package com.ruoyi.xkt.service;
+import com.ruoyi.xkt.domain.StoreOrder;
import com.ruoyi.xkt.dto.order.StoreOrderAddDTO;
import com.ruoyi.xkt.dto.order.StoreOrderInfo;
@@ -16,6 +17,14 @@ public interface IStoreOrderService {
*/
StoreOrderInfo createOrder(StoreOrderAddDTO storeOrderAddDTO);
+ /**
+ * 通过订单号获取订单
+ *
+ * @param orderNo
+ * @return
+ */
+ StoreOrder getByOrderNo(String orderNo);
+
/**
* 准备支付订单
*
diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/AlipayCallbackServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/AlipayCallbackServiceImpl.java
new file mode 100644
index 000000000..50c7d0f1a
--- /dev/null
+++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/AlipayCallbackServiceImpl.java
@@ -0,0 +1,36 @@
+package com.ruoyi.xkt.service.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.ruoyi.xkt.domain.AlipayCallback;
+import com.ruoyi.xkt.mapper.AlipayCallbackMapper;
+import com.ruoyi.xkt.service.IAlipayCallbackService;
+import io.jsonwebtoken.lang.Assert;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * @author liangyq
+ * @date 2025-04-08 17:40
+ */
+@Service
+public class AlipayCallbackServiceImpl implements IAlipayCallbackService {
+
+ @Autowired
+ private AlipayCallbackMapper alipayCallbackMapper;
+
+
+ @Override
+ public AlipayCallback getByNotifyId(String notifyId) {
+ Assert.notNull(notifyId);
+ return alipayCallbackMapper.selectOne(Wrappers.lambdaQuery(AlipayCallback.class)
+ .eq(AlipayCallback::getNotifyId, notifyId));
+ }
+
+ @Transactional
+ @Override
+ public int insertAlipayCallback(AlipayCallback alipayCallback) {
+ Assert.notNull(alipayCallback);
+ return alipayCallbackMapper.insert(alipayCallback);
+ }
+}
diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/InternalAccountServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/InternalAccountServiceImpl.java
new file mode 100644
index 000000000..aed4268ec
--- /dev/null
+++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/InternalAccountServiceImpl.java
@@ -0,0 +1,37 @@
+package com.ruoyi.xkt.service.impl;
+
+import com.ruoyi.xkt.domain.InternalAccount;
+import com.ruoyi.xkt.mapper.InternalAccountMapper;
+import com.ruoyi.xkt.mapper.InternalAccountTransDetailMapper;
+import com.ruoyi.xkt.service.IInternalAccountService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author liangyq
+ * @date 2025-04-08 21:14
+ */
+@Service
+public class InternalAccountServiceImpl implements IInternalAccountService {
+
+ @Autowired
+ private InternalAccountMapper internalAccountMapper;
+ @Autowired
+ private InternalAccountTransDetailMapper internalAccountTransDetailMapper;
+
+ @Transactional
+ @Override
+ public InternalAccount getWithLock(Long id) {
+ return internalAccountMapper.getForUpdate(id);
+ }
+
+ @Transactional
+ @Override
+ public List listWithLock(Collection ids) {
+ return internalAccountMapper.listForUpdate(ids);
+ }
+}
diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/PaymentBillServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/PaymentBillServiceImpl.java
new file mode 100644
index 000000000..551233b93
--- /dev/null
+++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/PaymentBillServiceImpl.java
@@ -0,0 +1,35 @@
+package com.ruoyi.xkt.service.impl;
+
+import com.ruoyi.common.constant.Constants;
+import com.ruoyi.xkt.domain.InternalAccount;
+import com.ruoyi.xkt.dto.order.StoreOrderInfo;
+import com.ruoyi.xkt.dto.payment.PaymentBillInfo;
+import com.ruoyi.xkt.mapper.PaymentBillDetailMapper;
+import com.ruoyi.xkt.mapper.PaymentBillMapper;
+import com.ruoyi.xkt.service.IInternalAccountService;
+import com.ruoyi.xkt.service.IPaymentBillService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * @author liangyq
+ * @date 2025-04-08 21:14
+ */
+@Service
+public class PaymentBillServiceImpl implements IPaymentBillService {
+
+ @Autowired
+ private PaymentBillMapper paymentBillMapper;
+ @Autowired
+ private PaymentBillDetailMapper paymentBillDetailMapper;
+ @Autowired
+ private IInternalAccountService internalAccountService;
+
+ @Transactional
+ @Override
+ public PaymentBillInfo createCollectionBillByOrder(StoreOrderInfo orderInfo) {
+ InternalAccount ca = internalAccountService.getWithLock(Constants.PLATFORM_INTERNAL_ACCOUNT_ID);
+ return null;
+ }
+}
diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java
index dd8d88ce8..63ef3c0bd 100644
--- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java
+++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreOrderServiceImpl.java
@@ -163,6 +163,13 @@ public class StoreOrderServiceImpl implements IStoreOrderService {
return new StoreOrderInfo(order, orderDetailList);
}
+ @Override
+ public StoreOrder getByOrderNo(String orderNo) {
+ Assert.notNull(orderNo);
+ return storeOrderMapper.selectOne(Wrappers.lambdaQuery(StoreOrder.class)
+ .eq(StoreOrder::getOrderNo, orderNo));
+ }
+
@Transactional
@Override
public StoreOrderInfo preparePayOrder(Long storeOrderId) {
diff --git a/xkt/src/main/resources/mapper/InternalAccountMapper.xml b/xkt/src/main/resources/mapper/InternalAccountMapper.xml
index af5cc8f60..247bb217c 100644
--- a/xkt/src/main/resources/mapper/InternalAccountMapper.xml
+++ b/xkt/src/main/resources/mapper/InternalAccountMapper.xml
@@ -2,4 +2,15 @@
+
+
\ No newline at end of file