economy

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 3, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Index

Constants

View Source
const (
	StoreAppleAppStore      = 0
	StoreGooglePlay         = 1
	StoreHuaweiAppGallery   = 2
	StoreFacebookInstant    = 3
	StoreSamsungGalaxyStore = 4
)

Store provider constants.

View Source
const (
	EnvUnknown    = 0
	EnvSandbox    = 1
	EnvProduction = 2
)

Variables

View Source
var ErrInsufficientFunds = errors.New("insufficient wallet balance")

ErrInsufficientFunds aliases negative-balance rejection for older call sites.

View Source
var ErrLedgerCursorInvalid = errors.New("wallet ledger cursor invalid")

ErrLedgerCursorInvalid is returned for malformed ledger cursors.

View Source
var ErrSubscriptionsListInvalidCursor = errors.New("subscriptions list cursor invalid")
View Source
var ErrTransactionSeenBefore = errors.New("TRANSACTION_SEEN_BEFORE")

ErrTransactionSeenBefore is retained for older tests; prefer SeenBefore on ValidatedPurchase.

Functions

func AppleNotificationHandler

func AppleNotificationHandler(logger NotificationLogger, pool *pgxpool.Pool, expectedEndpointID string, cbs IAPNotificationCallbacks) http.HandlerFunc

AppleNotificationHandler handles App Store Server Notifications V2 (and test JSON fixtures).

func GetWallet

func GetWallet(ctx context.Context, pool *pgxpool.Pool, userID string) (map[string]int64, error)

GetWallet returns the user's current wallet map (empty map if unset).

func GoogleNotificationHandler

func GoogleNotificationHandler(logger NotificationLogger, pool *pgxpool.Pool, expectedEndpointID string, cbs IAPNotificationCallbacks) http.HandlerFunc

GoogleNotificationHandler handles Play RTDN Pub/Sub push (and flat JSON fixtures).

func ProcessAppleValidationTx

func ProcessAppleValidationTx(ctx context.Context, pool *pgxpool.Pool, userID string, p StorePurchase, rawResponse string) error

ProcessAppleValidationTx persists an Apple purchase without auto-crediting wallet. Deprecated name retained for tests; prefer ValidatePurchaseApple.

func ProcessGoogleValidationTx

func ProcessGoogleValidationTx(ctx context.Context, pool *pgxpool.Pool, userID string, p StorePurchase, rawResponse string) error

ProcessGoogleValidationTx persists a Google purchase without auto-crediting wallet.

func UpdateWallet

func UpdateWallet(
	ctx context.Context,
	pool *pgxpool.Pool,
	userID string,
	changeset map[string]int64,
	metadata map[string]interface{},
	updateLedger bool,
) (updated, previous map[string]int64, err error)

UpdateWallet performs a single atomic wallet mutation.

func UpdateWalletLedgerMetadata

func UpdateWalletLedgerMetadata(ctx context.Context, pool *pgxpool.Pool, ledgerID, userID string, metadata map[string]interface{}) error

UpdateWalletLedgerMetadata merges metadata into an existing ledger row.

Types

type ErrWalletNegative

type ErrWalletNegative struct {
	UserID  string
	Path    string
	Current int64
	Amount  int64
}

ErrWalletNegative is returned when a wallet mutation would make a balance negative.

func (*ErrWalletNegative) Error

func (e *ErrWalletNegative) Error() string

func (*ErrWalletNegative) Is

func (e *ErrWalletNegative) Is(target error) bool

type IAPConfig

type IAPConfig struct {
	AppleSharedPassword           string
	AppleNotificationsEndpointID  string
	GoogleClientEmail             string
	GooglePrivateKey              string
	GooglePackageName             string
	GoogleNotificationsEndpointID string
	HuaweiPublicKey               string
	HuaweiClientID                string
	HuaweiClientSecret            string
	FacebookAppSecret             string
	SamsungPackageName            string
}

IAPConfig holds provider credentials (from env/server config).

var DefaultIAPConfig IAPConfig

DefaultIAPConfig is set at server startup for runtime module helpers.

func LoadIAPConfigFromEnv

func LoadIAPConfigFromEnv() IAPConfig

LoadIAPConfigFromEnv reads IAP credentials from environment variables. Empty values leave the corresponding field unset (dev/test-receipt paths still work).

type IAPNotificationCallbacks

type IAPNotificationCallbacks struct {
	PurchaseApple      func(ctx context.Context, ntype NotificationType, purchase *ValidatedPurchase, raw json.RawMessage) error
	PurchaseGoogle     func(ctx context.Context, ntype NotificationType, purchase *ValidatedPurchase, raw json.RawMessage) error
	SubscriptionApple  func(ctx context.Context, ntype NotificationType, sub *ValidatedSubscription, raw json.RawMessage) error
	SubscriptionGoogle func(ctx context.Context, ntype NotificationType, sub *ValidatedSubscription, raw json.RawMessage) error
}

IAPNotificationCallbacks are optional runtime hooks invoked after RTDN processing.

type LedgerItem

type LedgerItem struct {
	ID         string
	UserID     string
	Changeset  map[string]int64
	Metadata   map[string]interface{}
	CreateTime time.Time
	UpdateTime time.Time
}

LedgerItem is a wallet_ledger row.

type LedgerList

type LedgerList struct {
	Items      []*LedgerItem
	NextCursor string
}

LedgerList is a paginated ledger response.

func ListWalletLedger

func ListWalletLedger(ctx context.Context, pool *pgxpool.Pool, userID string, limit int, cursor string) (*LedgerList, error)

ListWalletLedger lists ledger entries newest-first with gob cursor pagination.

type MultiUpdateParams

type MultiUpdateParams struct {
	AccountUpdates []auth.AccountUpdateParams
	StorageWrites  []*storage.StorageObject
	StorageDeletes []storage.DeleteRequest
	WalletUpdates  []WalletUpdate
	UpdateLedger   bool
}

MultiUpdateParams groups atomic account, storage, and wallet mutations.

type NotificationLogger

type NotificationLogger interface {
	Error(msg string, err error)
	Warn(msg string)
}

NotificationLogger is optional logging for RTDN handlers.

type NotificationType

type NotificationType int

NotificationType mirrors store server-notification categories for runtime hooks.

const (
	NotificationTypeUnknown NotificationType = iota
	NotificationTypeSubscribed
	NotificationTypeRenewed
	NotificationTypeRefunded
	NotificationTypeExpired
	NotificationTypeRevoked
	NotificationTypeOther
)

type StorePurchase

type StorePurchase struct {
	TransactionID string
	ProductID     string
	PurchaseTime  time.Time
	Environment   int
}

StorePurchase is a pre-parsed purchase used by persistence helpers / tests.

type SubscriptionListResult

type SubscriptionListResult struct {
	Subscriptions []*ValidatedSubscription
	Cursor        string
	PrevCursor    string
}

func ListSubscriptions

func ListSubscriptions(ctx context.Context, pool *pgxpool.Pool, userID string, limit int, cursor string) (*SubscriptionListResult, error)

ListSubscriptions lists subscriptions for a user with optional gob cursor pagination.

type ValidatedPurchase

type ValidatedPurchase struct {
	UserID        string
	ProductID     string
	TransactionID string
	Store         int
	PurchaseTime  time.Time
	CreateTime    time.Time
	UpdateTime    time.Time
	RefundTime    time.Time
	Environment   int
	SeenBefore    bool
	RawResponse   string
}

ValidatedPurchase is a persisted or validated one-time purchase.

func GetPurchaseByTransactionID

func GetPurchaseByTransactionID(ctx context.Context, pool *pgxpool.Pool, transactionID string) (*ValidatedPurchase, error)

GetPurchaseByTransactionID looks up a purchase by transaction id.

func ListPurchases

func ListPurchases(ctx context.Context, pool *pgxpool.Pool, userID string, limit int) ([]*ValidatedPurchase, error)

ListPurchases lists purchases for a user (newest first).

func MarkPurchaseRefunded

func MarkPurchaseRefunded(ctx context.Context, pool *pgxpool.Pool, transactionID string, when time.Time) (*ValidatedPurchase, error)

MarkPurchaseRefunded sets refund_time on a purchase row.

func PersistPurchase

func PersistPurchase(ctx context.Context, pool *pgxpool.Pool, userID string, store int, p StorePurchase, rawResponse string) (*ValidatedPurchase, error)

PersistPurchase persists a pre-validated purchase (no external store call).

func ValidatePurchaseApple

func ValidatePurchaseApple(ctx context.Context, pool *pgxpool.Pool, cfg IAPConfig, userID, receipt string, persist bool) (*ValidatedPurchase, error)

ValidatePurchaseApple validates Apple receipt (JWS, legacy verifyReceipt, or JSON test receipt).

func ValidatePurchaseFacebookInstant

func ValidatePurchaseFacebookInstant(ctx context.Context, pool *pgxpool.Pool, cfg IAPConfig, userID, signedRequest string, persist bool) (*ValidatedPurchase, error)

ValidatePurchaseFacebookInstant verifies HMAC signedRequest.

func ValidatePurchaseGoogle

func ValidatePurchaseGoogle(ctx context.Context, pool *pgxpool.Pool, cfg IAPConfig, userID, productID, purchaseToken string, persist bool) (*ValidatedPurchase, error)

ValidatePurchaseGoogle validates Google purchase (test JSON, Publisher API, or dev token).

func ValidatePurchaseHuawei

func ValidatePurchaseHuawei(ctx context.Context, pool *pgxpool.Pool, cfg IAPConfig, userID, purchaseData, signature string, persist bool) (*ValidatedPurchase, error)

ValidatePurchaseHuawei validates Huawei purchase signature/data or test JSON.

func ValidatePurchaseSamsung

func ValidatePurchaseSamsung(ctx context.Context, pool *pgxpool.Pool, cfg IAPConfig, userID, purchaseID string, persist bool) (*ValidatedPurchase, error)

ValidatePurchaseSamsung validates Samsung Galaxy Store receipt.

type ValidatedSubscription

type ValidatedSubscription struct {
	UserID                string
	ProductID             string
	OriginalTransactionID string
	Store                 int
	PurchaseTime          time.Time
	ExpireTime            time.Time
	CreateTime            time.Time
	UpdateTime            time.Time
	RefundTime            time.Time
	Environment           int
	Active                bool
	SeenBefore            bool
	RawResponse           string
}

ValidatedSubscription is a persisted subscription.

func GetSubscriptionByOriginalTransactionID

func GetSubscriptionByOriginalTransactionID(ctx context.Context, pool *pgxpool.Pool, originalTransactionID string) (*ValidatedSubscription, error)

GetSubscriptionByOriginalTransactionID looks up a subscription.

func GetSubscriptionByProductID

func GetSubscriptionByProductID(ctx context.Context, pool *pgxpool.Pool, userID, productID string) (*ValidatedSubscription, error)

GetSubscriptionByProductID returns a user's subscription for a product.

func UpdateSubscriptionExpiry

func UpdateSubscriptionExpiry(ctx context.Context, pool *pgxpool.Pool, originalTransactionID string, expire, refund time.Time, rawNotification string) (*ValidatedSubscription, error)

UpdateSubscriptionExpiry sets expire/refund times from a notification.

func ValidateSubscriptionApple

func ValidateSubscriptionApple(ctx context.Context, pool *pgxpool.Pool, cfg IAPConfig, userID, receipt string, persist bool) (*ValidatedSubscription, error)

ValidateSubscriptionApple validates Apple subscription (test JSON, JWS, or verifyReceipt).

func ValidateSubscriptionGoogle

func ValidateSubscriptionGoogle(ctx context.Context, pool *pgxpool.Pool, cfg IAPConfig, userID, productID, purchaseToken string, persist bool) (*ValidatedSubscription, error)

ValidateSubscriptionGoogle validates Google subscription.

type WalletUpdate

type WalletUpdate struct {
	UserID    string
	Changeset map[string]int64
	Metadata  map[string]interface{}
}

WalletUpdate is a single wallet mutation request.

type WalletUpdateResult

type WalletUpdateResult struct {
	UserID   string
	Updated  map[string]int64
	Previous map[string]int64
}

WalletUpdateResult is the outcome of a successful wallet update for one user entry.

func MultiUpdate

MultiUpdate executes account, storage, and wallet mutations in one transaction.

func UpdateWallets

func UpdateWallets(ctx context.Context, pool *pgxpool.Pool, updates []WalletUpdate, updateLedger bool) ([]WalletUpdateResult, error)

UpdateWallets applies batch wallet updates in one transaction (all-or-nothing on negative).

func UpdateWalletsTx

func UpdateWalletsTx(ctx context.Context, tx pgx.Tx, updates []WalletUpdate, updateLedger bool) ([]WalletUpdateResult, error)

UpdateWalletsTx applies wallet updates inside an existing transaction.

Jump to

Keyboard shortcuts

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