billing

package
v0.9.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 28, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package billing provides a dual-provider (Paddle/Stripe) billing system with webhook processing, subscription management, and credit granting.

Consuming applications implement the CreditGranter interface to bridge billing webhook grants to their own credit/ledger system.

Index

Constants

View Source
const (
	ProviderCodePaddle  = "paddle"
	ProviderCodeStripe  = "stripe"
	CheckoutModeOverlay = "overlay"

	PlanCodePro  = "pro"
	PlanCodePlus = "plus"

	PackCodeTopUp     = "top_up"
	PackCodeBulkTopUp = "bulk_top_up"

	PurchaseKindSubscription = "subscription"
	PurchaseKindTopUpPack    = "top_up_pack"
)

Variables

View Source
var (
	ErrPaddleAPIKeyEmpty             = errors.New("billing.paddle.api.key.empty")
	ErrPaddleAPIEnvironmentInvalid   = errors.New("billing.paddle.api.environment.invalid")
	ErrPaddleAPIBaseURLInvalid       = errors.New("billing.paddle.api.base_url.invalid")
	ErrPaddleAPIPaginationInvalid    = errors.New("billing.paddle.api.pagination.invalid")
	ErrPaddleAPIRequestFailed        = errors.New("billing.paddle.api.request.failed")
	ErrPaddleAPITransient            = errors.New("billing.paddle.api.transient")
	ErrPaddleAPIRateLimited          = errors.New("billing.paddle.api.rate_limited")
	ErrPaddleAPICustomerNotFound     = errors.New("billing.paddle.api.customer.not_found")
	ErrPaddleAPITransactionNotFound  = errors.New("billing.paddle.api.transaction.not_found")
	ErrPaddleAPISubscriptionNotFound = errors.New("billing.paddle.api.subscription.not_found")
	ErrPaddleAPIPortalURLNotFound    = errors.New("billing.paddle.api.portal_url.not_found")
	ErrPaddleAPIDefaultCheckoutURL   = errors.New("billing.paddle.api.default_checkout_url.not_set")
	ErrPaddleAPIPriceNotFound        = errors.New("billing.paddle.api.price.not_found")
)
View Source
var (
	ErrPaddleProviderVerifierUnavailable   = errors.New("billing.paddle.provider.verifier.unavailable")
	ErrPaddleProviderAPIKeyEmpty           = errors.New("billing.paddle.provider.api_key.empty")
	ErrPaddleProviderClientTokenEmpty      = errors.New("billing.paddle.provider.client_token.empty")
	ErrPaddleProviderPriceIDEmpty          = errors.New("billing.paddle.provider.price_id.empty")
	ErrPaddleProviderPriceRecurringInvalid = errors.New("billing.paddle.provider.price.recurring.invalid")
	ErrPaddleProviderPriceOneOffInvalid    = errors.New("billing.paddle.provider.price.one_off.invalid")
	ErrPaddleProviderPriceAmountMismatch   = errors.New("billing.paddle.provider.price.amount.mismatch")
	ErrPaddleProviderPlanCreditsMissing    = errors.New("billing.paddle.provider.plan_credits.missing")
	ErrPaddleProviderPlanCreditsInvalid    = errors.New("billing.paddle.provider.plan_credits.invalid")
	ErrPaddleProviderPlanPriceMissing      = errors.New("billing.paddle.provider.plan_price.missing")
	ErrPaddleProviderPlanPriceInvalid      = errors.New("billing.paddle.provider.plan_price.invalid")
	ErrPaddleProviderPackCreditsMissing    = errors.New("billing.paddle.provider.pack_credits.missing")
	ErrPaddleProviderPackCreditsInvalid    = errors.New("billing.paddle.provider.pack_credits.invalid")
	ErrPaddleProviderPackPriceMissing      = errors.New("billing.paddle.provider.pack_price.missing")
	ErrPaddleProviderPackPriceInvalid      = errors.New("billing.paddle.provider.pack_price.invalid")
	ErrPaddleProviderPackPriceIDMissing    = errors.New("billing.paddle.provider.pack_price_id.missing")
	ErrPaddleWebhookPayloadInvalid         = errors.New("billing.paddle.webhook.payload.invalid")
	ErrPaddleProviderClientUnavailable     = errors.New("billing.paddle.provider.client.unavailable")
)
View Source
var (
	ErrPaddleWebhookVerifierUnavailable = errors.New("billing.paddle.webhook.verifier.unavailable")
	ErrPaddleWebhookSecretEmpty         = errors.New("billing.paddle.webhook.secret.empty")
	ErrPaddleWebhookMaxAgeInvalid       = errors.New("billing.paddle.webhook.max_age.invalid")
	ErrPaddleWebhookHeaderInvalid       = errors.New("billing.paddle.webhook.signature_header.invalid")
	ErrPaddleWebhookTimestampInvalid    = errors.New("billing.paddle.webhook.timestamp.invalid")
	ErrPaddleWebhookTimestampExpired    = errors.New("billing.paddle.webhook.timestamp.expired")
	ErrPaddleWebhookSignatureInvalid    = errors.New("billing.paddle.webhook.signature.invalid")
)
View Source
var (
	ErrBillingProviderUnavailable  = errors.New("billing.provider.unavailable")
	ErrBillingUserEmailInvalid     = errors.New("billing.user_email.invalid")
	ErrBillingPlanUnsupported      = errors.New("billing.plan.unsupported")
	ErrBillingSubscriptionActive   = errors.New("billing.subscription.active")
	ErrBillingSubscriptionUpgrade  = errors.New("billing.subscription.upgrade_required")
	ErrBillingSubscriptionRequired = errors.New("billing.subscription.required")
	ErrBillingTopUpPackUnknown     = errors.New("billing.top_up_pack.unknown")
	ErrBillingUserSyncFailed       = errors.New("billing.user_sync.failed")
)
View Source
var (
	ErrBillingCheckoutReconciliationUnavailable = errors.New("billing.checkout.reconcile.unavailable")
	ErrBillingCheckoutReconciliationUnsupported = errors.New("billing.checkout.reconcile.provider.unsupported")
	ErrBillingCheckoutTransactionInvalid        = errors.New("billing.checkout.transaction.invalid")
	ErrBillingCheckoutTransactionPending        = errors.New("billing.checkout.transaction.pending")
	ErrBillingCheckoutOwnershipMismatch         = errors.New("billing.checkout.ownership.mismatch")
)
View Source
var (
	ErrStripeAPIKeyEmpty                = errors.New("billing.stripe.api.key.empty")
	ErrStripeAPIRequestFailed           = errors.New("billing.stripe.api.request.failed")
	ErrStripeAPITransient               = errors.New("billing.stripe.api.transient")
	ErrStripeAPIRateLimited             = errors.New("billing.stripe.api.rate_limited")
	ErrStripeAPICustomerNotFound        = errors.New("billing.stripe.api.customer.not_found")
	ErrStripeAPICheckoutSessionNotFound = errors.New("billing.stripe.api.checkout_session.not_found")
	ErrStripeAPIPortalURLNotFound       = errors.New("billing.stripe.api.portal_url.not_found")
	ErrStripeAPIPriceNotFound           = errors.New("billing.stripe.api.price.not_found")
)
View Source
var (
	ErrStripeProviderVerifierUnavailable   = errors.New("billing.stripe.provider.verifier.unavailable")
	ErrStripeProviderAPIKeyEmpty           = errors.New("billing.stripe.provider.api_key.empty")
	ErrStripeProviderClientTokenEmpty      = errors.New("billing.stripe.provider.client_token.empty")
	ErrStripeProviderURLInvalid            = errors.New("billing.stripe.provider.url.invalid")
	ErrStripeProviderPriceIDEmpty          = errors.New("billing.stripe.provider.price_id.empty")
	ErrStripeProviderPlanCreditsMissing    = errors.New("billing.stripe.provider.plan_credits.missing")
	ErrStripeProviderPlanCreditsInvalid    = errors.New("billing.stripe.provider.plan_credits.invalid")
	ErrStripeProviderPlanPriceMissing      = errors.New("billing.stripe.provider.plan_price.missing")
	ErrStripeProviderPlanPriceInvalid      = errors.New("billing.stripe.provider.plan_price.invalid")
	ErrStripeProviderPackCreditsMissing    = errors.New("billing.stripe.provider.pack_credits.missing")
	ErrStripeProviderPackCreditsInvalid    = errors.New("billing.stripe.provider.pack_credits.invalid")
	ErrStripeProviderPackPriceMissing      = errors.New("billing.stripe.provider.pack_price.missing")
	ErrStripeProviderPackPriceInvalid      = errors.New("billing.stripe.provider.pack_price.invalid")
	ErrStripeProviderPackPriceIDMissing    = errors.New("billing.stripe.provider.pack_price_id.missing")
	ErrStripeProviderPriceRecurringInvalid = errors.New("billing.stripe.provider.price.recurring.invalid")
	ErrStripeProviderPriceOneOffInvalid    = errors.New("billing.stripe.provider.price.one_off.invalid")
	ErrStripeProviderPriceAmountMismatch   = errors.New("billing.stripe.provider.price.amount.mismatch")
	ErrStripeWebhookPayloadInvalid         = errors.New("billing.stripe.webhook.payload.invalid")
	ErrStripeProviderClientUnavailable     = errors.New("billing.stripe.provider.client.unavailable")
)
View Source
var (
	ErrStripeWebhookVerifierUnavailable = errors.New("billing.stripe.webhook.verifier.unavailable")
	ErrStripeWebhookSecretEmpty         = errors.New("billing.stripe.webhook.secret.empty")
	ErrStripeWebhookMaxAgeInvalid       = errors.New("billing.stripe.webhook.max_age.invalid")
	ErrStripeWebhookHeaderInvalid       = errors.New("billing.stripe.webhook.signature_header.invalid")
	ErrStripeWebhookTimestampInvalid    = errors.New("billing.stripe.webhook.timestamp.invalid")
	ErrStripeWebhookTimestampExpired    = errors.New("billing.stripe.webhook.timestamp.expired")
	ErrStripeWebhookSignatureInvalid    = errors.New("billing.stripe.webhook.signature.invalid")
)
View Source
var (
	ErrBillingSubscriptionStateRepositoryUnavailable = errors.New("billing.subscription_state.repository.unavailable")
	ErrBillingSubscriptionStateProviderInvalid       = errors.New("billing.subscription_state.provider.invalid")
	ErrBillingSubscriptionStateUserEmailInvalid      = errors.New("billing.subscription_state.user_email.invalid")
	ErrBillingSubscriptionStateSubscriptionIDInvalid = errors.New("billing.subscription_state.subscription_id.invalid")
	ErrBillingSubscriptionStateStatusInvalid         = errors.New("billing.subscription_state.status.invalid")
)
View Source
var (
	ErrWebhookSubscriptionStateRepositoryUnavailable = errors.New("billing.webhook.subscription_state.repository.unavailable")
	ErrWebhookSubscriptionStateProviderUnsupported   = errors.New("billing.webhook.subscription_state.provider.unsupported")
)
View Source
var (
	ErrWebhookGrantResolverUnavailable         = errors.New("billing.webhook.grant_resolver.unavailable")
	ErrWebhookGrantResolverProviderUnavailable = errors.New("billing.webhook.grant_resolver.provider.unavailable")
	ErrWebhookGrantResolverProviderUnsupported = errors.New("billing.webhook.grant_resolver.provider.unsupported")
	ErrWebhookCreditsServiceUnavailable        = errors.New("billing.webhook.credits_service.unavailable")
	ErrWebhookGrantPayloadInvalid              = errors.New("billing.webhook.payload.invalid")
	ErrWebhookGrantMetadataInvalid             = errors.New("billing.webhook.metadata.invalid")
	ErrWebhookGrantPlanUnknown                 = errors.New("billing.webhook.plan.unknown")
	ErrWebhookGrantPackUnknown                 = errors.New("billing.webhook.pack.unknown")
)
View Source
var ErrDuplicateGrant = errors.New("billing: duplicate grant")

ErrDuplicateGrant signals an idempotent duplicate — not a failure.

View Source
var ErrHTTPRetryAttemptsExhausted = errors.New("billing.http.retry.attempts.exhausted")

Functions

func Migrate

func Migrate(ctx context.Context, database *gorm.DB) error

func NormalizePackCode

func NormalizePackCode(rawPackCode string) string

func NormalizePurchaseKind

func NormalizePurchaseKind(rawPurchaseKind string) string

func PackLabelForCode

func PackLabelForCode(rawPackCode string) string

Types

type CatalogValidationProvider

type CatalogValidationProvider interface {
	ValidateCatalog(context.Context) error
}

type CheckoutEventStatus

type CheckoutEventStatus string
const (
	CheckoutEventStatusUnknown   CheckoutEventStatus = "unknown"
	CheckoutEventStatusPending   CheckoutEventStatus = "pending"
	CheckoutEventStatusSucceeded CheckoutEventStatus = "succeeded"
	CheckoutEventStatusFailed    CheckoutEventStatus = "failed"
	CheckoutEventStatusExpired   CheckoutEventStatus = "expired"
)

type CheckoutEventStatusProvider

type CheckoutEventStatusProvider interface {
	ResolveCheckoutEventStatus(string) CheckoutEventStatus
}

type CheckoutReconcileProvider

type CheckoutReconcileProvider interface {
	BuildCheckoutReconcileEvent(context.Context, string) (WebhookEvent, string, error)
}

type CheckoutSession

type CheckoutSession struct {
	ProviderCode  string
	TransactionID string
	CheckoutMode  string
}

type CommerceProvider

type CommerceProvider interface {
	Code() string
	SubscriptionPlans() []SubscriptionPlan
	TopUpPacks() []TopUpPack
	PublicConfig() PublicConfig
	BuildUserSyncEvents(context.Context, string) ([]WebhookEvent, error)
	CreateSubscriptionCheckout(context.Context, string, string) (CheckoutSession, error)
	CreateTopUpCheckout(context.Context, string, string) (CheckoutSession, error)
	CreateCustomerPortalSession(context.Context, string) (PortalSession, error)
}

type CreditGrantInput

type CreditGrantInput struct {
	UserEmail      string
	Credits        int64
	IdempotencyKey string
	Reason         string
	Reference      string
	Metadata       map[string]string
}

CreditGrantInput contains the data needed to grant credits from a billing event.

type CreditGranter

type CreditGranter interface {
	GrantBillingCredits(ctx context.Context, input CreditGrantInput) error
}

CreditGranter is the interface that consuming applications implement to bridge billing webhook grants to their credit/ledger system.

type HTTPErrorDescriptor

type HTTPErrorDescriptor struct {
	StatusCode int
	Message    string
}

func ResolveHTTPErrorDescriptor

func ResolveHTTPErrorDescriptor(providerCode string, err error) HTTPErrorDescriptor

type PaddleProvider

type PaddleProvider struct {
	// contains filtered or unexported fields
}

func NewPaddleProvider

func NewPaddleProvider(
	settings PaddleProviderSettings,
	verifier PaddleSignatureVerifier,
	client paddleCommerceClient,
) (*PaddleProvider, error)

func (*PaddleProvider) BuildCheckoutReconcileEvent

func (provider *PaddleProvider) BuildCheckoutReconcileEvent(
	ctx context.Context,
	transactionID string,
) (WebhookEvent, string, error)

func (*PaddleProvider) BuildUserSyncEvents

func (provider *PaddleProvider) BuildUserSyncEvents(
	ctx context.Context,
	userEmail string,
) ([]WebhookEvent, error)

func (*PaddleProvider) ClientToken

func (provider *PaddleProvider) ClientToken() string

func (*PaddleProvider) Code

func (provider *PaddleProvider) Code() string

func (*PaddleProvider) CreateCustomerPortalSession

func (provider *PaddleProvider) CreateCustomerPortalSession(
	ctx context.Context,
	userEmail string,
) (PortalSession, error)

func (*PaddleProvider) CreateSubscriptionCheckout

func (provider *PaddleProvider) CreateSubscriptionCheckout(
	ctx context.Context,
	userEmail string,
	planCode string,
) (CheckoutSession, error)

func (*PaddleProvider) CreateTopUpCheckout

func (provider *PaddleProvider) CreateTopUpCheckout(
	ctx context.Context,
	userEmail string,
	packCode string,
) (CheckoutSession, error)

func (*PaddleProvider) Environment

func (provider *PaddleProvider) Environment() string

func (*PaddleProvider) NewSubscriptionStatusWebhookProcessor

func (provider *PaddleProvider) NewSubscriptionStatusWebhookProcessor(
	stateRepository SubscriptionStateRepository,
) (WebhookProcessor, error)

func (*PaddleProvider) NewWebhookGrantResolver

func (provider *PaddleProvider) NewWebhookGrantResolver() (WebhookGrantResolver, error)

func (*PaddleProvider) ParseWebhookEvent

func (provider *PaddleProvider) ParseWebhookEvent(payload []byte) (WebhookEventMetadata, error)

func (*PaddleProvider) PublicConfig

func (provider *PaddleProvider) PublicConfig() PublicConfig

func (*PaddleProvider) ResolveCheckoutEventStatus

func (provider *PaddleProvider) ResolveCheckoutEventStatus(eventType string) CheckoutEventStatus

func (*PaddleProvider) SignatureHeaderName

func (provider *PaddleProvider) SignatureHeaderName() string

func (*PaddleProvider) SubscriptionPlans

func (provider *PaddleProvider) SubscriptionPlans() []SubscriptionPlan

func (*PaddleProvider) TopUpPacks

func (provider *PaddleProvider) TopUpPacks() []TopUpPack

func (*PaddleProvider) ValidateCatalog

func (provider *PaddleProvider) ValidateCatalog(ctx context.Context) error

func (*PaddleProvider) VerifySignature

func (provider *PaddleProvider) VerifySignature(signatureHeader string, payload []byte) error

type PaddleProviderSettings

type PaddleProviderSettings struct {
	Environment                string
	APIBaseURL                 string
	APIKey                     string
	ClientToken                string
	ProMonthlyPriceID          string
	PlusMonthlyPriceID         string
	SubscriptionMonthlyCredits map[string]int64
	SubscriptionMonthlyPrices  map[string]int64
	TopUpPackPriceIDs          map[string]string
	TopUpPackCredits           map[string]int64
	TopUpPackPrices            map[string]int64
}

type PaddleSignatureVerifier

type PaddleSignatureVerifier interface {
	Verify(signatureHeader string, payload []byte) error
}

type PaddleWebhookEnvelope

type PaddleWebhookEnvelope struct {
	EventID    string `json:"event_id"`
	EventType  string `json:"event_type"`
	OccurredAt string `json:"occurred_at"`
}

PaddleWebhookEnvelope represents the top-level structure of Paddle webhook notifications.

type PaddleWebhookVerifier

type PaddleWebhookVerifier struct {
	// contains filtered or unexported fields
}

PaddleWebhookVerifier verifies Paddle webhook signatures.

func NewPaddleWebhookVerifier

func NewPaddleWebhookVerifier(webhookSecret string, maxAge time.Duration) (*PaddleWebhookVerifier, error)

NewPaddleWebhookVerifier constructs a verifier with a webhook secret and timestamp tolerance.

func (*PaddleWebhookVerifier) Verify

func (verifier *PaddleWebhookVerifier) Verify(signatureHeader string, payload []byte) error

Verify validates Paddle-Signature against payload bytes.

type PortalSession

type PortalSession struct {
	ProviderCode string
	URL          string
}

type Provider

type Provider interface {
	WebhookProvider
	CommerceProvider
}

type PublicConfig

type PublicConfig struct {
	ProviderCode string
	Environment  string
	ClientToken  string
}

type Service

type Service struct {
	// contains filtered or unexported fields
}

func NewService

func NewService(provider CommerceProvider, subscriptionStateReaders ...SubscriptionStateRepository) *Service

func NewServiceWithWebhookProcessor

func NewServiceWithWebhookProcessor(
	provider CommerceProvider,
	webhookProcessor WebhookProcessor,
	subscriptionStateReaders ...SubscriptionStateRepository,
) *Service

func (*Service) CreatePortalSession

func (service *Service) CreatePortalSession(ctx context.Context, userEmail string) (PortalSession, error)

func (*Service) CreateSubscriptionCheckout

func (service *Service) CreateSubscriptionCheckout(
	ctx context.Context,
	userEmail string,
	planCode string,
) (CheckoutSession, error)

func (*Service) CreateTopUpCheckout

func (service *Service) CreateTopUpCheckout(
	ctx context.Context,
	userEmail string,
	packCode string,
) (CheckoutSession, error)

func (*Service) GetSubscriptionSummary

func (service *Service) GetSubscriptionSummary(ctx context.Context, userEmail string) (SubscriptionSummary, error)

func (*Service) ProviderCode

func (service *Service) ProviderCode() string

func (*Service) ReconcileCheckout

func (service *Service) ReconcileCheckout(
	ctx context.Context,
	userEmail string,
	transactionID string,
) error

func (*Service) SyncUserBillingEvents

func (service *Service) SyncUserBillingEvents(ctx context.Context, userEmail string) error

type StripeProvider

type StripeProvider struct {
	// contains filtered or unexported fields
}

func NewStripeProvider

func NewStripeProvider(
	settings StripeProviderSettings,
	verifier StripeSignatureVerifier,
	client stripeCommerceClient,
) (*StripeProvider, error)

func (*StripeProvider) BuildCheckoutReconcileEvent

func (provider *StripeProvider) BuildCheckoutReconcileEvent(
	ctx context.Context,
	transactionID string,
) (WebhookEvent, string, error)

func (*StripeProvider) BuildUserSyncEvents

func (provider *StripeProvider) BuildUserSyncEvents(ctx context.Context, userEmail string) ([]WebhookEvent, error)

func (*StripeProvider) Code

func (provider *StripeProvider) Code() string

func (*StripeProvider) CreateCustomerPortalSession

func (provider *StripeProvider) CreateCustomerPortalSession(
	ctx context.Context,
	userEmail string,
) (PortalSession, error)

func (*StripeProvider) CreateSubscriptionCheckout

func (provider *StripeProvider) CreateSubscriptionCheckout(
	ctx context.Context,
	userEmail string,
	planCode string,
) (CheckoutSession, error)

func (*StripeProvider) CreateTopUpCheckout

func (provider *StripeProvider) CreateTopUpCheckout(
	ctx context.Context,
	userEmail string,
	packCode string,
) (CheckoutSession, error)

func (*StripeProvider) NewSubscriptionStatusWebhookProcessor

func (provider *StripeProvider) NewSubscriptionStatusWebhookProcessor(
	stateRepository SubscriptionStateRepository,
) (WebhookProcessor, error)

func (*StripeProvider) NewWebhookGrantResolver

func (provider *StripeProvider) NewWebhookGrantResolver() (WebhookGrantResolver, error)

func (*StripeProvider) ParseWebhookEvent

func (provider *StripeProvider) ParseWebhookEvent(payload []byte) (WebhookEventMetadata, error)

func (*StripeProvider) PublicConfig

func (provider *StripeProvider) PublicConfig() PublicConfig

func (*StripeProvider) ResolveCheckoutEventStatus

func (provider *StripeProvider) ResolveCheckoutEventStatus(eventType string) CheckoutEventStatus

func (*StripeProvider) SignatureHeaderName

func (provider *StripeProvider) SignatureHeaderName() string

func (*StripeProvider) SubscriptionPlans

func (provider *StripeProvider) SubscriptionPlans() []SubscriptionPlan

func (*StripeProvider) TopUpPacks

func (provider *StripeProvider) TopUpPacks() []TopUpPack

func (*StripeProvider) ValidateCatalog

func (provider *StripeProvider) ValidateCatalog(ctx context.Context) error

func (*StripeProvider) VerifySignature

func (provider *StripeProvider) VerifySignature(signatureHeader string, payload []byte) error

type StripeProviderSettings

type StripeProviderSettings struct {
	Environment                string
	APIKey                     string
	ClientToken                string
	CheckoutSuccessURL         string
	CheckoutCancelURL          string
	PortalReturnURL            string
	ProMonthlyPriceID          string
	PlusMonthlyPriceID         string
	SubscriptionMonthlyCredits map[string]int64
	SubscriptionMonthlyPrices  map[string]int64
	TopUpPackPriceIDs          map[string]string
	TopUpPackCredits           map[string]int64
	TopUpPackPrices            map[string]int64
}

type StripeSignatureVerifier

type StripeSignatureVerifier interface {
	Verify(signatureHeader string, payload []byte) error
}

type StripeWebhookVerifier

type StripeWebhookVerifier struct {
	// contains filtered or unexported fields
}

func NewStripeWebhookVerifier

func NewStripeWebhookVerifier(webhookSecret string, maxAge time.Duration) (*StripeWebhookVerifier, error)

func (*StripeWebhookVerifier) Verify

func (verifier *StripeWebhookVerifier) Verify(signatureHeader string, payload []byte) error

type SubscriptionPlan

type SubscriptionPlan struct {
	Code           string `json:"code"`
	Label          string `json:"label"`
	MonthlyCredits int64  `json:"monthly_credits"`
	PriceDisplay   string `json:"price_display,omitempty"`
	BillingPeriod  string `json:"billing_period,omitempty"`
}

type SubscriptionState

type SubscriptionState struct {
	ProviderCode        string
	UserEmail           string
	Status              string
	ProviderStatus      string
	ActivePlan          string
	SubscriptionID      string
	NextBillingAt       time.Time
	LastEventID         string
	LastEventType       string
	LastEventOccurredAt time.Time
	LastTransactionID   string
	UpdatedAt           time.Time
}

type SubscriptionStateRepository

type SubscriptionStateRepository interface {
	Upsert(context.Context, SubscriptionStateUpsertInput) error
	Get(context.Context, string, string) (SubscriptionState, bool, error)
	GetBySubscriptionID(context.Context, string, string) (SubscriptionState, bool, error)
}

func NewSubscriptionStateRepository

func NewSubscriptionStateRepository(database *gorm.DB) SubscriptionStateRepository

type SubscriptionStateUpsertInput

type SubscriptionStateUpsertInput struct {
	ProviderCode      string
	UserEmail         string
	Status            string
	ProviderStatus    string
	ActivePlan        string
	SubscriptionID    string
	NextBillingAt     time.Time
	LastEventID       string
	LastEventType     string
	EventOccurredAt   time.Time
	LastTransactionID string
}

type SubscriptionStatusWebhookProcessorProvider

type SubscriptionStatusWebhookProcessorProvider interface {
	NewSubscriptionStatusWebhookProcessor(SubscriptionStateRepository) (WebhookProcessor, error)
}

type SubscriptionSummary

type SubscriptionSummary struct {
	ProviderCode        string
	Enabled             bool
	Status              string
	ProviderStatus      string
	IsDelinquent        bool
	DelinquentReason    string
	ActivePlan          string
	SubscriptionID      string
	NextBillingAt       time.Time
	LastEventType       string
	LastEventOccurredAt time.Time
	Environment         string
	ClientToken         string
	Plans               []SubscriptionPlan
	TopUpPacks          []TopUpPack
}

type TopUpPack

type TopUpPack struct {
	Code          string `json:"code"`
	Label         string `json:"label"`
	Credits       int64  `json:"credits"`
	PriceDisplay  string `json:"price_display,omitempty"`
	BillingPeriod string `json:"billing_period,omitempty"`
}

type WebhookEvent

type WebhookEvent struct {
	ProviderCode string
	EventID      string
	EventType    string
	OccurredAt   time.Time
	Payload      []byte
}

type WebhookEventMetadata

type WebhookEventMetadata struct {
	EventID    string
	EventType  string
	OccurredAt time.Time
}

type WebhookGrant

type WebhookGrant struct {
	UserEmail string
	Credits   int64
	Reason    string
	Reference string
	Metadata  map[string]string
}

type WebhookGrantResolver

type WebhookGrantResolver interface {
	Resolve(context.Context, WebhookEvent) (WebhookGrant, bool, error)
}

func NewWebhookGrantResolver

func NewWebhookGrantResolver(provider CommerceProvider) (WebhookGrantResolver, error)

type WebhookGrantResolverProvider

type WebhookGrantResolverProvider interface {
	NewWebhookGrantResolver() (WebhookGrantResolver, error)
}

type WebhookHandler

type WebhookHandler struct {
	Provider  WebhookProvider
	Processor WebhookProcessor
}

func NewWebhookHandler

func NewWebhookHandler(provider WebhookProvider, processor WebhookProcessor) *WebhookHandler

func (*WebhookHandler) ServeHTTP

func (handler *WebhookHandler) ServeHTTP(responseWriter http.ResponseWriter, request *http.Request)

type WebhookProcessor

type WebhookProcessor interface {
	Process(context.Context, WebhookEvent) error
}

func NewCreditsWebhookProcessor

func NewCreditsWebhookProcessor(
	granter CreditGranter,
	resolver WebhookGrantResolver,
) (WebhookProcessor, error)

func NewSubscriptionStatusWebhookProcessor

func NewSubscriptionStatusWebhookProcessor(
	provider CommerceProvider,
	stateRepository SubscriptionStateRepository,
) (WebhookProcessor, error)

func NewWebhookProcessorChain

func NewWebhookProcessorChain(processors ...WebhookProcessor) WebhookProcessor

type WebhookProcessorFunc

type WebhookProcessorFunc func(context.Context, WebhookEvent) error

func (WebhookProcessorFunc) Process

func (function WebhookProcessorFunc) Process(ctx context.Context, event WebhookEvent) error

type WebhookProvider

type WebhookProvider interface {
	Code() string
	SignatureHeaderName() string
	VerifySignature(signatureHeader string, payload []byte) error
	ParseWebhookEvent(payload []byte) (WebhookEventMetadata, error)
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL