fix: 延期订单超时不关闭、无法继续支付、不能作废
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
- 支付宝查单把 ACQ.TRADE_NOT_EXIST 当成查单失败,恢复任务永远判为未知,订单停在待支付; 同一套餐再下单时旧单也关不掉,新单无法创建。改为按"渠道无此订单"处理,过支付截止后关闭 - 延期订单详情对未过期的待支付订单返回 qr_content,后台可展示二维码、H5 可继续支付 - 新增作废待支付订单:后台 POST /orders/:id/close、H5 POST /orders/:id/cancel;作废前先查单,已支付则按支付成功办理
This commit is contained in:
101
internal/application/packagesilence/order_cancel.go
Normal file
101
internal/application/packagesilence/order_cancel.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package packagesilence
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
agentrechargeApp "github.com/break/junhong_cmp_fiber/internal/application/agentrecharge"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
||||
"github.com/break/junhong_cmp_fiber/internal/store/postgres"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||||
)
|
||||
|
||||
// CancelOrderCommand 是作废待支付延期订单的命令:Scope.CustomerID 非 0 为 H5 客户作废自己的订单,为 0 为后台运营作废。
|
||||
type CancelOrderCommand struct {
|
||||
OrderID uint
|
||||
Scope Scope
|
||||
Reason string
|
||||
}
|
||||
|
||||
// CancelPendingOrder 作废未支付的在线延期订单,作废后同一套餐可以重新下单。
|
||||
//
|
||||
// 作废前先按冻结商户查单:渠道已支付则按支付成功处理(照常延期)并拒绝作废;
|
||||
// 其余情况(未支付、渠道无此订单、查单失败)直接关闭。关闭后才到达的支付会进入异常并由恢复任务原路退款,不会吞款。
|
||||
func (s *ExtensionService) CancelPendingOrder(ctx context.Context, command CancelOrderCommand) (*dto.SilenceExtensionOrderResponse, error) {
|
||||
if command.Scope.CustomerID == 0 {
|
||||
if err := s.requirePermission(ctx, constants.PermissionPackageSilenceExtend); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
order, err := postgres.NewPackageSilenceOrderStore(s.db).GetByID(ctx, command.OrderID)
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, errors.New(errors.CodeNotFound, "延期订单不存在")
|
||||
}
|
||||
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询延期订单失败")
|
||||
}
|
||||
if command.Scope.CustomerID != 0 && (order.CustomerID == nil || *order.CustomerID != command.Scope.CustomerID) {
|
||||
return nil, errors.New(errors.CodeNotFound, "延期订单不存在")
|
||||
}
|
||||
if order.Status != constants.SilenceOrderStatusPendingPayment {
|
||||
return nil, errors.New(errors.CodeInvalidStatus, "只有待支付的延期订单可以作废")
|
||||
}
|
||||
|
||||
paid, err := s.confirmIfPaid(ctx, order)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if paid {
|
||||
return nil, errors.New(errors.CodeInvalidStatus, "该订单已支付,已按支付成功办理延期,不能作废")
|
||||
}
|
||||
|
||||
reason := "手动作废"
|
||||
if command.Scope.CustomerID != 0 {
|
||||
reason = "客户作废"
|
||||
}
|
||||
if extra := strings.TrimSpace(command.Reason); extra != "" {
|
||||
reason += ":" + extra
|
||||
}
|
||||
if err := s.closeOrder(ctx, order.ID, reason); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
current, err := postgres.NewPackageSilenceOrderStore(s.db).GetByID(ctx, order.ID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询延期订单失败")
|
||||
}
|
||||
return s.orderResponse(ctx, current, false)
|
||||
}
|
||||
|
||||
// confirmIfPaid 查询订单下待支付的支付单;渠道已支付时走支付确认并返回 true。查单失败不阻止作废。
|
||||
func (s *ExtensionService) confirmIfPaid(ctx context.Context, order *model.PackageSilenceExtensionOrder) (bool, error) {
|
||||
if order.PaymentMethod == model.PaymentByOffline {
|
||||
return false, nil
|
||||
}
|
||||
var payments []model.Payment
|
||||
if err := s.db.WithContext(ctx).Where("order_type = ? AND order_id = ? AND status = ?", constants.PaymentOrderTypeSilenceExtension, order.ID, model.PaymentRecordStatusPending).
|
||||
Order("id DESC").Find(&payments).Error; err != nil {
|
||||
return false, errors.Wrap(errors.CodeDatabaseError, err, "查询延期支付单失败")
|
||||
}
|
||||
for index := range payments {
|
||||
payment := &payments[index]
|
||||
state, query, err := s.queryPayment(ctx, payment)
|
||||
if err != nil || state != agentrechargeApp.OnlinePaymentStatePaid {
|
||||
continue
|
||||
}
|
||||
paidAt := s.now()
|
||||
if query.PaidAt != nil {
|
||||
paidAt = *query.PaidAt
|
||||
}
|
||||
if err := s.ConfirmPayment(ctx, PaymentConfirmCommand{
|
||||
PaymentNo: payment.PaymentNo, ThirdPartyTradeNo: query.ThirdPartyTradeNo, Amount: query.Amount, PaidAt: paidAt,
|
||||
}); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
Reference in New Issue
Block a user