mirror of
https://github.com/hanzoai/commerce.git
synced 2026-10-30 15:08:42 +00:00
Multi-tenant commerce and billing: orders, subscriptions, invoices, plans, usage metering and a credit ledger. One Go binary. MIT OR Apache-2.0. Claude-Session: https://claude.ai/code/session_01SAtaDFm8VDiWrhYHNNtxMw
68 lines
3.5 KiB
Go
68 lines
3.5 KiB
Go
package store
|
|
|
|
import (
|
|
"github.com/zap-proto/zip"
|
|
|
|
"github.com/hanzoai/commerce/middleware"
|
|
"github.com/hanzoai/commerce/models/store"
|
|
"github.com/hanzoai/commerce/util/permission"
|
|
"github.com/hanzoai/commerce/util/rest"
|
|
)
|
|
|
|
func Route(router *zip.Group, args ...zip.Handler) {
|
|
adminRequired := middleware.TokenRequired(permission.Admin)
|
|
publishedRequired := middleware.TokenRequired(permission.Admin, permission.Published)
|
|
namespaced := middleware.Namespace()
|
|
|
|
api := rest.New(store.Store{})
|
|
|
|
// Admin dashboard + the content storefront edge expect /store/current to return
|
|
// the caller org's store. getCurrent resolves the org FROM CONTEXT, so /current
|
|
// must run behind the same base auth gate (args = tokenRequired) that sets it —
|
|
// custom sub-routes do NOT inherit the base CRUD middleware (see util/rest.Route).
|
|
current := append(append([]zip.Handler{}, args...), getCurrent)
|
|
api.GET("/current", current...)
|
|
access := append(append([]zip.Handler{}, args...), getAccess)
|
|
api.GET("/access", access...)
|
|
api.POST("/:storeid/trial", adminRequired, namespaced, startTrial)
|
|
|
|
// Mint the org's least-privilege Published storefront read key (design
|
|
// path b). Admin-gated + org-bound; the returned token is stored in KMS and
|
|
// injected as HANZO_COMMERCE_STOREFRONT_TOKEN on the storefront.
|
|
api.POST("/token", adminRequired, namespaced, mintStorefrontToken)
|
|
|
|
// API for getting a full product/variant/bundle for a specific store
|
|
api.POST("/:storeid/authorize", publishedRequired, namespaced, authorize)
|
|
api.POST("/:storeid/authorize/:orderid", publishedRequired, namespaced, authorize)
|
|
api.POST("/:storeid/capture/:orderid", publishedRequired, namespaced, capture)
|
|
api.POST("/:storeid/charge", publishedRequired, namespaced, charge)
|
|
api.POST("/:storeid/paypal/pay", publishedRequired, namespaced, authorize)
|
|
api.POST("/:storeid/paypal/confirm/:payKey", publishedRequired, namespaced, confirm)
|
|
api.POST("/:storeid/paypal/cancel/:payKey", publishedRequired, namespaced, cancel)
|
|
|
|
// Support new checkout prefixed methods
|
|
api.POST("/:storeid/checkout/authorize", publishedRequired, namespaced, authorize)
|
|
api.POST("/:storeid/checkout/authorize/:orderid", publishedRequired, namespaced, authorize)
|
|
api.POST("/:storeid/checkout/capture/:orderid", publishedRequired, namespaced, capture)
|
|
api.POST("/:storeid/checkout/charge", publishedRequired, namespaced, charge)
|
|
api.POST("/:storeid/checkout/paypal/pay", publishedRequired, namespaced, authorize)
|
|
api.POST("/:storeid/checkout/paypal/confirm/:payKey", publishedRequired, namespaced, confirm)
|
|
api.POST("/:storeid/checkout/paypal/cancel/:payKey", publishedRequired, namespaced, cancel)
|
|
|
|
// API for getting a full product/variant/bundle for a specific store
|
|
api.GET("/:storeid/bundle/:key", publishedRequired, namespaced, getItem("bundle"))
|
|
api.GET("/:storeid/product/:key", publishedRequired, namespaced, getItem("product"))
|
|
api.GET("/:storeid/variant/:key", publishedRequired, namespaced, getItem("variant"))
|
|
|
|
// API for working with listings directly
|
|
api.GET("/:storeid/listing", publishedRequired, namespaced, listListing)
|
|
api.GET("/:storeid/listing/:key", publishedRequired, namespaced, getListing)
|
|
|
|
api.POST("/:storeid/listing/:key", adminRequired, namespaced, createListing)
|
|
api.PUT("/:storeid/listing/:key", adminRequired, namespaced, updateListing)
|
|
api.PATCH("/:storeid/listing/:key", adminRequired, namespaced, patchListing)
|
|
api.DELETE("/:storeid/listing/:key", adminRequired, namespaced, deleteListing)
|
|
|
|
api.Route(router, args...)
|
|
}
|