优化结构
This commit is contained in:
@@ -1,220 +0,0 @@
|
||||
package biz
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
PaymentStatusInitialized = "initialized"
|
||||
PaymentStatusPending = "pending"
|
||||
PaymentStatusPaid = "paid"
|
||||
PaymentStatusFailed = "failed"
|
||||
PaymentStatusClosed = "closed"
|
||||
PaymentStatusPartiallyRefunded = "partially_refunded"
|
||||
PaymentStatusRefunded = "refunded"
|
||||
|
||||
FulfillmentStatusPending = "pending"
|
||||
FulfillmentStatusProcessing = "processing"
|
||||
FulfillmentStatusSucceeded = "succeeded"
|
||||
FulfillmentStatusFailed = "failed"
|
||||
|
||||
RefundStatusNone = "none"
|
||||
RefundStatusProcessing = "processing"
|
||||
RefundStatusPending = "pending"
|
||||
RefundStatusPartial = "partial"
|
||||
RefundStatusSucceeded = "succeeded"
|
||||
RefundStatusFailed = "failed"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrPaymentOrderNotFound = errors.New("支付订单不存在")
|
||||
ErrPaymentOrderConflict = errors.New("支付订单参数冲突")
|
||||
ErrPaymentOrderBusy = errors.New("支付订单正在处理中")
|
||||
ErrPaymentOrderState = errors.New("支付订单状态不允许当前操作")
|
||||
ErrPaymentProviderConflict = errors.New("支付平台交易号冲突")
|
||||
)
|
||||
|
||||
// PaymentOrder is one payment attempt. Business modules own their domain
|
||||
// orders and link to this record through BusinessType and BusinessID.
|
||||
type PaymentOrder struct {
|
||||
ID uint64
|
||||
TradeNo string
|
||||
Provider string
|
||||
ProviderTradeNo string
|
||||
QueryID string
|
||||
BusinessType string
|
||||
BusinessID string
|
||||
Subject string
|
||||
PaymentMode string
|
||||
OriginalAmount int64
|
||||
Amount int64
|
||||
PaidAmount int64
|
||||
PayerPaidAmount int64
|
||||
CashPaidAmount int64
|
||||
PointPaidAmount int64
|
||||
DiscountAmount int64
|
||||
ProviderDiscountAmount int64
|
||||
MerchantDiscountAmount int64
|
||||
SettlementAmount int64
|
||||
Currency string
|
||||
PayerCurrency string
|
||||
AmountBreakdownKnown bool
|
||||
PaymentStatus string
|
||||
ProviderStatus string
|
||||
FulfillmentStatus string
|
||||
RefundStatus string
|
||||
RefundedAmount int64
|
||||
RefundRequestedAmount int64
|
||||
RefundNo string
|
||||
ConfirmationID string
|
||||
RequestFingerprint string
|
||||
CreatePayload json.RawMessage
|
||||
Extra json.RawMessage
|
||||
LastEventID string
|
||||
LastPayloadHash string
|
||||
LastError string
|
||||
FulfillmentToken string
|
||||
RefundToken string
|
||||
Version uint64
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
PaidAt *time.Time
|
||||
FulfilledAt *time.Time
|
||||
RefundedAt *time.Time
|
||||
FulfillmentLeaseUntil *time.Time
|
||||
RefundLeaseUntil *time.Time
|
||||
}
|
||||
|
||||
type PaymentProviderUpdate struct {
|
||||
Status string
|
||||
ProviderStatus string
|
||||
ProviderTradeNo string
|
||||
QueryID string
|
||||
Amount int64
|
||||
PayerPaidAmount int64
|
||||
CashPaidAmount int64
|
||||
PointPaidAmount int64
|
||||
DiscountAmount int64
|
||||
ProviderDiscountAmount int64
|
||||
MerchantDiscountAmount int64
|
||||
SettlementAmount int64
|
||||
Currency string
|
||||
PayerCurrency string
|
||||
AmountBreakdownKnown bool
|
||||
EventID string
|
||||
PayloadHash string
|
||||
CreatePayload json.RawMessage
|
||||
}
|
||||
|
||||
type PaymentOrderFilter struct {
|
||||
Provider string
|
||||
TradeNo string
|
||||
BusinessType string
|
||||
BusinessID string
|
||||
PaymentStatus string
|
||||
RefundStatus string
|
||||
}
|
||||
|
||||
type PaymentOrderRepo interface {
|
||||
CreatePaymentOrder(context.Context, *PaymentOrder) (order *PaymentOrder, created bool, err error)
|
||||
FindPaymentOrder(context.Context, string, string) (*PaymentOrder, error)
|
||||
ListPaymentOrders(context.Context, int, int, PaymentOrderFilter) ([]*PaymentOrder, int64, error)
|
||||
RecordPaymentCreate(context.Context, string, string, *PaymentProviderUpdate) (*PaymentOrder, error)
|
||||
ApplyPaymentResult(context.Context, string, string, *PaymentProviderUpdate) (*PaymentOrder, error)
|
||||
BeginPaymentFulfillment(context.Context, string, string, time.Duration) (order *PaymentOrder, token string, duplicate bool, err error)
|
||||
CompletePaymentFulfillment(context.Context, string, string, string, bool, string) (*PaymentOrder, error)
|
||||
BeginPaymentRefund(context.Context, string, string, int64, time.Duration) (order *PaymentOrder, token string, err error)
|
||||
CompletePaymentRefundRequest(context.Context, string, string, string, bool, string) (*PaymentOrder, error)
|
||||
ConfirmPaymentRefund(context.Context, string, string, string, int64, bool, string) (*PaymentOrder, error)
|
||||
}
|
||||
|
||||
// PaymentOrderSource is implemented by each business module. It returns the
|
||||
// canonical order facts; client-provided amount, currency and subject are not
|
||||
// trusted once the persistent payment-order flow is enabled.
|
||||
type PaymentOrderSource interface {
|
||||
Type() string
|
||||
PreparePayment(context.Context, string, string, string) (*PaymentIntent, error)
|
||||
}
|
||||
|
||||
type PaymentBusinessModule interface {
|
||||
PaymentOrderSource
|
||||
PaymentFulfillmentHandler
|
||||
PaymentRefundAuthorizer
|
||||
}
|
||||
|
||||
type PaymentRefundAuthorizer interface {
|
||||
AuthorizeRefund(context.Context, *PaymentOrder, int64) error
|
||||
}
|
||||
|
||||
type PaymentOrderSourceRegistry struct {
|
||||
mu sync.RWMutex
|
||||
sources map[string]PaymentOrderSource
|
||||
}
|
||||
|
||||
func NewPaymentOrderSourceRegistry() *PaymentOrderSourceRegistry {
|
||||
return &PaymentOrderSourceRegistry{sources: map[string]PaymentOrderSource{}}
|
||||
}
|
||||
|
||||
func (r *PaymentOrderSourceRegistry) Register(source PaymentOrderSource) error {
|
||||
if source == nil || strings.TrimSpace(source.Type()) == "" {
|
||||
return errors.New("支付业务订单来源无效")
|
||||
}
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
if _, exists := r.sources[source.Type()]; exists {
|
||||
return errors.New("支付业务订单来源已注册: " + source.Type())
|
||||
}
|
||||
r.sources[source.Type()] = source
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *PaymentOrderSourceRegistry) Source(kind string) PaymentOrderSource {
|
||||
if r == nil {
|
||||
return nil
|
||||
}
|
||||
r.mu.RLock()
|
||||
defer r.mu.RUnlock()
|
||||
return r.sources[kind]
|
||||
}
|
||||
|
||||
func (r *PaymentOrderSourceRegistry) Unregister(kind string) {
|
||||
if r == nil {
|
||||
return
|
||||
}
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
delete(r.sources, kind)
|
||||
}
|
||||
|
||||
func (o *PaymentOrder) Intent() *PaymentIntent {
|
||||
if o == nil {
|
||||
return nil
|
||||
}
|
||||
return &PaymentIntent{
|
||||
Provider: o.Provider,
|
||||
TradeNo: o.TradeNo,
|
||||
BusinessType: o.BusinessType,
|
||||
BusinessID: o.BusinessID,
|
||||
Subject: o.Subject,
|
||||
Amount: o.Amount,
|
||||
Currency: o.Currency,
|
||||
Extra: append(json.RawMessage(nil), o.Extra...),
|
||||
PaymentMode: defaultPaymentMode(o.Provider, o.PaymentMode),
|
||||
OriginalAmount: o.OriginalAmount,
|
||||
}
|
||||
}
|
||||
|
||||
func defaultPaymentMode(provider, mode string) string {
|
||||
if strings.TrimSpace(mode) != "" {
|
||||
return mode
|
||||
}
|
||||
if provider == PaymentInternal {
|
||||
return PaymentModeInternal
|
||||
}
|
||||
return PaymentModeExternal
|
||||
}
|
||||
Reference in New Issue
Block a user