Help us shape the future of Go! Take the 2026 Go Developer Survey

order

package
v1.21.2 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2026 License: GPL-3.0 Imports: 10 Imported by: 0

Documentation

Overview

Package order holds the billing domain's order entities and the rules that travel with them: the order and its details, the status state machine, order numbers, the durable order events and their wake-up channels, and the guest checkout data an order carries until the guest's account exists.

Index

Constants

View Source
const (
	TypeSubscribe    uint8 = 1
	TypeRenewal      uint8 = 2
	TypeResetTraffic uint8 = 3
	TypeRecharge     uint8 = 4
)

Order types, the values of the Type column.

View Source
const (
	StatusPending  uint8 = 1
	StatusPaid     uint8 = 2
	StatusClosed   uint8 = 3
	StatusFailed   uint8 = 4
	StatusFinished uint8 = 5
)

Order statuses, the values of the Status column. An order moves from Pending to Paid when the payment is confirmed and from Paid to Finished once it is fulfilled; Closed and Failed end a Pending order.

View Source
const EventTypePaymentPaid = "order.payment_paid"

EventTypePaymentPaid is the type of the event the order repository appends with the Pending -> Paid transition; its CreatedAt is when the order was settled, the reference point of the guest session exchange.

View Source
const PaymentSessionStarting = `{"state":"creating"}`

PaymentSessionStarting is a durable fence, not a payment result. A process crash or timeout after this write leaves an unknown attempt to reconcile.

View Source
const PaymentWindow = PaymentWindowMinutes * time.Minute

PaymentWindow is PaymentWindowMinutes as a duration.

View Source
const PaymentWindowMinutes = 15

PaymentWindowMinutes is how long a pending order waits for its payment before the deferred close task expires it; gateway checkouts are opened for the same window.

View Source
const TempOrderCacheKey = "temp_order:%s"

TempOrderCacheKey is the Redis key format of the temporary guest order older releases kept until payment: temp_order:<order no>.

View Source
const UnpaidCloseAge = 2 * PaymentWindow

UnpaidCloseAge is the age from which a pending order is treated as abandoned: the expiry close releases an order a gateway that cannot cancel an issued payment page lists as unpaid, and a guest's pending order no longer counts toward the pending-order cap. It doubles the payment window so a payer who opened the gateway page near expiry still finishes.

Variables

This section is empty.

Functions

func CanCheckout added in v1.21.0

func CanCheckout(status uint8) bool

CanCheckout reports whether a payment may be started for an order in status; checkout is only offered while the order waits for payment.

func CanClose added in v1.21.0

func CanClose(status uint8) bool

CanClose reports whether an order in status may still be closed: only a pending order can be given up.

func CanSettle added in v1.21.0

func CanSettle(status uint8) bool

CanSettle reports whether a verified payment may settle an order in status. A pending order becomes paid; a paid order only re-enqueues its activation, which heals a settlement whose queue insertion failed.

func CheckoutTokenHash added in v1.20.3

func CheckoutTokenHash(token string) string

CheckoutTokenHash returns the durable representation of the guest checkout capability. Only the caller receives the original high-entropy token.

func CouponUseStatuses added in v1.21.0

func CouponUseStatuses() []uint8

CouponUseStatuses lists the statuses of orders that count against a coupon's per-user limit: pending orders hold a reservation and settled orders consumed a use.

func EventChannel added in v1.20.3

func EventChannel(orderNo string) string

EventChannel returns the Redis Pub/Sub channel for one order's durable event stream. The channel is only a wake-up path; consumers still read events from the database by id.

func FulfillmentStatusName added in v1.21.0

func FulfillmentStatusName(status uint8) string

FulfillmentStatusName names the fulfillment side of an order status, as carried by V2 snapshots and order events.

func GenerateTradeNo added in v1.20.2

func GenerateTradeNo() string

GenerateTradeNo returns a fixed-width numeric trade number: a 14-digit timestamp in the application's time zone followed by 14 uniformly random digits from crypto/rand. crypto/rand cannot fail in practice; the panic matches how the password salt handles the same error.

func IsSettled added in v1.21.0

func IsSettled(status uint8) bool

IsSettled reports whether the order's payment was collected: it is paid and awaiting fulfillment, or already finished.

func IsTerminal added in v1.21.0

func IsTerminal(status uint8) bool

IsTerminal reports whether no transition leaves status.

func PaymentStatusName added in v1.21.0

func PaymentStatusName(status uint8) string

PaymentStatusName names the payment side of an order status, as carried by V2 snapshots and order events.

func SettledStatuses added in v1.21.0

func SettledStatuses() []uint8

SettledStatuses lists the statuses IsSettled accepts, for queries that select settled orders. Repositories must bind them as integers: a []uint8 is a byte string to database/sql, not a list.

func StatusName added in v1.21.0

func StatusName(status uint8) string

StatusName is the client-facing name of an order status in the V2 API.

Types

type DailyBreakdown added in v1.15.16

type DailyBreakdown struct {
	// Name is the plan name or the payment platform, depending on the group.
	Name string
	// Id is the grouped plan id; zero for a payment-method group and for
	// orders that carry no plan, such as balance top-ups.
	Id     int64
	Orders int64
	Amount int64
}

DailyBreakdown is one row of a settled-order breakdown, grouped by plan or by payment method for the daily report.

type DailyReport added in v1.15.16

type DailyReport struct {
	Date     time.Time
	Orders   int64
	Amount   int64
	ByPlan   []DailyBreakdown
	ByMethod []DailyBreakdown
}

DailyReport totals the orders settled on one day, alongside the plan and payment-method breakdowns.

type Details

type Details struct {
	Id                  int64                `gorm:"primaryKey"`
	ParentId            int64                `gorm:"type:bigint;default:null;comment:Parent Order Id"`
	SubOrders           []*Order             `gorm:"foreignKey:ParentId;references:Id"`
	UserId              int64                `gorm:"type:bigint;not null;default:0;comment:User Id"`
	OrderNo             string               `gorm:"type:varchar(255);not null;default:'';unique;comment:Order No"`
	Type                uint8                `gorm:"type:tinyint(1);not null;default:1;comment:Order Type: 1: Subscribe, 2: Renewal, 3: ResetTraffic, 4: Recharge"`
	Quantity            int64                `gorm:"type:bigint;not null;default:1;comment:Quantity"`
	Price               int64                `gorm:"type:int;not null;default:0;comment:Original price"`
	Amount              int64                `gorm:"type:int;not null;default:0;comment:Order Amount"`
	Discount            int64                `gorm:"type:int;not null;default:0;comment:Order Discount"`
	Coupon              string               `gorm:"type:varchar(255);default:null;comment:Coupon"`
	CouponDiscount      int64                `gorm:"type:int;not null;default:0;comment:Coupon Discount"`
	PaymentId           int64                `gorm:"type:bigint;not null;default:0;comment:Payment Id"`
	Payment             *payment.Payment     `gorm:"foreignKey:PaymentId;references:Id"`
	Method              string               `gorm:"type:varchar(255);not null;default:'';comment:Payment Method"`
	FeeAmount           int64                `gorm:"type:int;not null;default:0;comment:Fee Amount"`
	PaymentAmount       int64                `gorm:"type:bigint;not null;default:0;comment:Amount requested by payment gateway in minor units"`
	PaymentCurrency     string               `gorm:"type:varchar(16);not null;default:'';comment:Payment gateway currency"`
	TradeNo             string               `gorm:"type:varchar(255);default:null;comment:Trade No"`
	GiftAmount          int64                `gorm:"type:int;not null;default:0;comment:User Gift Amount"`
	Commission          int64                `gorm:"type:int;not null;default:0;comment:Order Commission"`
	CommissionRefererId int64                `gorm:"type:bigint;not null;default:0;comment:Referrer credited with the commission"`
	Status              uint8                `gorm:"type:tinyint(1);not null;default:1;comment:Order Status: 1: Pending, 2: Paid, 3: Failed"`
	SubscribeId         int64                `gorm:"type:bigint;not null;default:0;comment:Subscribe Id"`
	SubscribeToken      string               `gorm:"type:varchar(255);default:null;comment:Renewal Subscribe Token"`
	UserSubscribeId     int64                `gorm:"column:user_subscribe_id;type:bigint;not null;default:0;comment:User subscription renewed or reset by the order"`
	Subscribe           *subscribe.Subscribe `gorm:"foreignKey:SubscribeId;references:Id"`
	IsNew               bool                 `gorm:"type:tinyint(1);not null;default:0;comment:Is New Order"`
	CreatedAt           time.Time            `gorm:"<-:create;comment:Create Time"`
	UpdatedAt           time.Time            `gorm:"comment:Update Time"`
}

func (*Details) RefundBasis added in v1.21.0

func (d *Details) RefundBasis() int64

RefundBasis is what was paid for the subscription term: the original order plus its paid renewals. Traffic resets buy traffic, not time, and are not refunded. The refund quote and the refund settlement both measure against it.

An order's Amount is what was paid with money (through a gateway or from the wallet balance) and its GiftAmount the gift credit it consumed, at creation and at a balance checkout alike; the two never hold the same unit, so their sum is the value paid and refunding each to its own balance returns exactly that value.

type Event

type Event struct {
	ID          int64      `gorm:"primaryKey;autoIncrement"`
	OrderID     int64      `gorm:"type:bigint;not null;index:idx_order_event_order_id_id,priority:1"`
	OrderNo     string     `gorm:"type:varchar(255);not null;index:idx_order_event_order_no_id,priority:1"`
	EventType   string     `gorm:"type:varchar(64);not null"`
	Payload     string     `gorm:"type:text;not null"`
	CreatedAt   time.Time  `gorm:"<-:create"`
	PublishedAt *time.Time `gorm:"index:idx_order_event_published_at_id,priority:1"`
}

Event is the durable order event outbox. Redis only distributes these records with low latency; reconnecting clients always recover from this table.

func (Event) TableName

func (Event) TableName() string

type Order

type Order struct {
	Id                     int64     `gorm:"primaryKey"`
	ParentId               int64     `gorm:"type:bigint;default:null;comment:Parent Order Id"`
	UserId                 int64     `gorm:"type:bigint;not null;default:0;comment:User Id"`
	OrderNo                string    `gorm:"type:varchar(255);not null;default:'';unique;comment:Order No"`
	Type                   uint8     `gorm:"type:tinyint(1);not null;default:1;comment:Order Type: 1: Subscribe, 2: Renewal, 3: ResetTraffic, 4: Recharge"`
	Quantity               int64     `gorm:"type:bigint;not null;default:1;comment:Quantity"`
	Price                  int64     `gorm:"type:int;not null;default:0;comment:Original price"`
	Amount                 int64     `gorm:"type:int;not null;default:0;comment:Order Amount"`
	GiftAmount             int64     `gorm:"type:int;not null;default:0;comment:User Gift Amount"`
	Discount               int64     `gorm:"type:int;not null;default:0;comment:Discount Amount"`
	Coupon                 string    `gorm:"type:varchar(255);default:null;comment:Coupon"`
	CouponDiscount         int64     `gorm:"type:int;not null;default:0;comment:Coupon Discount Amount"`
	CouponReserved         bool      `gorm:"type:tinyint(1);not null;default:0;comment:Coupon usage reserved while order is pending"`
	Commission             int64     `gorm:"type:int;not null;default:0;comment:Order Commission"`
	CommissionRefererId    int64     `gorm:"type:bigint;not null;default:0;comment:Referrer credited with the commission"`
	PaymentId              int64     `gorm:"type:bigint;not null;default:0;comment:Payment Method Id"`
	Method                 string    `gorm:"type:varchar(255);not null;default:'';comment:Payment Method"`
	FeeAmount              int64     `gorm:"type:int;not null;default:0;comment:Fee Amount"`
	PaymentAmount          int64     `gorm:"type:bigint;not null;default:0;comment:Amount requested by payment gateway in minor units"`
	PaymentCurrency        string    `gorm:"type:varchar(16);not null;default:'';comment:Payment gateway currency"`
	PaymentSession         string    `gorm:"type:text;default:null;comment:Durable external checkout attempt and payment entry" json:"-"`
	TradeNo                string    `gorm:"type:varchar(255);default:null;comment:Trade No"`
	Status                 uint8     `gorm:"type:tinyint(1);not null;default:1;comment:Order Status: 1: Pending, 2: Paid, 3:Close, 4: Failed, 5:Finished;"`
	SubscribeId            int64     `gorm:"type:bigint;not null;default:0;comment:Subscribe Id"`
	SubscribeToken         string    `gorm:"type:varchar(255);default:null;comment:Renewal Subscribe Token"`
	UserSubscribeId        int64     `gorm:"column:user_subscribe_id;type:bigint;not null;default:0;comment:User subscription renewed or reset by the order"`
	GuestAuthType          string    `gorm:"type:varchar(255);not null;default:'';comment:Guest auth type before account activation"`
	GuestIdentifier        string    `gorm:"type:varchar(255);not null;default:'';comment:Guest auth identifier before account activation"`
	GuestPasswordHash      string    `gorm:"type:varchar(255);not null;default:'';comment:Guest password hash before account activation"`
	GuestInviteCode        string    `gorm:"type:varchar(255);not null;default:'';comment:Guest invite code before account activation"`
	GuestCheckoutTokenHash string    `gorm:"type:char(64);not null;default:'';comment:Hash of guest checkout capability"`
	StateVersion           int64     `gorm:"type:bigint;not null;default:0;comment:Monotonic version for order state transitions"`
	IdempotencyKey         string    `gorm:"type:varchar(128);uniqueIndex;default:null;comment:V2 create idempotency key"`
	IdempotencyHash        string    `gorm:"type:char(64);default:null;comment:Stable hash of the V2 create request"`
	IsNew                  bool      `gorm:"type:tinyint(1);not null;default:0;comment:Is New Order"`
	CreatedAt              time.Time `gorm:"<-:create;comment:Create Time"`
	UpdatedAt              time.Time `gorm:"comment:Update Time"`
}

func (*Order) IsPaidRenewal added in v1.21.0

func (o *Order) IsPaidRenewal() bool

IsPaidRenewal reports whether the order renews a subscription and its payment was collected.

func (Order) TableName

func (Order) TableName() string

type OrdersTotal

type OrdersTotal struct {
	AmountTotal        int64
	NewOrderAmount     int64
	RenewalOrderAmount int64
}

type OrdersTotalWithDate

type OrdersTotalWithDate struct {
	Date               string
	AmountTotal        int64
	NewOrderAmount     int64
	RenewalOrderAmount int64
}

type TemporaryOrderInfo added in v1.20.3

type TemporaryOrderInfo struct {
	OrderNo       string `json:"order_no"`
	CheckoutToken string `json:"checkout_token"`
	Identifier    string `json:"identifier"`
	AuthType      string `json:"auth_type"`
	// PasswordHash is the one-way encoded password needed to finish a guest
	// account after payment.  Never place the plaintext password in Redis.
	PasswordHash string `json:"password_hash,omitempty"`
	// Password is retained only to finish orders created by older releases.
	// New orders never populate it and it must never be logged.
	Password   string `json:"password,omitempty"`
	InviteCode string `json:"invite_code,omitempty"`
}

func (*TemporaryOrderInfo) Marshal added in v1.20.3

func (t *TemporaryOrderInfo) Marshal() ([]byte, error)

func (*TemporaryOrderInfo) Unmarshal added in v1.20.3

func (t *TemporaryOrderInfo) Unmarshal(data []byte) error

type UserCounts

type UserCounts struct {
	NewUsers     int64 `gorm:"column:new_users"`
	RenewalUsers int64 `gorm:"column:renewal_users"`
}

UserCounts User counts for new and renewal users

Jump to

Keyboard shortcuts

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