Documentation
¶
Overview ¶
Package checkout implements the user-facing money flows of the billing module: purchase, renewal, traffic reset, recharge, order preview and close. Only the module facade may reach it.
Index ¶
- Constants
- Variables
- func ApplyQuote(o *orderEntity.Order, q pricing.Quote)
- func EnsureCouponUserLimit(ctx context.Context, orders CouponUserLimiter, userID int64, c *coupon.Coupon) error
- func InsertOrder(ctx context.Context, tx repository.BillingStore, o *orderEntity.Order, ...) error
- func ReserveCoupon(ctx context.Context, tx repository.BillingStore, o *orderEntity.Order) error
- type CouponUserLimiter
- type Deps
- type Inventory
- type OrderQueue
- type Orders
- type PlanReader
- type PlanTerms
- type Service
- func (s *Service) Close(ctx context.Context, req *dto.CloseOrderRequest) error
- func (s *Service) CloseByAdmin(ctx context.Context, orderNo string, adminID int64) (bool, error)
- func (s *Service) PreCreateOrder(ctx context.Context, req *dto.PurchaseOrderRequest) (*dto.PreOrderResponse, error)
- func (s *Service) Purchase(ctx context.Context, req *dto.PurchaseOrderRequest) (*dto.PurchaseOrderResponse, error)
- func (s *Service) Recharge(ctx context.Context, req *dto.RechargeOrderRequest) (*dto.RechargeOrderResponse, error)
- func (s *Service) Renewal(ctx context.Context, req *dto.RenewalOrderRequest) (*dto.RenewalOrderResponse, error)
- func (s *Service) ResetTraffic(ctx context.Context, req *dto.ResetTrafficOrderRequest) (*dto.ResetTrafficOrderResponse, error)
- type Transactor
- type UserSubscriptionReader
- type Wallets
Constants ¶
const ( CloseOrderTimeMinutes = orderEntity.PaymentWindowMinutes // MaxOrderAmount Order amount limits MaxOrderAmount = 2147483647 // int32 max value (2.1 billion) MaxRechargeAmount = 2000000000 // 2 billion, slightly lower for safety MinRechargeAmount = 100 // minimum recharge amount in minor currency units MaxQuantity = 1000 // Maximum quantity per order )
Order lifecycle constants shared with the V2 orchestration layer via the module facade.
Variables ¶
var ErrGatewayUnconfirmed = gateway.ErrUnconfirmed
ErrGatewayUnconfirmed reports that a gateway order could not be confirmed safe to close, so the order intentionally stays pending.
Functions ¶
func ApplyQuote ¶ added in v1.21.0
func ApplyQuote(o *orderEntity.Order, q pricing.Quote)
ApplyQuote copies a quote onto the order being created.
func EnsureCouponUserLimit ¶ added in v1.21.0
func EnsureCouponUserLimit(ctx context.Context, orders CouponUserLimiter, userID int64, c *coupon.Coupon) error
EnsureCouponUserLimit is ensureCouponUserLimit for the order creators of other subdomains, such as an administrator's.
func InsertOrder ¶ added in v1.21.0
func InsertOrder(ctx context.Context, tx repository.BillingStore, o *orderEntity.Order, source string) error
InsertOrder stores the order and its audit record as one atomic billing operation; source names who created it.
func ReserveCoupon ¶ added in v1.21.0
func ReserveCoupon(ctx context.Context, tx repository.BillingStore, o *orderEntity.Order) error
ReserveCoupon claims one use of the order's coupon inside its creation transaction.
Types ¶
type CouponUserLimiter ¶ added in v1.21.0
type CouponUserLimiter = couponUserLimiter
CouponUserLimiter counts a buyer's uses of a coupon; the order repository satisfies it both outside and inside a transaction.
type Deps ¶
type Deps struct {
Orders Orders
Coupons pricing.CouponFinder
Payments gateway.MethodFinder
Plans PlanReader
UserSubs UserSubscriptionReader
Wallets Wallets
Tx Transactor
Inventory Inventory
Queue OrderQueue
// Gateways opens the gateway of an order's payment method; nil selects
// the production gateways.
Gateways *gateway.Registry
// SingleModel forbids holding more than one blocking subscription;
// read per request because the admin can change it at runtime.
SingleModel func() bool
// CurrencyUnit is the site currency; read per request because the admin
// can change it at runtime.
CurrencyUnit func() string
}
type OrderQueue ¶
type OrderQueue interface {
EnqueueActivation(ctx context.Context, orderNo string) error
EnqueueDeferredClose(ctx context.Context, orderNo string) error
}
OrderQueue mirrors the facade's order queue port.
type Orders ¶ added in v1.21.0
type Orders interface {
FindOneByOrderNo(ctx context.Context, orderNo string) (*orderEntity.Order, error)
MarkOrderPaid(ctx context.Context, orderNo, tradeNo string) (bool, error)
CountUserCouponUsage(ctx context.Context, userID int64, coupon string) (int64, error)
IsUserEligibleForNewOrder(ctx context.Context, userID int64) (bool, error)
}
Orders is the order persistence the flows use outside a transaction; settlement marks orders paid through it.
type PlanReader ¶
type PlanReader interface {
FindOne(ctx context.Context, id int64) (*subscribeEntity.Subscribe, error)
}
PlanReader is the module's port onto the subscription domain's plan catalogue; the legacy subscribe repository satisfies it structurally.
type PlanTerms ¶ added in v1.21.0
type PlanTerms struct {
Plan *subscribeEntity.Subscribe
Quantity int64
Coupon *coupon.Coupon
Method *paymentEntity.Payment
}
PlanTerms are what prices an order for a plan: the quantity, the coupon checked against the plan, and the payment method whose fee applies.
func ResolvePlanTerms ¶ added in v1.21.0
func ResolvePlanTerms(ctx context.Context, coupons pricing.CouponFinder, methods gateway.MethodFinder, plan *subscribeEntity.Subscribe, quantity int64, code string, paymentID int64) (PlanTerms, error)
ResolvePlanTerms resolves the coupon an order names and the payment method it is paid with. A zero paymentID prices the order without a method, as a preview does before the buyer chose one.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
func NewService ¶
func (*Service) Close ¶
Close closes a pending order: the billing transaction releases the coupon reservation and refunds the gift deduction, then the reserved plan inventory returns in its own subscription-domain transaction (ADR-001 step 2). Orders whose gateway checkout already collected money are settled instead of closed.
func (*Service) CloseByAdmin ¶ added in v1.21.0
CloseByAdmin closes a pending order for an administrator through the same flow as owner and expiry closes, so the coupon, gift deduction and plan inventory are released and a cancellable gateway payment is voided first; a payment the gateway confirms is settled instead. It reports whether this call closed the order.
func (*Service) PreCreateOrder ¶
func (s *Service) PreCreateOrder(ctx context.Context, req *dto.PurchaseOrderRequest) (*dto.PreOrderResponse, error)
PreCreateOrder previews the price of a purchase, or of a renewal when the request names the subscription to renew, without creating an order. It prices with the same terms and the same Compute as the order it previews, using the gift credit the buyer's wallet holds now.
func (*Service) Purchase ¶
func (s *Service) Purchase(ctx context.Context, req *dto.PurchaseOrderRequest) (*dto.PurchaseOrderResponse, error)
Purchase creates a pending order for a new subscription. The billing transaction locks the buyer's wallet, prices the order with the gift credit it holds, reserves the coupon use and the gift credit and inserts the order; plan inventory is reserved afterwards in its own subscription-domain transaction (ADR-001 step 2).
func (*Service) Recharge ¶
func (s *Service) Recharge(ctx context.Context, req *dto.RechargeOrderRequest) (*dto.RechargeOrderResponse, error)
Recharge creates a balance recharge order. The recharged amount is the order price; the payment method's fee is charged on top.
func (*Service) Renewal ¶
func (s *Service) Renewal(ctx context.Context, req *dto.RenewalOrderRequest) (*dto.RenewalOrderResponse, error)
Renewal creates a pending order that extends one of the buyer's subscriptions. It is priced like a purchase of the subscription's plan.
func (*Service) ResetTraffic ¶
func (s *Service) ResetTraffic(ctx context.Context, req *dto.ResetTrafficOrderRequest) (*dto.ResetTrafficOrderResponse, error)
ResetTraffic creates a paid traffic-reset order for an active subscription. The plan's replacement price is paid like any other order: gift credit first, then the payment method's fee on what remains.
type Transactor ¶ added in v1.21.0
type Transactor interface {
InBillingTx(ctx context.Context, fn func(repository.BillingStore) error) error
}
Transactor runs billing-scoped transactions.
type UserSubscriptionReader ¶
type UserSubscriptionReader interface {
HasBlockingSubscription(ctx context.Context, userID int64) (bool, error)
CountQuotaConsumingSubscriptions(ctx context.Context, userID, subscribeID int64) (int64, error)
FindOneUserSubscribe(ctx context.Context, id int64) (*usersub.SubscribeDetails, error)
FindOneSubscribe(ctx context.Context, id int64) (*usersub.Subscribe, error)
}
UserSubscriptionReader is the module's port onto the subscription domain's user subscriptions; the legacy user-subscription repository satisfies it structurally.