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 }