订单退款
This commit is contained in:
parent
1225a4efdc
commit
f2109eee9b
|
@ -2,6 +2,7 @@ package gmodel
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fusenapi/utils/handler"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
@ -35,6 +36,32 @@ func (m *FsRefundReasonModel) CreateOrUpdate(ctx context.Context, req *FsRefundR
|
||||||
return req, err
|
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 {
|
func (m *FsRefundReasonModel) TableName() string {
|
||||||
return m.name
|
return m.name
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,18 +52,18 @@ func (l *UserOrderCancelLogic) UserOrderCancel(req *types.UserOrderCancelReq, us
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断订单状态
|
// 判断订单状态
|
||||||
var notCancelStatusMap = make(map[constants.Order]struct{}, 3)
|
var notCancelStatusMap = make(map[int64]struct{}, 3)
|
||||||
notCancelStatusMap[constants.STATUS_NEW_NOT_PAY] = struct{}{}
|
notCancelStatusMap[int64(constants.STATUS_NEW_NOT_PAY)] = struct{}{}
|
||||||
notCancelStatusMap[constants.STATUS_NEW_PART_PAY] = struct{}{}
|
notCancelStatusMap[int64(constants.STATUS_NEW_PART_PAY)] = struct{}{}
|
||||||
notCancelStatusMap[constants.STATUS_NEW_PAY_COMPLETED] = struct{}{}
|
notCancelStatusMap[int64(constants.STATUS_NEW_PAY_COMPLETED)] = struct{}{}
|
||||||
_, ok := notCancelStatusMap[constants.Order(*orderInfo.Status)]
|
_, ok := notCancelStatusMap[int64(*orderInfo.Status)]
|
||||||
if !ok {
|
if !ok {
|
||||||
return resp.SetStatusWithMessage(basic.CodeOrderNotCancelledErr, "the order status not cancle")
|
return resp.SetStatusWithMessage(basic.CodeOrderNotCancelledErr, "the order status not cancle")
|
||||||
}
|
}
|
||||||
|
|
||||||
var cancelTime int64 = time.Now().Unix() - (*orderInfo.Ctime + int64(constants.CANCLE_ORDER_EXPIRE))
|
var cancelTime int64 = time.Now().Unix() - (*orderInfo.Ctime + int64(constants.CANCLE_ORDER_EXPIRE))
|
||||||
// 第一次支付成功后48小时后不能进行取消操作
|
// 第一次支付成功后48小时后不能进行取消操作
|
||||||
if orderInfo.IsPayCompleted != nil && cancelTime > 0 {
|
if *orderInfo.IsPayCompleted == 1 && cancelTime > 0 {
|
||||||
return resp.SetStatusWithMessage(basic.CodeOrderNotCancelledErr, "The current order cannot be cancelled")
|
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
|
var paymentIntent stripe.PaymentIntent
|
||||||
err := json.Unmarshal(event.Data.Raw, &paymentIntent)
|
err := json.Unmarshal(event.Data.Raw, &paymentIntent)
|
||||||
if err != nil {
|
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")
|
return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type payment_intent.succeeded")
|
||||||
}
|
}
|
||||||
err = l.HandlePaymentIntentSucceeded(&paymentIntent)
|
err = l.HandlePaymentIntentSucceeded(&paymentIntent)
|
||||||
if err != nil {
|
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":
|
case "payment_method.attached":
|
||||||
var paymentMethod stripe.PaymentMethod
|
var paymentMethod stripe.PaymentMethod
|
||||||
|
@ -120,6 +121,19 @@ func (l *StripeWebhookLogic) StripeWebhook(req *types.StripeWebhookReq, userinfo
|
||||||
logx.Error(err)
|
logx.Error(err)
|
||||||
return resp.SetStatusWithMessage(basic.CodeAesCbcDecryptionErr, "pay notify Unmarshal fail event.Type payment_method.attached")
|
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
|
// ... handle other event types
|
||||||
default:
|
default:
|
||||||
logx.Error("Unhandled event")
|
logx.Error("Unhandled event")
|
||||||
|
@ -135,6 +149,66 @@ func (l *StripeWebhookLogic) HandlePayEventCreate(fsPayEvent *gmodel.FsPayEvent)
|
||||||
return err
|
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完成
|
// session完成
|
||||||
// func (l *StripeWebhookLogic) handlePaymentSessionCompleted(sessionId string, tradeNo string) (err error) {
|
// func (l *StripeWebhookLogic) handlePaymentSessionCompleted(sessionId string, tradeNo string) (err error) {
|
||||||
// // 查询支付记录
|
// // 查询支付记录
|
||||||
|
@ -157,7 +231,7 @@ func (l *StripeWebhookLogic) HandlePayEventCreate(fsPayEvent *gmodel.FsPayEvent)
|
||||||
// return err
|
// return err
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// 成功的付款
|
// 付款成功
|
||||||
func (l *StripeWebhookLogic) HandlePaymentIntentSucceeded(paymentIntent *stripe.PaymentIntent) error {
|
func (l *StripeWebhookLogic) HandlePaymentIntentSucceeded(paymentIntent *stripe.PaymentIntent) error {
|
||||||
orderSn, ok := paymentIntent.Metadata["order_sn"]
|
orderSn, ok := paymentIntent.Metadata["order_sn"]
|
||||||
if !ok || orderSn == "" {
|
if !ok || orderSn == "" {
|
||||||
|
|
|
@ -62,6 +62,8 @@ var (
|
||||||
CodePayCancelOk = &StatusResponse{5021, "cancellation successful"} // 支付取消成功
|
CodePayCancelOk = &StatusResponse{5021, "cancellation successful"} // 支付取消成功
|
||||||
CodePayCancelNotOk = &StatusResponse{5022, "cancellation failed"} // 支付取消失败
|
CodePayCancelNotOk = &StatusResponse{5022, "cancellation failed"} // 支付取消失败
|
||||||
|
|
||||||
|
CodePaybackNotOk = &StatusResponse{5023, "pay back failed"} // 支付回调处理失败
|
||||||
|
|
||||||
CodeGuestDupErr = &StatusResponse{5010, "user is already guest and does not need to reapply"} // 用户已经是访客用户,无需重复申请
|
CodeGuestDupErr = &StatusResponse{5010, "user is already guest and does not need to reapply"} // 用户已经是访客用户,无需重复申请
|
||||||
CodeGuestGenErr = &StatusResponse{5011, "serialization failed for guest ID"} // 访客ID序列化失败
|
CodeGuestGenErr = &StatusResponse{5011, "serialization failed for guest ID"} // 访客ID序列化失败
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user