66 lines
1.5 KiB
Go
66 lines
1.5 KiB
Go
package channel
|
|
|
|
import (
|
|
"errors"
|
|
"sync"
|
|
|
|
"pay-bridge/internal/model"
|
|
)
|
|
|
|
var (
|
|
ErrChannelNotFound = errors.New("channel not found")
|
|
ErrNotSupported = errors.New("operation not supported by this channel")
|
|
)
|
|
|
|
var globalRegistry = &Registry{}
|
|
|
|
// Registry 渠道注册表
|
|
type Registry struct {
|
|
mu sync.RWMutex
|
|
factories map[string]ChannelFactory
|
|
}
|
|
|
|
// Register 注册渠道工厂(供各渠道包在 init() 中调用)
|
|
func Register(channelCode string, factory ChannelFactory) {
|
|
globalRegistry.Register(channelCode, factory)
|
|
}
|
|
|
|
func (r *Registry) Register(channelCode string, factory ChannelFactory) {
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
if r.factories == nil {
|
|
r.factories = make(map[string]ChannelFactory)
|
|
}
|
|
r.factories[channelCode] = factory
|
|
}
|
|
|
|
// Get 根据渠道码、商户配置和网关地址获取渠道实例
|
|
func Get(channelCode string, config *model.ChannelConfig, urls URLs) (PaymentChannel, error) {
|
|
return globalRegistry.Get(channelCode, config, urls)
|
|
}
|
|
|
|
func (r *Registry) Get(channelCode string, config *model.ChannelConfig, urls URLs) (PaymentChannel, error) {
|
|
r.mu.RLock()
|
|
factory, ok := r.factories[channelCode]
|
|
r.mu.RUnlock()
|
|
if !ok {
|
|
return nil, ErrChannelNotFound
|
|
}
|
|
return factory(config, urls), nil
|
|
}
|
|
|
|
// List 列出已注册的渠道码
|
|
func List() []string {
|
|
return globalRegistry.List()
|
|
}
|
|
|
|
func (r *Registry) List() []string {
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
codes := make([]string, 0, len(r.factories))
|
|
for code := range r.factories {
|
|
codes = append(codes, code)
|
|
}
|
|
return codes
|
|
}
|