native

package
v4.2.0 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package native implements the order package's v2 routes in the package itself, on the kernel's v2_order and v2_coupon tables adopted in place (kernel.storage.adopt). Legacy handlers and native routes share the tables, so a route can switch between them at any time; the kernel keeps writing v2_order from the payment callbacks (paid, completed) and reads it for statistics. Responses are byte-compatible with the legacy handlers (internal/tests/ordercompat).

Other domains are read through kernel views only: the plan catalog (kapi_plan_catalog_v1) and the subscription groups a plan grants (kapi_plan_subscription_group_v1) for pricing and completing an order, the plan names (kapi_plan_name_v1) for the order lists and details, and the user directory (kapi_user_directory_v1) for the buyer's current plan and, in an administrator's order answers, the buyer's e-mail. Completing an order grants its plan through the kernel's KernelSubscriber contract (kernel.subscriber.entitlements.v1): the package never writes v2_user. Completion pays no commission and sends no notification, in the kernel as here.

The order list and detail answers carry the order, its plan's id and name and, for an administrator, its buyer's id and e-mail; never the buyer's subscription token or UUID, which no kernel view exposes.

Index

Constants

View Source
const (
	AdminOrdersRouteID = "order.admin.orders.get"
	AdminOrderRouteID  = "order.admin.orders.id.get"
	UserOrdersRouteID  = "order.user.order.get"
	UserOrderRouteID   = "order.user.order.id.get"
)

Order list and detail routes, by route id.

View Source
const MarkPaidRouteID = "order.admin.orders.id.paid.post"

MarkPaidRouteID marks an order paid and completes it.

View Source
const OrderSortTiebreaker = "id DESC"

OrderSortTiebreaker orders orders that share a sorted value, so pages neither repeat nor skip an order.

Variables

View Source
var OrderSortColumns = map[string]v2compat.SortColumn{
	"id":           {Expr: "id", Unique: true},
	"trade_no":     {Expr: "trade_no", Unique: true},
	"status":       {Expr: "status"},
	"type":         {Expr: "type"},
	"total_amount": {Expr: "total_amount"},
	"created_at":   {Expr: "created_at"},
	"paid_at":      {Expr: "paid_at", Nullable: true},
}

OrderSortColumns are the columns the administrator's order list sorts by: the keys and the meaning of the kernel's service.OrderSortColumns. The buyer's e-mail and the plan's name are other tables' and are not sortable; an unpaid order (NULL paid_at) sorts last ascending.

Functions

func CompleteRequestID

func CompleteRequestID(orderID uint) string

CompleteRequestID names an order's completion in the kernel's subscriber request ledger, as the kernel's completion (OrderService.Complete and the payment callbacks) does, so an order's plan is granted once whichever side completes it.

Types

type Buyer

type Buyer struct {
	ID    uint   `gorm:"primaryKey" json:"id"`
	Email string `json:"email"`
}

Buyer is the part of a kapi_user_directory_v1 row an administrator's order answer shows as its buyer.

func (Buyer) TableName

func (Buyer) TableName() string

TableName is the kernel view.

type CatalogPlan

type CatalogPlan struct {
	ID             uint `gorm:"primaryKey"`
	GroupID        uint
	TransferEnable int64 // GiB
	SpeedLimit     *int64
	DeviceLimit    *int
	MonthPrice     *int64
	QuarterPrice   *int64
	HalfYearPrice  *int64
	YearPrice      *int64
	TwoYearPrice   *int64
	ThreeYearPrice *int64
	OnetimePrice   *int64
}

CatalogPlan is a row of kapi_plan_catalog_v1: what an order needs of a plan.

func (CatalogPlan) TableName

func (CatalogPlan) TableName() string

TableName is the kernel view.

type Coupon

type Coupon struct {
	ID           uint      `gorm:"primaryKey" json:"id"`
	Code         string    `gorm:"size:32;uniqueIndex" json:"code"`
	Name         string    `gorm:"size:255" json:"name"`
	Type         int       `gorm:"default:1" json:"type"`       // 1: percentage, 2: fixed amount
	Value        int       `json:"value"`                       // percentage (0-100) or amount in cents
	LimitUse     *int      `json:"limit_use"`                   // null or -1 = unlimited
	LimitUseWith *uint     `gorm:"index" json:"limit_use_with"` // limit to specific plan ID
	LimitPeriod  *string   `gorm:"size:20" json:"limit_period"` // limit to specific period
	UseCount     int       `gorm:"default:0" json:"use_count"`  // how many times used
	StartedAt    int64     `json:"started_at"`                  // unix timestamp
	EndedAt      int64     `json:"ended_at"`                    // unix timestamp
	CreatedAt    time.Time `json:"created_at"`
	UpdatedAt    time.Time `json:"updated_at"`
}

Coupon is a v2_coupon row, with the kernel model's fields and tags.

func (Coupon) TableName

func (Coupon) TableName() string

TableName is the adopted kernel table.

type DirectoryUser

type DirectoryUser struct {
	ID     uint `gorm:"primaryKey"`
	PlanID *uint
}

DirectoryUser is the part of a kapi_user_directory_v1 row an order reads.

func (DirectoryUser) TableName

func (DirectoryUser) TableName() string

TableName is the kernel view.

type Order

type Order struct {
	ID                uint      `gorm:"primaryKey" json:"id"`
	InviteUserID      *uint     `gorm:"index" json:"invite_user_id"`
	UserID            uint      `gorm:"index" json:"user_id"`
	PlanID            uint      `gorm:"index" json:"plan_id"`
	CouponID          *uint     `gorm:"index" json:"coupon_id"`
	PaymentID         *uint     `gorm:"index" json:"payment_id"`
	Type              int       `json:"type"` // 1: new, 2: renew, 3: upgrade, 4: reset
	Period            string    `gorm:"size:20" json:"period"`
	TradeNo           string    `gorm:"size:36;uniqueIndex" json:"trade_no"`
	CallbackNo        *string   `gorm:"size:255" json:"callback_no"`
	TotalAmount       int64     `json:"total_amount"`
	DiscountAmount    *int64    `json:"discount_amount"`
	SurplusAmount     *int64    `json:"surplus_amount"`
	RefundAmount      *int64    `json:"refund_amount"`
	Balance           *int64    `json:"balance"`
	SurplusOrder      *string   `gorm:"type:text" json:"surplus_order"`
	Status            int       `gorm:"default:0" json:"status"` // 0: pending, 1: paid, 2: cancelled, 3: completed, 4: discounted
	CommissionStatus  int       `gorm:"default:0" json:"commission_status"`
	CommissionBalance int64     `gorm:"default:0" json:"commission_balance"`
	PaidAt            *int64    `json:"paid_at"`
	CreatedAt         time.Time `json:"created_at"`
	UpdatedAt         time.Time `json:"updated_at"`
}

Order is a v2_order row. Its fields and tags match the kernel model without its relations, which the native routes never load, so answers are the same.

func (Order) TableName

func (Order) TableName() string

TableName is the adopted kernel table.

type OrderList

type OrderList struct {
	Total int64       `json:"total"`
	List  []OrderView `json:"list"`
}

OrderList is a page of orders and how many match.

type OrderView

type OrderView struct {
	Order
	User *Buyer    `json:"user,omitempty"`
	Plan *PlanName `json:"plan,omitempty"`
}

OrderView is an order as the list and detail routes answer it, as the kernel's service.OrderView: the order's columns, its plan's id and name, and for an administrator its buyer's id and e-mail. A plan or buyer that no longer exists is left out.

type PlanGroup

type PlanGroup struct {
	PlanID  uint
	GroupID uint
}

PlanGroup is a row of kapi_plan_subscription_group_v1: a subscription group a plan grants.

func (PlanGroup) TableName

func (PlanGroup) TableName() string

TableName is the kernel view.

type PlanName

type PlanName struct {
	ID   uint   `gorm:"primaryKey" json:"id"`
	Name string `json:"name"`
}

PlanName is a row of kapi_plan_name_v1: a plan's id and name, which an order answer shows as its plan.

func (PlanName) TableName

func (PlanName) TableName() string

TableName is the kernel view.

type Service

type Service struct {
	// Open returns the package's storage connection, on which the adopted
	// tables and the granted views are visible.
	Open func(ctx context.Context) (*gorm.DB, error)
	// Subscriber is the kernel's KernelSubscriber; without it the route
	// that completes an order has no native handler and stays legacy.
	Subscriber Subscriber
	// Now defaults to time.Now.
	Now func() time.Time
}

Service holds what the native routes need.

func (*Service) AdminCancelOrder

func (s *Service) AdminCancelOrder(ctx context.Context, request pluginhostsdk.NativeRequest) (pluginhostsdk.NativeResponse, error)

AdminCancelOrder is POST /api/v2/admin/orders/:id/cancel.

func (*Service) AdminCoupons

AdminCoupons is GET /api/v2/admin/coupon: every coupon, newest first, with an unlimited use count shown as -1 and the creation time in Unix seconds.

func (*Service) AdminCreateCoupon

func (s *Service) AdminCreateCoupon(ctx context.Context, request pluginhostsdk.NativeRequest) (pluginhostsdk.NativeResponse, error)

AdminCreateCoupon is POST /api/v2/admin/coupon. A coupon starts now and ends in 30 days unless the request says otherwise.

func (*Service) AdminDeleteCoupon

func (s *Service) AdminDeleteCoupon(ctx context.Context, request pluginhostsdk.NativeRequest) (pluginhostsdk.NativeResponse, error)

AdminDeleteCoupon is DELETE /api/v2/admin/coupon/:id.

func (*Service) AdminMarkOrderPaid

func (s *Service) AdminMarkOrderPaid(ctx context.Context, request pluginhostsdk.NativeRequest) (pluginhostsdk.NativeResponse, error)

AdminMarkOrderPaid is POST /api/v2/admin/orders/:id/paid: the order is marked paid, then completed, as the kernel's handler does.

func (*Service) AdminOrder

AdminOrder is GET /api/v2/admin/orders/:id: the order with its plan and buyer.

func (*Service) AdminOrderStats

AdminOrderStats is GET /api/v2/admin/orders/stats. Today starts at midnight UTC.

func (*Service) AdminOrders

AdminOrders is GET /api/v2/admin/orders: every order, newest first unless sort and order say otherwise (the columns of OrderSortColumns), each with its plan and buyer, filtered by buyer, status, type, trade number or part of the buyer's e-mail. A filter that does not parse filters by what strconv returns, as in the kernel.

func (*Service) AdminUpdateOrderStatus

func (s *Service) AdminUpdateOrderStatus(ctx context.Context, request pluginhostsdk.NativeRequest) (pluginhostsdk.NativeResponse, error)

AdminUpdateOrderStatus is PUT /api/v2/admin/orders/:id/status. Setting "completed" this way grants nothing, as in the kernel.

func (*Service) CheckCoupon

CheckCoupon is POST /api/v2/user/coupon/check: whether a code is usable now. Coupons apply to every plan.

func (*Service) Handlers

func (s *Service) Handlers() map[string]pluginhostsdk.NativeHandler

Handlers returns the native handlers by route id.

func (*Service) SaveOrder

SaveOrder is POST /api/v2/user/order/save: the caller orders a plan for a period, optionally with a coupon. An order for the plan the caller holds is a renewal, for another plan an upgrade, else a new purchase.

func (*Service) UserOrder

UserOrder is GET /api/v2/user/order/:id: the caller's own order with its plan. Another user's order is not found, as an unknown one.

func (*Service) UserOrders

UserOrders is GET /api/v2/user/order: the caller's own orders, newest first, each with its plan. A request with no caller lists nothing.

type Subscriber

type Subscriber interface {
	ApplyEntitlement(ctx context.Context, in *kernelsubscriberv1.ApplyEntitlementRequest, opts ...grpc.CallOption) (*kernelsubscriberv1.ApplyEntitlementResponse, error)
}

Subscriber is the part of KernelSubscriber the native routes call.

Jump to

Keyboard shortcuts

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