从Stripe退款后,修改订单状态,添加退款记录
This commit is contained in:
@@ -22,6 +22,8 @@ public class PaymentInfo extends BaseEntity{
|
|||||||
* paid and liquidated means the refund request has been executed.
|
* paid and liquidated means the refund request has been executed.
|
||||||
* expired means the request has been rejected.
|
* expired means the request has been rejected.
|
||||||
* wait means the request is still under processing.
|
* wait means the request is still under processing.
|
||||||
|
* -------------------------------------------------
|
||||||
|
* 退款:Partial refund 部分退款; Refunded 全部退款
|
||||||
*/
|
*/
|
||||||
private String tradeState;//交易状态
|
private String tradeState;//交易状态
|
||||||
|
|
||||||
|
|||||||
@@ -13,11 +13,14 @@ public class RefundInfo extends BaseEntity{
|
|||||||
|
|
||||||
private String refundId;//支付系统退款单号(微信)
|
private String refundId;//支付系统退款单号(微信)
|
||||||
|
|
||||||
|
// 退款必定对应一次具体的收费款项
|
||||||
|
private String chargeId;
|
||||||
|
|
||||||
// private Integer totalFee;//原订单金额(分)
|
// private Integer totalFee;//原订单金额(分)
|
||||||
private Float totalFee;//原订单金额(分)
|
private Float totalFee;//原订单金额(分)
|
||||||
|
|
||||||
// private Integer refund;//退款金额(分)
|
// private Integer refund;//退款金额(分)
|
||||||
private Float refund;//退款金额(分)
|
private Float refund;//退款金额(元)
|
||||||
|
|
||||||
private String reason;//退款原因
|
private String reason;//退款原因
|
||||||
|
|
||||||
|
|||||||
@@ -34,4 +34,6 @@ public interface PaymentInfoService extends IService<PaymentInfo> {
|
|||||||
PageBaseResponse<OrderListVO> getPaymentInfo(QueryPageByTimeDTO queryPageByTimeDTO);
|
PageBaseResponse<OrderListVO> getPaymentInfo(QueryPageByTimeDTO queryPageByTimeDTO);
|
||||||
|
|
||||||
List<PaymentInfo> getPaymentInfoByPromCode(Long accountId, String promCode);
|
List<PaymentInfo> getPaymentInfoByPromCode(Long accountId, String promCode);
|
||||||
|
|
||||||
|
PaymentInfo updatePaymentRefundStatus(Charge charge);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package com.ai.da.service;
|
|||||||
|
|
||||||
import com.ai.da.mapper.primary.entity.RefundInfo;
|
import com.ai.da.mapper.primary.entity.RefundInfo;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import com.stripe.model.Charge;
|
||||||
|
import com.stripe.model.Refund;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -19,4 +21,13 @@ public interface RefundInfoService extends IService<RefundInfo> {
|
|||||||
void updateRefundForAliPay(String refundNo, String content, String refundStatus);
|
void updateRefundForAliPay(String refundNo, String content, String refundStatus);
|
||||||
|
|
||||||
void updateRefundForPayPal(Long id, String refundId, 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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -435,4 +435,28 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
|||||||
public List<PaymentInfo> getPaymentInfoByPromCode(Long accountId, String promCode){
|
public List<PaymentInfo> getPaymentInfoByPromCode(Long accountId, String promCode){
|
||||||
return baseMapper.selectPaidPaymentsByAccountAndPromotion(accountId, 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,14 +10,16 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.google.gson.Gson;
|
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 org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.HashMap;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class RefundInfoServiceImpl extends ServiceImpl<RefundInfoMapper, RefundInfo> implements RefundInfoService {
|
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.update(refundInfo, queryWrapper);
|
||||||
baseMapper.updateById(refundInfo);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -430,6 +430,26 @@ public class StripeServiceImpl implements StripeService {
|
|||||||
orderInfo.setOrderStatus(OrderStatusEnum.SUCCESS.getType());
|
orderInfo.setOrderStatus(OrderStatusEnum.SUCCESS.getType());
|
||||||
orderInfo.setNote("");
|
orderInfo.setNote("");
|
||||||
orderInfoService.updateById(orderInfo);
|
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());
|
log.info("回调事件 {} 处理完成", event.getType());
|
||||||
|
|||||||
Reference in New Issue
Block a user