优化结构
This commit is contained in:
@@ -4,7 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"kra/internal/biz/system"
|
||||
bizpayment "kra/internal/biz/payment"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -68,11 +68,11 @@ func (paymentOrderPO) TableName() string { return "pay_orders" }
|
||||
|
||||
type paymentOrderRepo struct{ data Provider }
|
||||
|
||||
func NewPaymentOrderRepo(data Provider) system.PaymentOrderRepo {
|
||||
func NewPaymentOrderRepo(data Provider) bizpayment.PaymentOrderRepo {
|
||||
return &paymentOrderRepo{data: data}
|
||||
}
|
||||
|
||||
func newPaymentOrderPO(order *system.PaymentOrder) (*paymentOrderPO, error) {
|
||||
func newPaymentOrderPO(order *bizpayment.PaymentOrder) (*paymentOrderPO, error) {
|
||||
if order == nil {
|
||||
return nil, errors.New("支付订单为空")
|
||||
}
|
||||
@@ -85,16 +85,16 @@ func newPaymentOrderPO(order *system.PaymentOrder) (*paymentOrderPO, error) {
|
||||
ID: order.ID, TradeNo: order.TradeNo, Provider: order.Provider,
|
||||
ProviderTradeNo: optionalString(order.ProviderTradeNo), QueryID: order.QueryID,
|
||||
BusinessType: order.BusinessType, BusinessID: order.BusinessID, Subject: order.Subject,
|
||||
PaymentMode: defaultString(order.PaymentMode, system.PaymentModeExternal), OriginalAmount: order.OriginalAmount,
|
||||
PaymentMode: defaultString(order.PaymentMode, bizpayment.PaymentModeExternal), OriginalAmount: order.OriginalAmount,
|
||||
Amount: order.Amount, PaidAmount: order.PaidAmount, PayerPaidAmount: order.PayerPaidAmount,
|
||||
CashPaidAmount: order.CashPaidAmount, PointPaidAmount: order.PointPaidAmount, DiscountAmount: order.DiscountAmount,
|
||||
ProviderDiscountAmount: order.ProviderDiscountAmount, MerchantDiscountAmount: order.MerchantDiscountAmount,
|
||||
SettlementAmount: order.SettlementAmount, Currency: order.Currency, PayerCurrency: order.PayerCurrency,
|
||||
AmountBreakdownKnown: order.AmountBreakdownKnown,
|
||||
PaymentStatus: defaultString(order.PaymentStatus, system.PaymentStatusInitialized),
|
||||
PaymentStatus: defaultString(order.PaymentStatus, bizpayment.PaymentStatusInitialized),
|
||||
ProviderStatus: order.ProviderStatus,
|
||||
FulfillmentStatus: defaultString(order.FulfillmentStatus, system.FulfillmentStatusPending),
|
||||
RefundStatus: defaultString(order.RefundStatus, system.RefundStatusNone),
|
||||
FulfillmentStatus: defaultString(order.FulfillmentStatus, bizpayment.FulfillmentStatusPending),
|
||||
RefundStatus: defaultString(order.RefundStatus, bizpayment.RefundStatusNone),
|
||||
RefundedAmount: order.RefundedAmount, RefundRequestedAmount: order.RefundRequestedAmount, RefundNo: order.RefundNo,
|
||||
ConfirmationID: order.ConfirmationID, RequestFingerprint: order.RequestFingerprint,
|
||||
CreatePayload: createPayload, Extra: extra, LastEventID: order.LastEventID,
|
||||
@@ -105,15 +105,15 @@ func newPaymentOrderPO(order *system.PaymentOrder) (*paymentOrderPO, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func toBizPaymentOrder(po *paymentOrderPO) *system.PaymentOrder {
|
||||
func toBizPaymentOrder(po *paymentOrderPO) *bizpayment.PaymentOrder {
|
||||
if po == nil {
|
||||
return nil
|
||||
}
|
||||
return &system.PaymentOrder{
|
||||
return &bizpayment.PaymentOrder{
|
||||
ID: po.ID, TradeNo: po.TradeNo, Provider: po.Provider,
|
||||
ProviderTradeNo: dereferenceString(po.ProviderTradeNo), QueryID: po.QueryID,
|
||||
BusinessType: po.BusinessType, BusinessID: po.BusinessID, Subject: po.Subject,
|
||||
PaymentMode: defaultString(po.PaymentMode, system.PaymentModeExternal), OriginalAmount: po.OriginalAmount,
|
||||
PaymentMode: defaultString(po.PaymentMode, bizpayment.PaymentModeExternal), OriginalAmount: po.OriginalAmount,
|
||||
Amount: po.Amount, PaidAmount: po.PaidAmount, PayerPaidAmount: po.PayerPaidAmount,
|
||||
CashPaidAmount: po.CashPaidAmount, PointPaidAmount: po.PointPaidAmount, DiscountAmount: po.DiscountAmount,
|
||||
ProviderDiscountAmount: po.ProviderDiscountAmount, MerchantDiscountAmount: po.MerchantDiscountAmount,
|
||||
@@ -131,7 +131,7 @@ func toBizPaymentOrder(po *paymentOrderPO) *system.PaymentOrder {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *paymentOrderRepo) CreatePaymentOrder(ctx context.Context, order *system.PaymentOrder) (*system.PaymentOrder, bool, error) {
|
||||
func (r *paymentOrderRepo) CreatePaymentOrder(ctx context.Context, order *bizpayment.PaymentOrder) (*bizpayment.PaymentOrder, bool, error) {
|
||||
po, err := newPaymentOrderPO(order)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
@@ -154,18 +154,18 @@ func (r *paymentOrderRepo) CreatePaymentOrder(ctx context.Context, order *system
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
func (r *paymentOrderRepo) FindPaymentOrder(ctx context.Context, provider, tradeNo string) (*system.PaymentOrder, error) {
|
||||
func (r *paymentOrderRepo) FindPaymentOrder(ctx context.Context, provider, tradeNo string) (*bizpayment.PaymentOrder, error) {
|
||||
var po paymentOrderPO
|
||||
if err := r.data.DB().WithContext(ctx).Where("provider = ? AND trade_no = ?", provider, tradeNo).First(&po).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, system.ErrPaymentOrderNotFound
|
||||
return nil, bizpayment.ErrPaymentOrderNotFound
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return toBizPaymentOrder(&po), nil
|
||||
}
|
||||
|
||||
func (r *paymentOrderRepo) ListPaymentOrders(ctx context.Context, page, pageSize int, filter system.PaymentOrderFilter) ([]*system.PaymentOrder, int64, error) {
|
||||
func (r *paymentOrderRepo) ListPaymentOrders(ctx context.Context, page, pageSize int, filter bizpayment.PaymentOrderFilter) ([]*bizpayment.PaymentOrder, int64, error) {
|
||||
db := r.data.DB().WithContext(ctx).Model(&paymentOrderPO{})
|
||||
if value := strings.TrimSpace(filter.Provider); value != "" {
|
||||
db = db.Where("provider = ?", value)
|
||||
@@ -193,14 +193,14 @@ func (r *paymentOrderRepo) ListPaymentOrders(ctx context.Context, page, pageSize
|
||||
if err := pagination.ApplyRequired(db.Order("id desc"), page, pageSize, 100).Find(&rows).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
items := make([]*system.PaymentOrder, 0, len(rows))
|
||||
items := make([]*bizpayment.PaymentOrder, 0, len(rows))
|
||||
for i := range rows {
|
||||
items = append(items, toBizPaymentOrder(&rows[i]))
|
||||
}
|
||||
return items, total, nil
|
||||
}
|
||||
|
||||
func (r *paymentOrderRepo) RecordPaymentCreate(ctx context.Context, provider, tradeNo string, update *system.PaymentProviderUpdate) (*system.PaymentOrder, error) {
|
||||
func (r *paymentOrderRepo) RecordPaymentCreate(ctx context.Context, provider, tradeNo string, update *bizpayment.PaymentProviderUpdate) (*bizpayment.PaymentOrder, error) {
|
||||
return r.withLockedOrder(ctx, provider, tradeNo, func(tx *gorm.DB, po *paymentOrderPO) error {
|
||||
if update == nil {
|
||||
return errors.New("支付下单结果为空")
|
||||
@@ -215,11 +215,11 @@ func (r *paymentOrderRepo) RecordPaymentCreate(ctx context.Context, provider, tr
|
||||
po.LastEventID = trimTo(update.EventID, 128)
|
||||
po.LastPayloadHash = trimTo(update.PayloadHash, 64)
|
||||
status := normalizeOrderPaymentStatus(update.Status)
|
||||
if status == system.PaymentStatusPaid {
|
||||
if status == bizpayment.PaymentStatusPaid {
|
||||
// Provider create responses are never sufficient proof of payment.
|
||||
status = system.PaymentStatusPending
|
||||
status = bizpayment.PaymentStatusPending
|
||||
}
|
||||
if po.PaymentStatus != system.PaymentStatusPaid && po.PaymentStatus != system.PaymentStatusPartiallyRefunded && po.PaymentStatus != system.PaymentStatusRefunded && status != "" {
|
||||
if po.PaymentStatus != bizpayment.PaymentStatusPaid && po.PaymentStatus != bizpayment.PaymentStatusPartiallyRefunded && po.PaymentStatus != bizpayment.PaymentStatusRefunded && status != "" {
|
||||
po.PaymentStatus = status
|
||||
}
|
||||
po.Version++
|
||||
@@ -227,7 +227,7 @@ func (r *paymentOrderRepo) RecordPaymentCreate(ctx context.Context, provider, tr
|
||||
})
|
||||
}
|
||||
|
||||
func (r *paymentOrderRepo) ApplyPaymentResult(ctx context.Context, provider, tradeNo string, update *system.PaymentProviderUpdate) (*system.PaymentOrder, error) {
|
||||
func (r *paymentOrderRepo) ApplyPaymentResult(ctx context.Context, provider, tradeNo string, update *bizpayment.PaymentProviderUpdate) (*bizpayment.PaymentOrder, error) {
|
||||
return r.withLockedOrder(ctx, provider, tradeNo, func(tx *gorm.DB, po *paymentOrderPO) error {
|
||||
if update == nil {
|
||||
return errors.New("支付查单结果为空")
|
||||
@@ -236,13 +236,13 @@ func (r *paymentOrderRepo) ApplyPaymentResult(ctx context.Context, provider, tra
|
||||
return err
|
||||
}
|
||||
if update.Amount > 0 && update.Amount != po.Amount {
|
||||
return system.ErrPaymentOrderConflict
|
||||
return bizpayment.ErrPaymentOrderConflict
|
||||
}
|
||||
if update.PayerPaidAmount < 0 || update.CashPaidAmount < 0 || update.PointPaidAmount < 0 || update.DiscountAmount < 0 || update.ProviderDiscountAmount < 0 || update.MerchantDiscountAmount < 0 || update.SettlementAmount < 0 {
|
||||
return system.ErrPaymentOrderConflict
|
||||
return bizpayment.ErrPaymentOrderConflict
|
||||
}
|
||||
if update.Currency != "" && !strings.EqualFold(update.Currency, po.Currency) {
|
||||
return system.ErrPaymentOrderConflict
|
||||
return bizpayment.ErrPaymentOrderConflict
|
||||
}
|
||||
po.ProviderStatus = trimTo(update.ProviderStatus, 64)
|
||||
po.LastEventID = trimTo(update.EventID, 128)
|
||||
@@ -259,22 +259,22 @@ func (r *paymentOrderRepo) ApplyPaymentResult(ctx context.Context, provider, tra
|
||||
po.AmountBreakdownKnown = true
|
||||
}
|
||||
switch normalizeOrderPaymentStatus(update.Status) {
|
||||
case system.PaymentStatusPaid:
|
||||
if po.PaymentStatus != system.PaymentStatusPartiallyRefunded && po.PaymentStatus != system.PaymentStatusRefunded {
|
||||
po.PaymentStatus = system.PaymentStatusPaid
|
||||
case bizpayment.PaymentStatusPaid:
|
||||
if po.PaymentStatus != bizpayment.PaymentStatusPartiallyRefunded && po.PaymentStatus != bizpayment.PaymentStatusRefunded {
|
||||
po.PaymentStatus = bizpayment.PaymentStatusPaid
|
||||
}
|
||||
po.PaidAmount = po.Amount
|
||||
if po.PaidAt == nil {
|
||||
now := time.Now().UTC()
|
||||
po.PaidAt = &now
|
||||
}
|
||||
case system.PaymentStatusPending:
|
||||
if po.PaymentStatus != system.PaymentStatusPaid && po.PaymentStatus != system.PaymentStatusPartiallyRefunded && po.PaymentStatus != system.PaymentStatusRefunded {
|
||||
po.PaymentStatus = system.PaymentStatusPending
|
||||
case bizpayment.PaymentStatusPending:
|
||||
if po.PaymentStatus != bizpayment.PaymentStatusPaid && po.PaymentStatus != bizpayment.PaymentStatusPartiallyRefunded && po.PaymentStatus != bizpayment.PaymentStatusRefunded {
|
||||
po.PaymentStatus = bizpayment.PaymentStatusPending
|
||||
}
|
||||
case system.PaymentStatusFailed:
|
||||
if po.PaymentStatus != system.PaymentStatusPaid && po.PaymentStatus != system.PaymentStatusPartiallyRefunded && po.PaymentStatus != system.PaymentStatusRefunded {
|
||||
po.PaymentStatus = system.PaymentStatusFailed
|
||||
case bizpayment.PaymentStatusFailed:
|
||||
if po.PaymentStatus != bizpayment.PaymentStatusPaid && po.PaymentStatus != bizpayment.PaymentStatusPartiallyRefunded && po.PaymentStatus != bizpayment.PaymentStatusRefunded {
|
||||
po.PaymentStatus = bizpayment.PaymentStatusFailed
|
||||
}
|
||||
}
|
||||
po.Version++
|
||||
@@ -282,27 +282,27 @@ func (r *paymentOrderRepo) ApplyPaymentResult(ctx context.Context, provider, tra
|
||||
})
|
||||
}
|
||||
|
||||
func (r *paymentOrderRepo) BeginPaymentFulfillment(ctx context.Context, provider, tradeNo string, lease time.Duration) (*system.PaymentOrder, string, bool, error) {
|
||||
func (r *paymentOrderRepo) BeginPaymentFulfillment(ctx context.Context, provider, tradeNo string, lease time.Duration) (*bizpayment.PaymentOrder, string, bool, error) {
|
||||
var token string
|
||||
var duplicate bool
|
||||
order, err := r.withLockedOrder(ctx, provider, tradeNo, func(tx *gorm.DB, po *paymentOrderPO) error {
|
||||
if po.FulfillmentStatus == system.FulfillmentStatusSucceeded {
|
||||
if po.FulfillmentStatus == bizpayment.FulfillmentStatusSucceeded {
|
||||
duplicate = true
|
||||
return nil
|
||||
}
|
||||
if po.PaymentStatus != system.PaymentStatusPaid {
|
||||
return system.ErrPaymentOrderState
|
||||
if po.PaymentStatus != bizpayment.PaymentStatusPaid {
|
||||
return bizpayment.ErrPaymentOrderState
|
||||
}
|
||||
now := time.Now().UTC()
|
||||
if po.FulfillmentStatus == system.FulfillmentStatusProcessing && po.FulfillmentLeaseUntil != nil && po.FulfillmentLeaseUntil.After(now) {
|
||||
return system.ErrPaymentOrderBusy
|
||||
if po.FulfillmentStatus == bizpayment.FulfillmentStatusProcessing && po.FulfillmentLeaseUntil != nil && po.FulfillmentLeaseUntil.After(now) {
|
||||
return bizpayment.ErrPaymentOrderBusy
|
||||
}
|
||||
if lease <= 0 {
|
||||
lease = 10 * time.Minute
|
||||
}
|
||||
token = uuid.NewString()
|
||||
until := now.Add(lease)
|
||||
po.FulfillmentStatus = system.FulfillmentStatusProcessing
|
||||
po.FulfillmentStatus = bizpayment.FulfillmentStatusProcessing
|
||||
po.FulfillmentToken = token
|
||||
po.FulfillmentLeaseUntil = &until
|
||||
po.LastError = ""
|
||||
@@ -312,56 +312,56 @@ func (r *paymentOrderRepo) BeginPaymentFulfillment(ctx context.Context, provider
|
||||
return order, token, duplicate, err
|
||||
}
|
||||
|
||||
func (r *paymentOrderRepo) CompletePaymentFulfillment(ctx context.Context, provider, tradeNo, token string, success bool, message string) (*system.PaymentOrder, error) {
|
||||
func (r *paymentOrderRepo) CompletePaymentFulfillment(ctx context.Context, provider, tradeNo, token string, success bool, message string) (*bizpayment.PaymentOrder, error) {
|
||||
return r.withLockedOrder(ctx, provider, tradeNo, func(tx *gorm.DB, po *paymentOrderPO) error {
|
||||
if po.FulfillmentStatus != system.FulfillmentStatusProcessing || po.FulfillmentToken != token {
|
||||
return system.ErrPaymentOrderBusy
|
||||
if po.FulfillmentStatus != bizpayment.FulfillmentStatusProcessing || po.FulfillmentToken != token {
|
||||
return bizpayment.ErrPaymentOrderBusy
|
||||
}
|
||||
po.FulfillmentToken = ""
|
||||
po.FulfillmentLeaseUntil = nil
|
||||
po.LastError = trimTo(message, 512)
|
||||
if success {
|
||||
po.FulfillmentStatus = system.FulfillmentStatusSucceeded
|
||||
po.FulfillmentStatus = bizpayment.FulfillmentStatusSucceeded
|
||||
now := time.Now().UTC()
|
||||
po.FulfilledAt = &now
|
||||
} else {
|
||||
po.FulfillmentStatus = system.FulfillmentStatusFailed
|
||||
po.FulfillmentStatus = bizpayment.FulfillmentStatusFailed
|
||||
}
|
||||
po.Version++
|
||||
return tx.Save(po).Error
|
||||
})
|
||||
}
|
||||
|
||||
func (r *paymentOrderRepo) BeginPaymentRefund(ctx context.Context, provider, tradeNo string, amount int64, lease time.Duration) (*system.PaymentOrder, string, error) {
|
||||
func (r *paymentOrderRepo) BeginPaymentRefund(ctx context.Context, provider, tradeNo string, amount int64, lease time.Duration) (*bizpayment.PaymentOrder, string, error) {
|
||||
var token string
|
||||
order, err := r.withLockedOrder(ctx, provider, tradeNo, func(tx *gorm.DB, po *paymentOrderPO) error {
|
||||
if po.PaymentStatus != system.PaymentStatusPaid && po.PaymentStatus != system.PaymentStatusPartiallyRefunded {
|
||||
return system.ErrPaymentOrderState
|
||||
if po.PaymentStatus != bizpayment.PaymentStatusPaid && po.PaymentStatus != bizpayment.PaymentStatusPartiallyRefunded {
|
||||
return bizpayment.ErrPaymentOrderState
|
||||
}
|
||||
if amount <= 0 {
|
||||
return system.ErrPaymentOrderConflict
|
||||
return bizpayment.ErrPaymentOrderConflict
|
||||
}
|
||||
now := time.Now().UTC()
|
||||
if po.RefundStatus == system.RefundStatusProcessing && po.RefundLeaseUntil != nil && po.RefundLeaseUntil.After(now) {
|
||||
return system.ErrPaymentOrderBusy
|
||||
if po.RefundStatus == bizpayment.RefundStatusProcessing && po.RefundLeaseUntil != nil && po.RefundLeaseUntil.After(now) {
|
||||
return bizpayment.ErrPaymentOrderBusy
|
||||
}
|
||||
if po.RefundStatus == system.RefundStatusProcessing && po.RefundRequestedAmount != amount {
|
||||
return system.ErrPaymentOrderConflict
|
||||
if po.RefundStatus == bizpayment.RefundStatusProcessing && po.RefundRequestedAmount != amount {
|
||||
return bizpayment.ErrPaymentOrderConflict
|
||||
}
|
||||
if po.RefundStatus == system.RefundStatusPending {
|
||||
return system.ErrPaymentOrderBusy
|
||||
if po.RefundStatus == bizpayment.RefundStatusPending {
|
||||
return bizpayment.ErrPaymentOrderBusy
|
||||
}
|
||||
// An expired processing lease means the provider outcome is unknown.
|
||||
// Retry the same refund amount with the same durable refund number. A
|
||||
// different amount must never reuse that operation identity.
|
||||
reserved := int64(0)
|
||||
if po.RefundStatus == system.RefundStatusProcessing && po.RefundLeaseUntil != nil && !po.RefundLeaseUntil.After(now) {
|
||||
if po.RefundStatus == bizpayment.RefundStatusProcessing && po.RefundLeaseUntil != nil && !po.RefundLeaseUntil.After(now) {
|
||||
reserved = 0
|
||||
} else {
|
||||
reserved = po.RefundRequestedAmount
|
||||
}
|
||||
if amount > po.Amount-po.RefundedAmount-reserved {
|
||||
return system.ErrPaymentOrderConflict
|
||||
return bizpayment.ErrPaymentOrderConflict
|
||||
}
|
||||
if lease <= 0 {
|
||||
lease = 10 * time.Minute
|
||||
@@ -371,7 +371,7 @@ func (r *paymentOrderRepo) BeginPaymentRefund(ctx context.Context, provider, tra
|
||||
po.RefundNo = uuid.NewString()
|
||||
}
|
||||
until := now.Add(lease)
|
||||
po.RefundStatus = system.RefundStatusProcessing
|
||||
po.RefundStatus = bizpayment.RefundStatusProcessing
|
||||
po.RefundRequestedAmount = amount
|
||||
po.RefundToken = token
|
||||
po.RefundLeaseUntil = &until
|
||||
@@ -382,18 +382,18 @@ func (r *paymentOrderRepo) BeginPaymentRefund(ctx context.Context, provider, tra
|
||||
return order, token, err
|
||||
}
|
||||
|
||||
func (r *paymentOrderRepo) CompletePaymentRefundRequest(ctx context.Context, provider, tradeNo, token string, accepted bool, message string) (*system.PaymentOrder, error) {
|
||||
func (r *paymentOrderRepo) CompletePaymentRefundRequest(ctx context.Context, provider, tradeNo, token string, accepted bool, message string) (*bizpayment.PaymentOrder, error) {
|
||||
return r.withLockedOrder(ctx, provider, tradeNo, func(tx *gorm.DB, po *paymentOrderPO) error {
|
||||
if po.RefundStatus != system.RefundStatusProcessing || po.RefundToken != token {
|
||||
return system.ErrPaymentOrderBusy
|
||||
if po.RefundStatus != bizpayment.RefundStatusProcessing || po.RefundToken != token {
|
||||
return bizpayment.ErrPaymentOrderBusy
|
||||
}
|
||||
po.RefundToken = ""
|
||||
po.RefundLeaseUntil = nil
|
||||
po.LastError = trimTo(message, 512)
|
||||
if accepted {
|
||||
po.RefundStatus = system.RefundStatusPending
|
||||
po.RefundStatus = bizpayment.RefundStatusPending
|
||||
} else {
|
||||
po.RefundStatus = system.RefundStatusFailed
|
||||
po.RefundStatus = bizpayment.RefundStatusFailed
|
||||
po.RefundRequestedAmount = 0
|
||||
po.RefundNo = ""
|
||||
}
|
||||
@@ -402,26 +402,26 @@ func (r *paymentOrderRepo) CompletePaymentRefundRequest(ctx context.Context, pro
|
||||
})
|
||||
}
|
||||
|
||||
func (r *paymentOrderRepo) ConfirmPaymentRefund(ctx context.Context, provider, tradeNo, refundNo string, amount int64, success bool, message string) (*system.PaymentOrder, error) {
|
||||
func (r *paymentOrderRepo) ConfirmPaymentRefund(ctx context.Context, provider, tradeNo, refundNo string, amount int64, success bool, message string) (*bizpayment.PaymentOrder, error) {
|
||||
return r.withLockedOrder(ctx, provider, tradeNo, func(tx *gorm.DB, po *paymentOrderPO) error {
|
||||
if po.RefundStatus != system.RefundStatusPending || po.RefundNo == "" || po.RefundNo != refundNo || po.RefundRequestedAmount != amount {
|
||||
return system.ErrPaymentOrderState
|
||||
if po.RefundStatus != bizpayment.RefundStatusPending || po.RefundNo == "" || po.RefundNo != refundNo || po.RefundRequestedAmount != amount {
|
||||
return bizpayment.ErrPaymentOrderState
|
||||
}
|
||||
po.LastError = trimTo(message, 512)
|
||||
po.RefundRequestedAmount = 0
|
||||
if !success {
|
||||
po.RefundStatus = system.RefundStatusFailed
|
||||
po.RefundStatus = bizpayment.RefundStatusFailed
|
||||
po.RefundNo = ""
|
||||
po.Version++
|
||||
return tx.Save(po).Error
|
||||
}
|
||||
po.RefundedAmount += amount
|
||||
if po.RefundedAmount >= po.Amount {
|
||||
po.PaymentStatus = system.PaymentStatusRefunded
|
||||
po.RefundStatus = system.RefundStatusSucceeded
|
||||
po.PaymentStatus = bizpayment.PaymentStatusRefunded
|
||||
po.RefundStatus = bizpayment.RefundStatusSucceeded
|
||||
} else {
|
||||
po.PaymentStatus = system.PaymentStatusPartiallyRefunded
|
||||
po.RefundStatus = system.RefundStatusPartial
|
||||
po.PaymentStatus = bizpayment.PaymentStatusPartiallyRefunded
|
||||
po.RefundStatus = bizpayment.RefundStatusPartial
|
||||
}
|
||||
po.RefundNo = ""
|
||||
now := time.Now().UTC()
|
||||
@@ -431,13 +431,13 @@ func (r *paymentOrderRepo) ConfirmPaymentRefund(ctx context.Context, provider, t
|
||||
})
|
||||
}
|
||||
|
||||
func (r *paymentOrderRepo) withLockedOrder(ctx context.Context, provider, tradeNo string, fn func(*gorm.DB, *paymentOrderPO) error) (*system.PaymentOrder, error) {
|
||||
var result *system.PaymentOrder
|
||||
func (r *paymentOrderRepo) withLockedOrder(ctx context.Context, provider, tradeNo string, fn func(*gorm.DB, *paymentOrderPO) error) (*bizpayment.PaymentOrder, error) {
|
||||
var result *bizpayment.PaymentOrder
|
||||
err := r.data.DB().WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
var po paymentOrderPO
|
||||
if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).Where("provider = ? AND trade_no = ?", provider, tradeNo).First(&po).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return system.ErrPaymentOrderNotFound
|
||||
return bizpayment.ErrPaymentOrderNotFound
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -450,16 +450,16 @@ func (r *paymentOrderRepo) withLockedOrder(ctx context.Context, provider, tradeN
|
||||
return result, err
|
||||
}
|
||||
|
||||
func applyProviderIdentity(tx *gorm.DB, po *paymentOrderPO, update *system.PaymentProviderUpdate) error {
|
||||
func applyProviderIdentity(tx *gorm.DB, po *paymentOrderPO, update *bizpayment.PaymentProviderUpdate) error {
|
||||
if update.ProviderTradeNo != "" {
|
||||
if po.ProviderTradeNo != nil && *po.ProviderTradeNo != update.ProviderTradeNo {
|
||||
return system.ErrPaymentProviderConflict
|
||||
return bizpayment.ErrPaymentProviderConflict
|
||||
}
|
||||
var other paymentOrderPO
|
||||
// This check is repeated under the order transaction so a platform
|
||||
// transaction cannot be attached to a different merchant order.
|
||||
if err := tx.Where("provider = ? AND provider_trade_no = ? AND id <> ?", po.Provider, update.ProviderTradeNo, po.ID).First(&other).Error; err == nil {
|
||||
return system.ErrPaymentProviderConflict
|
||||
return bizpayment.ErrPaymentProviderConflict
|
||||
} else if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return err
|
||||
}
|
||||
@@ -468,7 +468,7 @@ func applyProviderIdentity(tx *gorm.DB, po *paymentOrderPO, update *system.Payme
|
||||
}
|
||||
if update.QueryID != "" {
|
||||
if po.QueryID != "" && po.QueryID != update.QueryID {
|
||||
return system.ErrPaymentProviderConflict
|
||||
return bizpayment.ErrPaymentProviderConflict
|
||||
}
|
||||
po.QueryID = update.QueryID
|
||||
}
|
||||
@@ -478,11 +478,11 @@ func applyProviderIdentity(tx *gorm.DB, po *paymentOrderPO, update *system.Payme
|
||||
func normalizeOrderPaymentStatus(value string) string {
|
||||
switch strings.ToLower(strings.TrimSpace(value)) {
|
||||
case "success", "paid", "fulfilled":
|
||||
return system.PaymentStatusPaid
|
||||
return bizpayment.PaymentStatusPaid
|
||||
case "pending", "created", "client_pending", "processing":
|
||||
return system.PaymentStatusPending
|
||||
return bizpayment.PaymentStatusPending
|
||||
case "failed", "closed", "cancelled", "canceled":
|
||||
return system.PaymentStatusFailed
|
||||
return bizpayment.PaymentStatusFailed
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user