订单退款
This commit is contained in:
parent
1225a4efdc
commit
f2109eee9b
|
@ -2,6 +2,7 @@ package gmodel
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fusenapi/utils/handler"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
@ -35,6 +36,32 @@ func (m *FsRefundReasonModel) CreateOrUpdate(ctx context.Context, req *FsRefundR
|
|||
return req, err
|
||||
}
|
||||
|
||||
func (m *FsRefundReasonModel) FindOneByQuery(ctx context.Context, rowBuilder *gorm.DB, filterMap map[string]string) (*FsRefundReason, error) {
|
||||
var resp FsRefundReason
|
||||
|
||||
if filterMap != nil {
|
||||
rowBuilder = rowBuilder.Scopes(handler.FilterData(filterMap))
|
||||
}
|
||||
|
||||
result := rowBuilder.WithContext(ctx).Limit(1).Find(&resp)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
} else {
|
||||
return &resp, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (m *FsRefundReasonModel) RowSelectBuilder(selectData []string) *gorm.DB {
|
||||
var rowBuilder = m.db.Table(m.name)
|
||||
|
||||
if selectData != nil {
|
||||
rowBuilder = rowBuilder.Select(selectData)
|
||||
} else {
|
||||
rowBuilder = rowBuilder.Select("*")
|
||||
}
|
||||
return rowBuilder
|
||||
}
|
||||
|
||||
func (m *FsRefundReasonModel) TableName() string {
|
||||
return m.name
|
||||
}
|
||||
|
|
|
@ -52,18 +52,18 @@ func (l *UserOrderCancelLogic) UserOrderCancel(req *types.UserOrderCancelReq, us
|
|||
}
|
||||
|
||||
// 判断订单状态
|
||||
var notCancelStatusMap = make(map[constants.Order]struct{}, 3)
|
||||
notCancelStatusMap[constants.STATUS_NEW_NOT_PAY] = struct{}{}
|
||||
notCancelStatusMap[constants.STATUS_NEW_PART_PAY] = struct{}{}
|
||||
notCancelStatusMap[constants.STATUS_NEW_PAY_COMPLETED] = struct{}{}
|
||||
_, ok := notCancelStatusMap[constants.Order(*orderInfo.Status)]
|
||||
var notCancelStatusMap = make(map[int64]struct{}, 3)
|
||||
notCancelStatusMap[int64(constants.STATUS_NEW_NOT_PAY)] = struct{}{}
|
||||
notCancelStatusMap[int64(constants.STATUS_NEW_PART_PAY)] = struct{}{}
|
||||
notCancelStatusMap[int64(constants.STATUS_NEW_PAY_COMPLETED)] = struct{}{}
|
||||
_, ok := notCancelStatusMap[int64(*orderInfo.Status)]
|
||||
if !ok {
|
||||
return resp.SetStatusWithMessage(basic.CodeOrderNotCancelledErr, "the order status not cancle")
|
||||
}
|
||||
|
||||
var cancelTime int64 = time.Now().Unix() - (*orderInfo.Ctime + int64(constants.CANCLE_ORDER_EXPIRE))
|
||||
// 第一次支付成功后48小时后不能进行取消操作
|
||||
if orderInfo.IsPayCompleted != nil && cancelTime > 0 {
|
||||
if *orderInfo.IsPayCompleted == 1 && cancelTime > 0 {
|
||||
return resp.SetStatusWithMessage(basic.CodeOrderNotCancelledErr, "The current order cannot be cancelled")
|
||||
}
|
||||
|
||||
|
|
|
@ -106,12 +106,13 @@ func (l *StripeWebhookLogic) StripeWebhook(req *types.StripeWebhookReq, userinfo
|
|||
var paymentIntent stripe.PaymentIntent
|
||||
err := json.Unmarshal(event.Data.Raw, &paymentIntent)
|
||||
if err != nil {
|
||||
logx.Error(err)
|
||||
logx.Errorf("err:%+v,desc:%s", err, "pay notify Unmarshal fail event.Type payment_intent.succeeded")
|
||||
return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type payment_intent.succeeded")
|
||||
}
|
||||
err = l.HandlePaymentIntentSucceeded(&paymentIntent)
|
||||
if err != nil {
|
||||
return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type Unhandled")
|
||||
logx.Errorf("err:%+v,desc:%s", err, "pay notify handle payment_intent.succeeded")
|
||||
return resp.SetStatusWithMessage(basic.CodePaybackNotOk, "pay notify handle payment_intent.succeeded")
|
||||
}
|
||||
case "payment_method.attached":
|
||||
var paymentMethod stripe.PaymentMethod
|
||||
|
@ -120,6 +121,19 @@ func (l *StripeWebhookLogic) StripeWebhook(req *types.StripeWebhookReq, userinfo
|
|||
logx.Error(err)
|
||||
return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type payment_method.attached")
|
||||
}
|
||||
case "charge.refunded":
|
||||
var chargeRefunded stripe.Charge
|
||||
err := json.Unmarshal(event.Data.Raw, &chargeRefunded)
|
||||
if err != nil {
|
||||
logx.Errorf("err:%+v,desc:%s", err, "pay notify Unmarshal fail event.Type charge.refunded")
|
||||
return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type charge.refunded")
|
||||
}
|
||||
err = l.HandleChargeRefunded(&chargeRefunded)
|
||||
if err != nil {
|
||||
logx.Errorf("err:%+v,desc:%s", err, "pay notify handle charge.refunded")
|
||||
return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify handle charge.refunded")
|
||||
}
|
||||
|
||||
// ... handle other event types
|
||||
default:
|
||||
logx.Error("Unhandled event")
|
||||
|
@ -135,6 +149,66 @@ func (l *StripeWebhookLogic) HandlePayEventCreate(fsPayEvent *gmodel.FsPayEvent)
|
|||
return err
|
||||
}
|
||||
|
||||
// 退款成功
|
||||
func (l *StripeWebhookLogic) HandleChargeRefunded(chargeRefunded *stripe.Charge) (err error) {
|
||||
// 退款成功
|
||||
if chargeRefunded.Status == "succeeded" {
|
||||
orderModel := gmodel.NewFsOrderModel(l.svcCtx.MysqlConn)
|
||||
err = orderModel.Trans(l.ctx, func(ctx context.Context, connGorm *gorm.DB) (err error) {
|
||||
// 查询支付记录
|
||||
payModelT := gmodel.NewFsPayModel(connGorm)
|
||||
payModelTRSB := payModelT.RowSelectBuilder(nil)
|
||||
payModelTRSB1 := payModelTRSB.Where("trade_no = ?", chargeRefunded.PaymentIntent.ID).Where("pay_status = ?", constants.PAYSTATUS_SUCCESS).Where("is_refund = ?", 0)
|
||||
payInfo, err := payModelT.FindOneByQuery(l.ctx, payModelTRSB1, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 更新支付记录
|
||||
*payInfo.IsRefund = 1
|
||||
_, err = payModelT.CreateOrUpdate(ctx, payInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 获取是否还有未退款的数据
|
||||
payModelTRSB2 := payModelTRSB.Where("order_number = ?", payInfo.OrderNumber).Where("pay_status = ?", constants.PAYSTATUS_SUCCESS).Where("is_refund = ?", 0)
|
||||
count, err := payModelT.FindCount(l.ctx, payModelTRSB2, nil)
|
||||
if count == 0 {
|
||||
// 退款完成更新订单状态
|
||||
orderModelT := gmodel.NewFsOrderModel(connGorm)
|
||||
orderModelTRSB := orderModelT.RowSelectBuilder(nil).Where("sn =?", payInfo.OrderNumber)
|
||||
orderInfoRel, err := orderModelT.FindOneByQuery(ctx, orderModelTRSB, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var isRefunded int64 = 1
|
||||
var isRefunding int64 = 1
|
||||
var orderStatus int64 = int64(constants.STATUS_NEW_REFUNDED)
|
||||
var orderInfo = &gmodel.FsOrder{}
|
||||
orderInfo.Id = orderInfoRel.Id
|
||||
orderInfo.IsRefunded = &isRefunded
|
||||
orderInfo.IsRefunding = &isRefunding
|
||||
orderInfo.Status = &orderStatus
|
||||
orderModelT.Update(ctx, orderInfo)
|
||||
|
||||
// 记录退款原因
|
||||
refundReasonModelT := gmodel.NewFsRefundReasonModel(connGorm)
|
||||
refundReasonModelTRSB := refundReasonModelT.RowSelectBuilder(nil).Where("order_id =?", orderInfoRel.Id)
|
||||
refundReasonInfo, err := refundReasonModelT.FindOneByQuery(ctx, refundReasonModelTRSB, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*refundReasonInfo.IsRefund = 1
|
||||
_, err = refundReasonModelT.CreateOrUpdate(ctx, refundReasonInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return err
|
||||
})
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// session完成
|
||||
// func (l *StripeWebhookLogic) handlePaymentSessionCompleted(sessionId string, tradeNo string) (err error) {
|
||||
// // 查询支付记录
|
||||
|
@ -157,7 +231,7 @@ func (l *StripeWebhookLogic) HandlePayEventCreate(fsPayEvent *gmodel.FsPayEvent)
|
|||
// return err
|
||||
// }
|
||||
|
||||
// 成功的付款
|
||||
// 付款成功
|
||||
func (l *StripeWebhookLogic) HandlePaymentIntentSucceeded(paymentIntent *stripe.PaymentIntent) error {
|
||||
orderSn, ok := paymentIntent.Metadata["order_sn"]
|
||||
if !ok || orderSn == "" {
|
||||
|
|
|
@ -62,6 +62,8 @@ var (
|
|||
CodePayCancelOk = &StatusResponse{5021, "cancellation successful"} // 支付取消成功
|
||||
CodePayCancelNotOk = &StatusResponse{5022, "cancellation failed"} // 支付取消失败
|
||||
|
||||
CodePaybackNotOk = &StatusResponse{5023, "pay back failed"} // 支付回调处理失败
|
||||
|
||||
CodeGuestDupErr = &StatusResponse{5010, "user is already guest and does not need to reapply"} // 用户已经是访客用户,无需重复申请
|
||||
CodeGuestGenErr = &StatusResponse{5011, "serialization failed for guest ID"} // 访客ID序列化失败
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user