65 lines
1019 B
Go

package paymentsvc
import (
"context"
"errors"
"sync"
)
var (
ErrPaymentInProgress = errors.New("payment is already in progress")
ErrProviderNotConfigured = errors.New("payment provider is not configured")
)
type StatusUpdate struct {
Code string `json:"code"`
}
type StatusHandler func(StatusUpdate)
type Provider interface {
Sale(
ctx context.Context,
req SaleRequest,
onStatus StatusHandler,
) (*Result, error)
}
type Service struct {
provider Provider
mu sync.Mutex
busy bool
}
func NewService(provider Provider) *Service {
return &Service{
provider: provider,
}
}
func (s *Service) Sale(
ctx context.Context,
req SaleRequest,
onStatus StatusHandler,
) (*Result, error) {
if s == nil || s.provider == nil {
return nil, ErrProviderNotConfigured
}
s.mu.Lock()
if s.busy {
s.mu.Unlock()
return nil, ErrPaymentInProgress
}
s.busy = true
s.mu.Unlock()
defer func() {
s.mu.Lock()
s.busy = false
s.mu.Unlock()
}()
return s.provider.Sale(ctx, req, onStatus)
}