mirror of
https://github.com/hanzoai/commerce.git
synced 2026-10-30 15:08:42 +00:00
Four places still answered for Hanzo on another brand's host. - The org endpoint published the deployment's Square application for every brand. Those credentials are the default brand's account; any other brand now publishes Square, and the square provider, only with an account of its own (payment.SquareOwned). - The purchase doors bought a plan wherever the catalog is not on sale: subscribe/card, POST /subscriptions and a plan change answer 404 on a host whose brand Sells nothing, as the list and GetPlan already do. - The public catalog listed entries that name their brands under every brand whose category admits them. An entry now lists only under the brands it names, as the console scopes it, and with no ?brand the host's brand is the default rather than hanzo. - Zoo's identity origin is zoolabs.id: it replaces zoo.id, which is not Zoo's, in the brand table and in Zoo's return hosts. Co-authored-by: Hanzo Dev <[email protected]>
79 lines
2.8 KiB
Go
79 lines
2.8 KiB
Go
package payment
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/hanzoai/commerce/models/organization"
|
|
)
|
|
|
|
// SquarePublic is the PUBLIC Square Web Payments config the browser needs to
|
|
// tokenize a card for an org: the application id + location id + environment.
|
|
// Every field is public (Square exposes them to the client SDK) — no secret,
|
|
// no access token, no webhook key.
|
|
type SquarePublic struct {
|
|
ApplicationID string `json:"applicationId"`
|
|
LocationID string `json:"locationId"`
|
|
Environment string `json:"environment"` // "sandbox" | "production"
|
|
Live bool `json:"live"`
|
|
}
|
|
|
|
// SquarePublicConfig resolves the PUBLIC Square config for an org through the
|
|
// SINGLE test-mode authority (org.TestMode / SQUARE_ENVIRONMENT) and the same
|
|
// KMS-then-env fallback the charge path uses, so the app id the browser
|
|
// tokenizes with always matches the environment + access token commerce will
|
|
// vault/charge with.
|
|
//
|
|
// This is the ONE place that resolution lives: both the authenticated
|
|
// /v1/billing/settings handler and the public host→org tenant projection
|
|
// (/v1/commerce/tenant) call it, so a card form and its charge can never drift
|
|
// onto different Square applications.
|
|
func SquarePublicConfig(org *organization.Organization) SquarePublic {
|
|
// A nil org (an unauthenticated / no-org caller on the co-resident billing path) means
|
|
// "no per-org Square creds" — resolve from the env fallback below rather than nil-deref.
|
|
// A zero Organization is env-fallback-safe (TestMode reads env/!Live; Square is a value).
|
|
if org == nil {
|
|
org = &organization.Organization{}
|
|
}
|
|
useSandbox := org.TestMode()
|
|
env := org.SquareEnvironment()
|
|
|
|
sq := org.SquareConfig(useSandbox)
|
|
appID := sq.ApplicationId
|
|
locationID := sq.LocationId
|
|
|
|
// Env fallback (KMS disabled or no per-org Square creds — the common case
|
|
// for cloud orgs). The SAME useSandbox authority picks the sandbox vs
|
|
// production public vars, so the app id always matches `env`.
|
|
if appID == "" || locationID == "" {
|
|
appID = strings.TrimSpace(os.Getenv("SQUARE_APPLICATION_ID"))
|
|
locationID = strings.TrimSpace(os.Getenv("SQUARE_LOCATION_ID"))
|
|
if useSandbox {
|
|
if a := strings.TrimSpace(os.Getenv("SQUARE_SANDBOX_APPLICATION_ID")); a != "" {
|
|
appID = a
|
|
}
|
|
if l := strings.TrimSpace(os.Getenv("SQUARE_SANDBOX_LOCATION_ID")); l != "" {
|
|
locationID = l
|
|
}
|
|
}
|
|
}
|
|
|
|
return SquarePublic{
|
|
ApplicationID: appID,
|
|
LocationID: locationID,
|
|
Environment: env,
|
|
Live: org.Live,
|
|
}
|
|
}
|
|
|
|
// SquareOwned reports whether the org holds Square credentials of its own —
|
|
// the same test SquarePublicConfig makes before it falls back to the
|
|
// deployment's env credentials, which belong to the deployment's own brand.
|
|
func SquareOwned(org *organization.Organization) bool {
|
|
if org == nil {
|
|
return false
|
|
}
|
|
sq := org.SquareConfig(org.TestMode())
|
|
return sq.ApplicationId != "" && sq.LocationId != ""
|
|
}
|