billing

package
v1.17.0 Latest Latest
Warning

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

Go to latest
Published: Aug 7, 2026 License: GPL-3.0 Imports: 16 Imported by: 0

Documentation

Overview

Package billing is the facade of the billing module. It starts with the admin-side order and payment-method management; the public checkout flows join as migration proceeds (ADR-001 step 4). Admin and public handlers call the same service; access-plane concerns stay in the handlers.

Index

Constants

View Source
const (
	CloseOrderTimeMinutes = checkout.CloseOrderTimeMinutes
	MaxQuantity           = checkout.MaxQuantity
)

Order lifecycle constants shared with the V2 orchestration layer.

Variables

View Source
var ErrGatewayUnconfirmed = checkout.ErrGatewayUnconfirmed

ErrGatewayUnconfirmed marks a refused close whose order stays pending until the gateway confirms payment; schedulers treat it as an expected outcome.

View Source
var ErrIdempotencyKeyReused = v2orch.ErrIdempotencyKeyReused

ErrIdempotencyKeyReused is handled as HTTP 409 by the V2 handler. It is a distinct transport condition: the original order remains intact.

Functions

func NewRepoBuilder added in v1.15.2

func NewRepoBuilder() repository.BillingBuilder

NewRepoBuilder exports the module-owned repository implementations for store assembly (ADR-001 step-6 preparation).

Types

type ActivationTaskQueue

type ActivationTaskQueue = portal.ActivationQueue

Portal re-exports the guest storefront subdomain's ports and configuration for the composition root.

type AffiliateReader

type AffiliateReader = wallet.AffiliateReader

AffiliateReader and AuthMethodReader re-export the wallet subdomain's read-only ports onto the identity domain (referral tree, masked login identifiers); the legacy user repository satisfies both structurally.

type AuthMethodReader

type AuthMethodReader = wallet.AuthMethodReader

AffiliateReader and AuthMethodReader re-export the wallet subdomain's read-only ports onto the identity domain (referral tree, masked login identifiers); the legacy user repository satisfies both structurally.

type DailyOrderReport added in v1.15.16

type DailyOrderReport = adminorder.DailyReport

DailyOrderReport and its lines re-export the admin order subdomain's daily summary for the queue shell that formats and delivers it.

type DailyOrderReportLine added in v1.15.16

type DailyOrderReportLine = adminorder.DailyReportLine

DailyOrderReport and its lines re-export the admin order subdomain's daily summary for the queue shell that formats and delivers it.

type Deps

type Deps struct {
	Orders   repository.OrderRepo
	Payments repository.PaymentRepo
	Coupons  repository.CouponRepo
	Plans    PlanReader
	UserSubs UserSubscriptionReader
	// Store carries the scoped transactions, wallet view and inbox the
	// checkout/portal subdomains need; it narrows further when modules own
	// their persistence (ADR-001 step 6).
	Store repository.Store
	Tx    Transactor
	Queue OrderQueue
	// SingleModel forbids holding more than one blocking subscription;
	// runtime-mutable, read per request.
	SingleModel func() bool
	// CurrencyUnit is the site currency used for gateway verification;
	// runtime-mutable, read per request.
	CurrencyUnit func() string
	// Host is the site host used to derive default payment notify URLs.
	Host string
	// IsGatewayMode reports whether notify URLs must use the gateway prefix.
	IsGatewayMode func() bool

	// InvitePolicy snapshots the runtime-mutable site-wide referral
	// fallback for the commission stage; UserProfiles resolves referral
	// settings from the identity domain.
	InvitePolicy func() (percentage uint8, onlyFirstPurchase bool)
	UserProfiles activation.ProfileReader

	// Wallet-specific dependencies: audit-log statements, user cache
	// invalidation and the identity-domain read ports.
	Logs        repository.LogRepo
	UserCache   repository.UserCacheRepo
	Affiliates  AffiliateReader
	AuthMethods AuthMethodReader

	// Portal-specific dependencies.
	PortalPlans        PortalPlanReader
	GuestAccounts      GuestAccountReader
	Sessions           SessionStore
	GuestCheckoutCache GuestCheckoutCache
	ActivationQueue    ActivationTaskQueue
	ExchangeRate       ExchangeRateCache
	Portal             PortalConfig
}

Deps declares everything the module needs; the composition root (internal/svc) provides them. The module wraps legacy repositories during migration and will own its persistence once the domain data moves in (ADR-001 step 5).

type EPayNotifyMeta

type EPayNotifyMeta = callbacks.EPayNotifyMeta

EPayNotifyMeta re-exports the callback subdomain's raw transport details.

type ExchangeRateCache

type ExchangeRateCache = portal.ExchangeRateCache

Portal re-exports the guest storefront subdomain's ports and configuration for the composition root.

type GuestAccountReader

type GuestAccountReader = portal.GuestAccountReader

Portal re-exports the guest storefront subdomain's ports and configuration for the composition root.

type GuestCheckoutCache

type GuestCheckoutCache = portal.GuestCheckoutCache

Portal re-exports the guest storefront subdomain's ports and configuration for the composition root.

type OrderQueue

type OrderQueue interface {
	EnqueueActivation(ctx context.Context, orderNo string) error
	EnqueueDeferredClose(ctx context.Context, orderNo string) error
}

OrderQueue schedules the order lifecycle tasks. The composition root adapts the asynq client; an activation delivery that already exists for the order is not an error (the Paid state is the durable outbox), and a deferred close fires after the pending order's payment window expires.

type PlanReader

type PlanReader = checkout.PlanReader

PlanReader re-exports the checkout subdomain's port onto the subscription domain's plan catalogue.

type PortalConfig

type PortalConfig = portal.Config

Portal re-exports the guest storefront subdomain's ports and configuration for the composition root.

type PortalPlanReader

type PortalPlanReader = portal.PlanReader

Portal re-exports the guest storefront subdomain's ports and configuration for the composition root.

type Service

type Service interface {
	CreateOrder(ctx context.Context, req *dto.CreateOrderRequest) error
	GetOrderList(ctx context.Context, req *dto.GetOrderListRequest) (*dto.GetOrderListResponse, error)
	// UpdateOrderStatus applies the admin's Pending->Paid/Closed transition
	// and enqueues activation for paid orders.
	UpdateOrderStatus(ctx context.Context, req *dto.UpdateOrderStatusRequest) error

	CreatePaymentMethod(ctx context.Context, req *dto.CreatePaymentMethodRequest) (*dto.PaymentConfig, error)
	UpdatePaymentMethod(ctx context.Context, req *dto.UpdatePaymentMethodRequest) (*dto.PaymentConfig, error)
	DeletePaymentMethod(ctx context.Context, req *dto.DeletePaymentMethodRequest) error
	GetPaymentMethodList(ctx context.Context, req *dto.GetPaymentMethodListRequest) (*dto.GetPaymentMethodListResponse, error)
	GetPaymentPlatform(ctx context.Context) (*dto.PlatformResponse, error)

	CreateCoupon(ctx context.Context, req *dto.CreateCouponRequest) error
	UpdateCoupon(ctx context.Context, req *dto.UpdateCouponRequest) error
	DeleteCoupon(ctx context.Context, req *dto.DeleteCouponRequest) error
	BatchDeleteCoupon(ctx context.Context, req *dto.BatchDeleteCouponRequest) error
	GetCouponList(ctx context.Context, req *dto.GetCouponListRequest) (*dto.GetCouponListResponse, error)

	// The user-facing order queries resolve the current user from the request
	// context, enforce ownership and never expose referrer commission.
	QueryOrderDetail(ctx context.Context, req *dto.QueryOrderDetailRequest) (*dto.OrderDetail, error)
	QueryOrderList(ctx context.Context, req *dto.QueryOrderListRequest) (*dto.QueryOrderListResponse, error)

	// The checkout flows resolve the current user from the request context.
	Purchase(ctx context.Context, req *dto.PurchaseOrderRequest) (*dto.PurchaseOrderResponse, error)
	Renewal(ctx context.Context, req *dto.RenewalOrderRequest) (*dto.RenewalOrderResponse, error)
	ResetTraffic(ctx context.Context, req *dto.ResetTrafficOrderRequest) (*dto.ResetTrafficOrderResponse, error)
	Recharge(ctx context.Context, req *dto.RechargeOrderRequest) (*dto.RechargeOrderResponse, error)
	PreCreateOrder(ctx context.Context, req *dto.PurchaseOrderRequest) (*dto.PreOrderResponse, error)
	// CloseOrder settles gateway-collected money instead of closing, releases
	// coupon and gift reservations, and returns reserved plan inventory.
	CloseOrder(ctx context.Context, req *dto.CloseOrderRequest) error

	// The portal flows serve the guest storefront; checkout resolves the
	// client IP from the request context.
	PortalPurchase(ctx context.Context, req *dto.PortalPurchaseRequest) (*dto.PortalPurchaseResponse, error)
	PortalPrePurchase(ctx context.Context, req *dto.PrePurchaseOrderRequest) (*dto.PrePurchaseOrderResponse, error)
	PortalCheckout(ctx context.Context, req *dto.CheckoutOrderRequest) (*dto.CheckoutOrderResponse, error)
	QueryPurchaseOrder(ctx context.Context, req *dto.QueryPurchaseOrderRequest) (*dto.QueryPurchaseOrderResponse, error)
	GetAvailablePaymentMethods(ctx context.Context) (*dto.GetAvailablePaymentMethodsResponse, error)
	GetPortalSubscription(ctx context.Context, req *dto.GetSubscriptionRequest) (*dto.GetSubscriptionResponse, error)
	// IssuePortalSession exchanges a completed guest purchase for a normal
	// authenticated session.
	IssuePortalSession(ctx context.Context, userID int64) (string, error)

	// The gateway callback flows read the authenticated payment configuration
	// from the request context (set by the notify handler's token lookup).
	EPayNotify(ctx context.Context, meta EPayNotifyMeta, req *dto.EPayNotifyRequest) error
	StripeNotify(ctx context.Context, payload []byte, signature string) error
	AlipayNotify(ctx context.Context, form url.Values) error
	CryptomusNotify(ctx context.Context, payload []byte) error

	// The V2 orchestration: idempotent create-and-checkout, guest checkout
	// capabilities and SSE event-stream tickets.
	V2CreateAndCheckout(ctx context.Context, req *dto.V2CreateOrderRequest, idempotencyKey string) (*dto.V2OrderResponse, error)
	V2Checkout(ctx context.Context, orderNo string, req *dto.V2CheckoutOrderRequest) (*dto.V2OrderResponse, error)
	V2GetOrder(ctx context.Context, orderNo, checkoutToken string) (*dto.V2OrderResponse, error)
	V2EventTicket(ctx context.Context, orderNo, checkoutToken string) (*dto.V2EventTicketResponse, error)
	V2Session(ctx context.Context, orderNo, checkoutToken string) (*dto.V2OrderSessionResponse, error)
	// V2AuthorizeEventStream validates the stream ticket and returns the
	// initial snapshot with the ticket expiry.
	V2AuthorizeEventStream(ctx context.Context, orderNo, ticket string) (dto.V2OrderSnapshot, time.Time, error)

	// The wallet flows resolve the current user from the request context:
	// commission withdrawal, balance/commission statements and the affiliate
	// earnings overview.
	CommissionWithdraw(ctx context.Context, req *dto.CommissionWithdrawRequest) (*dto.WithdrawalLog, error)
	QueryUserBalanceLog(ctx context.Context) (*dto.QueryUserBalanceLogListResponse, error)
	QueryUserCommissionLog(ctx context.Context, req *dto.QueryUserCommissionLogListRequest) (*dto.QueryUserCommissionLogListResponse, error)
	QueryWithdrawalLog(ctx context.Context, req *dto.QueryWithdrawalLogListRequest) (*dto.QueryWithdrawalLogListResponse, error)
	QueryUserAffiliate(ctx context.Context) (*dto.QueryUserAffiliateCountResponse, error)
	QueryUserAffiliateList(ctx context.Context, req *dto.QueryUserAffiliateListRequest) (*dto.QueryUserAffiliateListResponse, error)

	// The paid-order activation stages sequenced by the queue shell:
	// recharge credit, referral commission and final settlement. Each is
	// idempotent.
	ActivateRecharge(ctx context.Context, orderNo string) (balance int64, err error)
	SettleOrderCommission(ctx context.Context, orderNo string, buyerID int64) error
	FinalizeOrder(ctx context.Context, orderNo string) error

	// DailyOrderReport totals one day's settled orders for the operations
	// report; plan names are resolved so the caller only formats.
	DailyOrderReport(ctx context.Context, date time.Time) (*DailyOrderReport, error)
}

Service is the only surface other code may depend on; the implementation lives under internal/ where the compiler seals it off.

func New

func New(deps Deps) Service

type SessionStore

type SessionStore = portal.SessionStore

Portal re-exports the guest storefront subdomain's ports and configuration for the composition root.

type Transactor

type Transactor interface {
	InBillingTx(ctx context.Context, fn func(repository.BillingStore) error) error
}

Transactor is the module's window onto billing-scoped transactions; the repository store satisfies it structurally.

type UserSubscriptionReader

type UserSubscriptionReader = checkout.UserSubscriptionReader

UserSubscriptionReader re-exports the checkout subdomain's port onto the subscription domain's user subscriptions.

Directories

Path Synopsis
entity
wallet
Package wallet holds the billing domain's money entities: the wallet row (the single source of truth for balance/gift/commission since migration 02144) and withdrawal records (ADR-001 step 5).
Package wallet holds the billing domain's money entities: the wallet row (the single source of truth for balance/gift/commission since migration 02144) and withdrawal records (ADR-001 step 5).
internal
activation
Package activation implements the billing-domain stages of the paid-order activation saga: the recharge wallet credit, the referral commission and the final settlement.
Package activation implements the billing-domain stages of the paid-order activation saga: the recharge wallet credit, the referral commission and the final settlement.
adminorder
Package adminorder implements the admin-side order management subdomain of the billing module.
Package adminorder implements the admin-side order management subdomain of the billing module.
adminpayment
Package adminpayment implements the payment-method management subdomain of the billing module.
Package adminpayment implements the payment-method management subdomain of the billing module.
callbacks
Package callbacks implements the payment gateway callback subdomain of the billing module: it authenticates EPay/Stripe/Alipay/Cryptomus notifications, verifies them against the order's immutable payment expectation, re-confirms with the gateway and settles the payment.
Package callbacks implements the payment gateway callback subdomain of the billing module: it authenticates EPay/Stripe/Alipay/Cryptomus notifications, verifies them against the order's immutable payment expectation, re-confirms with the gateway and settles the payment.
checkout
Package checkout implements the user-facing money flows of the billing module: purchase, renewal, traffic reset, recharge, order preview and close.
Package checkout implements the user-facing money flows of the billing module: purchase, renewal, traffic reset, recharge, order preview and close.
coupon
Package coupon implements the coupon management subdomain of the billing module.
Package coupon implements the coupon management subdomain of the billing module.
portal
Package portal implements the guest storefront subdomain of the billing module: guest pre-orders, gateway/balance checkout, order status polling with session exchange, and the public plan/payment listings.
Package portal implements the guest storefront subdomain of the billing module: guest pre-orders, gateway/balance checkout, order status polling with session exchange, and the public plan/payment listings.
settle
Package settle holds the one settlement primitive shared by the checkout and payment-callback subdomains: marking a gateway-verified payment as paid and enqueueing activation.
Package settle holds the one settlement primitive shared by the checkout and payment-callback subdomains: marking a gateway-verified payment as paid and enqueueing activation.
userorder
Package userorder implements the user-facing order query subdomain of the billing module (the checkout flows join as migration proceeds).
Package userorder implements the user-facing order query subdomain of the billing module (the checkout flows join as migration proceeds).
v2
Package v2 implements the V2 order orchestration subdomain of the billing module: idempotent create-and-checkout, guest checkout capabilities and the SSE event-stream tickets.
Package v2 implements the V2 order orchestration subdomain of the billing module: idempotent create-and-checkout, guest checkout capabilities and the SSE event-stream tickets.
wallet
Package wallet implements the user-facing wallet subdomain of the billing module: commission withdrawal, balance/commission statements and the affiliate earnings overview.
Package wallet implements the user-facing wallet subdomain of the billing module: commission withdrawal, balance/commission statements and the affiliate earnings overview.

Jump to

Keyboard shortcuts

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