feat:订单支付
parent
e9ba3fe08a
commit
a7084826ed
|
|
@ -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;
|
||||
|
||||
/**
|
||||
* 支付宝服务器异步通知
|
||||
* <p>
|
||||
* 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<String, String> 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<String, String> getParamsMap(HttpServletRequest request) {
|
||||
Map<String, String> 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<String, String> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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<PaymentBillDetail> paymentBillDetails;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<InternalAccount> {
|
||||
/**
|
||||
* 获取内部账户(带锁)
|
||||
*
|
||||
* @param id
|
||||
* @return
|
||||
*/
|
||||
InternalAccount getForUpdate(@Param("id") Long id);
|
||||
|
||||
/**
|
||||
* 获取内部账户列表(带锁)
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
List<InternalAccount> listForUpdate(@Param("ids") Collection<Long> ids);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
@ -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<InternalAccount> listWithLock(Collection<Long> ids);
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
||||
/**
|
||||
* 准备支付订单
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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<InternalAccount> listWithLock(Collection<Long> ids) {
|
||||
return internalAccountMapper.listForUpdate(ids);
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -2,4 +2,15 @@
|
|||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ruoyi.xkt.mapper.InternalAccountMapper">
|
||||
|
||||
<select id="getForUpdate" resultType="com.ruoyi.xkt.domain.InternalAccount">
|
||||
SELECT *
|
||||
FROM internal_account
|
||||
WHERE id = #{id} FOR UPDATE
|
||||
</select>
|
||||
<select id="listForUpdate" resultType="com.ruoyi.xkt.domain.InternalAccount">
|
||||
SELECT *
|
||||
FROM internal_account
|
||||
WHERE id IN
|
||||
<foreach collection="ids" item="id" separator="," open="(" close=")">#{id}</foreach> FOR UPDATE
|
||||
</select>
|
||||
</mapper>
|
||||
Loading…
Reference in New Issue