从Stripe退款后,修改订单状态,添加退款记录

This commit is contained in:
2025-04-25 10:06:07 +08:00
parent 58bd986090
commit a2d259aea1
7 changed files with 127 additions and 4 deletions

View File

@@ -22,6 +22,8 @@ public class PaymentInfo extends BaseEntity{
* paid and liquidated means the refund request has been executed.
* expired means the request has been rejected.
* wait means the request is still under processing.
* -------------------------------------------------
* 退款Partial refund 部分退款; Refunded 全部退款
*/
private String tradeState;//交易状态

View File

@@ -13,11 +13,14 @@ public class RefundInfo extends BaseEntity{
private String refundId;//支付系统退款单号(微信)
// 退款必定对应一次具体的收费款项
private String chargeId;
// private Integer totalFee;//原订单金额(分)
private Float totalFee;//原订单金额(分)
// private Integer refund;//退款金额(分)
private Float refund;//退款金额()
private Float refund;//退款金额()
private String reason;//退款原因

View File

@@ -34,4 +34,6 @@ public interface PaymentInfoService extends IService<PaymentInfo> {
PageBaseResponse<OrderListVO> getPaymentInfo(QueryPageByTimeDTO queryPageByTimeDTO);
List<PaymentInfo> getPaymentInfoByPromCode(Long accountId, String promCode);
PaymentInfo updatePaymentRefundStatus(Charge charge);
}

View File

@@ -3,6 +3,8 @@ package com.ai.da.service;
import com.ai.da.mapper.primary.entity.RefundInfo;
import com.baomidou.mybatisplus.extension.service.IService;
import com.stripe.model.Charge;
import com.stripe.model.Refund;
import java.util.List;
@@ -19,4 +21,13 @@ public interface RefundInfoService extends IService<RefundInfo> {
void updateRefundForAliPay(String refundNo, String content, String refundStatus);
void updateRefundForPayPal(Long id, String refundId, String content, String refundStatus);
List<RefundInfo> getByChargeId(String chargeId);
RefundInfo createRefundForStripe(Refund refund);
RefundInfo updateRefundStatusForStripe(Refund refund);
RefundInfo updateRefundForStripe(Charge charge);
}

View File

@@ -435,4 +435,28 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
public List<PaymentInfo> getPaymentInfoByPromCode(Long accountId, String promCode){
return baseMapper.selectPaidPaymentsByAccountAndPromotion(accountId, promCode);
}
public PaymentInfo updatePaymentRefundStatus(Charge charge){
// 判断当前退款是部分退款还是全部退款
QueryWrapper<PaymentInfo> qw = new QueryWrapper<>();
qw.eq("transaction_id", charge.getInvoice());
PaymentInfo paymentInfo = baseMapper.selectOne(qw);
if (Objects.nonNull(paymentInfo)){
String status ;
if (Objects.equals(charge.getAmount(), charge.getAmountRefunded())){
status = "Refunded";
}else if (charge.getAmount() > charge.getAmountRefunded()){
status = "Partial refund";
}else {
status = "Refund Exception";
log.warn("{}, 退款金额高于付款金额, ChargeId为{}", status, charge.getId());
}
if (!paymentInfo.getTradeState().equals(status)){
paymentInfo.setTradeState(status);
paymentInfo.setUpdateTime(LocalDateTime.now());
baseMapper.updateById(paymentInfo);
}
}
return null;
}
}

View File

@@ -10,14 +10,16 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.stripe.model.Charge;
import com.stripe.model.Refund;
import io.netty.util.internal.StringUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.Duration;
import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.time.LocalDateTime;
import java.util.*;
@Service
public class RefundInfoServiceImpl extends ServiceImpl<RefundInfoMapper, RefundInfo> implements RefundInfoService {
@@ -170,4 +172,63 @@ public class RefundInfoServiceImpl extends ServiceImpl<RefundInfoMapper, RefundI
// baseMapper.update(refundInfo, queryWrapper);
baseMapper.updateById(refundInfo);
}
public List<RefundInfo> getByChargeId(String chargeId){
List<RefundInfo> refundInfoList = baseMapper.selectList(new QueryWrapper<RefundInfo>().eq("charge_id", chargeId));
// 判断当前已退款的金额是否全部退完(针对多次部分退款的情况)
if (refundInfoList.isEmpty()){
return new ArrayList<>();
}else {
return refundInfoList;
}
}
public RefundInfo getByRefundId(String refundId){
return baseMapper.selectOne(new QueryWrapper<RefundInfo>().eq("refund_id", refundId));
}
public RefundInfo createRefundForStripe(Refund refund){
// 先确认这个回调是否已经被记录
RefundInfo refundInfo = getByRefundId(refund.getId());
if (Objects.isNull(refundInfo)){
refundInfo = new RefundInfo();
refundInfo.setRefundId(refund.getId());
refundInfo.setChargeId(refund.getCharge());
refundInfo.setRefund(refund.getAmount() / 100f);
refundInfo.setReason(refund.getReason());
refundInfo.setRefundStatus(refund.getStatus());
refundInfo.setCreateTime(LocalDateTime.now());
baseMapper.insert(refundInfo);
}
return refundInfo;
}
public RefundInfo updateRefundStatusForStripe(Refund refund){
RefundInfo refundInfo = getByRefundId(refund.getId());
if (Objects.isNull(refundInfo)){
return null;
}
if (!refundInfo.getRefundStatus().equals(refund.getStatus())){
refundInfo.setRefundStatus(refund.getStatus());
refundInfo.setUpdateTime(LocalDateTime.now());
baseMapper.updateById(refundInfo);
}
return refundInfo;
}
public RefundInfo updateRefundForStripe(Charge charge){
List<RefundInfo> refundInfoList = getByChargeId(charge.getId());
if (!refundInfoList.isEmpty()){
RefundInfo refundInfo = refundInfoList.get(refundInfoList.size() - 1);
if (StringUtil.isNullOrEmpty(refundInfo.getOrderNo())){
String orderNo = charge.getDescription().replace("AiDA - ", "");
refundInfo.setOrderNo(orderNo);
refundInfo.setTotalFee(charge.getAmount() / 100f);
refundInfo.setUpdateTime(LocalDateTime.now());
baseMapper.updateById(refundInfo);
return refundInfo;
}
}
return null;
}
}

View File

@@ -430,6 +430,26 @@ public class StripeServiceImpl implements StripeService {
orderInfo.setOrderStatus(OrderStatusEnum.SUCCESS.getType());
orderInfo.setNote("");
orderInfoService.updateById(orderInfo);
}else if (event.getType().equals("charge.refunded")){
// 更新退款信息
RefundInfo refundInfo = refundInfoService.updateRefundForStripe(charge);
// 更新 t_payment_info的支付状态
if (Objects.nonNull(refundInfo)){
paymentInfoService.updatePaymentRefundStatus(charge);
}
}
}else if (stripeObject instanceof Refund){
Refund refund = (Refund) stripeObject;
if (event.getType().equals("refund.created")){
// 新增退款信息
refundInfoService.createRefundForStripe(refund);
}else if (event.getType().equals("refund.updated")){
// 根据***id更新退款记录信息
RefundInfo refundInfo = refundInfoService.updateRefundStatusForStripe(refund);
if (Objects.isNull(refundInfo)){
// 等事件先创建,再更新。回调事件的顺序随机
response = false;
}
}
}
log.info("回调事件 {} 处理完成", event.getType());