1801 lines
57 KiB
Go
1801 lines
57 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"git.k6n.net/mats/go-cart-actor/internal/ucp"
|
|
)
|
|
|
|
const (
|
|
ucpVersion = "2026-04-08"
|
|
publicHost = "https://shop.tornberg.me"
|
|
localEdge = "http://localhost:8080"
|
|
keyID = "k6n-ecdsa-2026"
|
|
customerURL = publicHost + "/.well-known/ucp/schemas/shopping/customer.json"
|
|
authURL = publicHost + "/.well-known/ucp/schemas/shopping/authentication.json"
|
|
paymentURL = publicHost + "/.well-known/ucp/schemas/payments/processor_tokenizer.json"
|
|
openapiURL = publicHost + "/.well-known/ucp/openapi/shopping-rest.openapi.json"
|
|
)
|
|
|
|
func main() {
|
|
repoRoot, err := filepath.Abs("..")
|
|
if err != nil {
|
|
failf("resolve repo root: %v", err)
|
|
}
|
|
|
|
profileJSON := mustMarshalJSON(buildProfile())
|
|
customerJSON := mustValidateJSON(customerSchemaJSON)
|
|
authJSON := mustValidateJSON(authenticationSchemaJSON)
|
|
paymentJSON := mustValidateJSON(processorTokenizerSchemaJSON)
|
|
openapiJSON := mustValidateJSON(shoppingRESTOpenAPIJSON)
|
|
|
|
mustWrite(filepath.Join(repoRoot, "docs", "ucp-profile.json"), profileJSON)
|
|
mustWrite(filepath.Join(repoRoot, "docs", "ucp", "schemas", "shopping", "customer.json"), customerJSON)
|
|
mustWrite(filepath.Join(repoRoot, "docs", "ucp", "schemas", "shopping", "authentication.json"), authJSON)
|
|
mustWrite(filepath.Join(repoRoot, "docs", "ucp", "schemas", "payments", "processor_tokenizer.json"), paymentJSON)
|
|
mustWrite(filepath.Join(repoRoot, "docs", "ucp", "openapi", "shopping-rest.openapi.json"), openapiJSON)
|
|
mustWrite(filepath.Join(repoRoot, "backoffice", "deploy", "k8s", "38-ucp-profile.generated.yaml"),
|
|
buildConfigMapYAML(profileJSON, customerJSON, authJSON, paymentJSON, openapiJSON))
|
|
}
|
|
|
|
func failf(format string, args ...any) {
|
|
fmt.Fprintf(os.Stderr, format+"\n", args...)
|
|
os.Exit(1)
|
|
}
|
|
|
|
func mustMarshalJSON(v any) []byte {
|
|
out, err := json.MarshalIndent(v, "", " ")
|
|
if err != nil {
|
|
failf("marshal json: %v", err)
|
|
}
|
|
out = append(out, '\n')
|
|
return out
|
|
}
|
|
|
|
func mustValidateJSON(raw string) []byte {
|
|
data := []byte(strings.TrimSpace(raw) + "\n")
|
|
var v any
|
|
if err := json.Unmarshal(data, &v); err != nil {
|
|
failf("invalid generated json: %v", err)
|
|
}
|
|
out, err := json.MarshalIndent(v, "", " ")
|
|
if err != nil {
|
|
failf("re-marshal generated json: %v", err)
|
|
}
|
|
out = append(out, '\n')
|
|
return out
|
|
}
|
|
|
|
func mustWrite(path string, data []byte) {
|
|
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
|
failf("mkdir %s: %v", filepath.Dir(path), err)
|
|
}
|
|
if err := os.WriteFile(path, data, 0o644); err != nil {
|
|
failf("write %s: %v", path, err)
|
|
}
|
|
}
|
|
|
|
func buildProfile() ucp.ProfileData {
|
|
return ucp.ProfileData{
|
|
UCP: ucp.Profile{
|
|
Version: ucpVersion,
|
|
Business: ucp.BusinessInfo{
|
|
Name: "K6N E-Commerce",
|
|
Description: "Swedish multi-country e-commerce platform — cart, checkout, order, catalog, and fulfillment services",
|
|
Domain: "shop.tornberg.me",
|
|
},
|
|
Services: map[string][]ucp.ServiceBinding{
|
|
"dev.ucp.shopping": {
|
|
{
|
|
Version: ucpVersion,
|
|
Spec: "https://ucp.dev/2026-04-08/specification/overview",
|
|
Transport: "rest",
|
|
Schema: openapiURL,
|
|
Endpoint: publicHost + "/ucp/v1",
|
|
},
|
|
{
|
|
Version: ucpVersion,
|
|
Spec: "https://ucp.dev/2026-04-08/specification/overview",
|
|
Transport: "mcp",
|
|
Schema: "https://ucp.dev/2026-04-08/services/shopping/mcp.openrpc.json",
|
|
Endpoint: publicHost + "/cart-mcp",
|
|
},
|
|
{
|
|
Version: ucpVersion,
|
|
Spec: "https://ucp.dev/2026-04-08/specification/overview",
|
|
Transport: "mcp",
|
|
Schema: "https://ucp.dev/2026-04-08/services/shopping/mcp.openrpc.json",
|
|
Endpoint: publicHost + "/order-mcp",
|
|
},
|
|
{
|
|
Version: ucpVersion,
|
|
Spec: "https://ucp.dev/2026-04-08/specification/overview",
|
|
Transport: "mcp",
|
|
Schema: "https://ucp.dev/2026-04-08/services/shopping/mcp.openrpc.json",
|
|
Endpoint: publicHost + "/promotions-mcp",
|
|
},
|
|
},
|
|
},
|
|
Capabilities: map[string][]ucp.CapabilityDecl{
|
|
"dev.ucp.shopping.cart": {{
|
|
Version: ucpVersion,
|
|
Spec: "https://ucp.dev/2026-04-08/specification/cart",
|
|
Schema: "https://ucp.dev/2026-04-08/schemas/shopping/cart.json",
|
|
Description: "Pre-checkout cart management — create, read, update cart contents, manage items, vouchers, and user identity",
|
|
Operations: []ucp.OpDef{
|
|
{Method: "POST", Path: "/carts"},
|
|
{Method: "GET", Path: "/carts/{id}"},
|
|
{Method: "PUT", Path: "/carts/{id}"},
|
|
{Method: "POST", Path: "/carts/{id}/cancel"},
|
|
},
|
|
}},
|
|
"dev.ucp.shopping.checkout": {{
|
|
Version: ucpVersion,
|
|
Spec: "https://ucp.dev/2026-04-08/specification/checkout",
|
|
Schema: "https://ucp.dev/2026-04-08/schemas/shopping/checkout.json",
|
|
Description: "Purchase session orchestration — initiate, update, complete, and cancel checkout sessions with Adyen and Klarna payment integration",
|
|
Operations: []ucp.OpDef{
|
|
{Method: "POST", Path: "/checkout-sessions"},
|
|
{Method: "GET", Path: "/checkout-sessions/{id}"},
|
|
{Method: "PUT", Path: "/checkout-sessions/{id}"},
|
|
{Method: "POST", Path: "/checkout-sessions/{id}/complete"},
|
|
{Method: "POST", Path: "/checkout-sessions/{id}/cancel"},
|
|
},
|
|
}},
|
|
"dev.ucp.shopping.order": {{
|
|
Version: ucpVersion,
|
|
Spec: "https://ucp.dev/2026-04-08/specification/order",
|
|
Schema: "https://ucp.dev/2026-04-08/schemas/shopping/order.json",
|
|
Description: "Order lifecycle — view order state, cancel, fulfill, complete, request returns, and issue refunds",
|
|
Operations: []ucp.OpDef{
|
|
{Method: "GET", Path: "/orders/{id}"},
|
|
{Method: "POST", Path: "/orders/{id}/cancel"},
|
|
{Method: "POST", Path: "/orders/{id}/fulfillments"},
|
|
{Method: "POST", Path: "/orders/{id}/returns"},
|
|
{Method: "POST", Path: "/orders/{id}/refunds"},
|
|
},
|
|
}},
|
|
"dev.ucp.shopping.catalog.search": {{
|
|
Version: ucpVersion,
|
|
Spec: "https://ucp.dev/2026-04-08/specification/catalog",
|
|
Schema: "https://ucp.dev/2026-04-08/schemas/shopping/catalog_search.json",
|
|
Description: "Full-text product search with BM25 and ColBERT relevance ranking, facet filtering, and autocomplete suggestions",
|
|
Operations: []ucp.OpDef{
|
|
{Method: "GET", Path: "/catalog/feed"},
|
|
{Method: "POST", Path: "/catalog/search"},
|
|
},
|
|
}},
|
|
"dev.ucp.shopping.catalog.lookup": {{
|
|
Version: ucpVersion,
|
|
Spec: "https://ucp.dev/2026-04-08/specification/catalog",
|
|
Schema: "https://ucp.dev/2026-04-08/schemas/shopping/catalog_lookup.json",
|
|
Description: "Retrieve products by SKU or id, including full PDP details and related metadata",
|
|
Operations: []ucp.OpDef{
|
|
{Method: "POST", Path: "/catalog/lookup"},
|
|
{Method: "POST", Path: "/catalog/product"},
|
|
},
|
|
}},
|
|
"dev.ucp.shopping.customer": {{
|
|
Version: ucpVersion,
|
|
Spec: "https://ucp.dev/2026-04-08/specification/identity-linking",
|
|
Schema: customerURL,
|
|
Description: "Customer profile management — view and update profile information, manage stored addresses with default shipping/billing designations, and identity linking across carts, checkouts, and orders",
|
|
Operations: []ucp.OpDef{
|
|
{Method: "POST", Path: "/customers"},
|
|
{Method: "GET", Path: "/customers/{id}"},
|
|
{Method: "PUT", Path: "/customers/{id}"},
|
|
{Method: "DELETE", Path: "/customers/{id}"},
|
|
{Method: "POST", Path: "/customers/{id}/addresses"},
|
|
{Method: "PUT", Path: "/customers/{id}/addresses/{addressId}"},
|
|
{Method: "DELETE", Path: "/customers/{id}/addresses/{addressId}"},
|
|
},
|
|
}},
|
|
"dev.ucp.shopping.authentication": {{
|
|
Version: ucpVersion,
|
|
Spec: "https://ucp.dev/2026-04-08/specification/authentication",
|
|
Schema: authURL,
|
|
Description: "Customer authentication — email+password registration and login with HMAC-signed session cookies, logout, current-customer lookup, email verification, and password reset. Failed logins and reset requests are rate-limited.",
|
|
Operations: []ucp.OpDef{
|
|
{Method: "POST", Path: "/auth/register"},
|
|
{Method: "POST", Path: "/auth/login"},
|
|
{Method: "POST", Path: "/auth/logout"},
|
|
{Method: "GET", Path: "/auth/me"},
|
|
{Method: "POST", Path: "/auth/verify-request"},
|
|
{Method: "POST", Path: "/auth/verify"},
|
|
{Method: "POST", Path: "/auth/reset-request"},
|
|
{Method: "POST", Path: "/auth/reset"},
|
|
},
|
|
}},
|
|
"dev.ucp.common.identity_linking": {{
|
|
Version: ucpVersion,
|
|
Spec: "https://ucp.dev/2026-04-08/specification/identity-linking",
|
|
Schema: "https://ucp.dev/2026-04-08/schemas/common/identity_linking.json",
|
|
Description: "Identity linking — automatically links carts, checkouts, and orders to customer profiles via the /customers/{id} REST endpoints. Carts are linked when userId is set; checkouts are linked when customerId is provided; orders are linked on checkout completion.",
|
|
}},
|
|
"dev.ucp.shopping.discount": {{
|
|
Version: ucpVersion,
|
|
Extends: "dev.ucp.shopping.checkout",
|
|
Spec: "https://ucp.dev/2026-04-08/specification/discount",
|
|
Schema: "https://ucp.dev/2026-04-08/schemas/shopping/discount.json",
|
|
Description: "Promotion and discount code evaluation — percentage discounts, fixed amounts, volume discounts with progress nudges",
|
|
}},
|
|
"dev.ucp.shopping.fulfillment": {{
|
|
Version: ucpVersion,
|
|
Extends: "dev.ucp.shopping.checkout",
|
|
Spec: "https://ucp.dev/2026-04-08/specification/fulfillment",
|
|
Schema: "https://ucp.dev/2026-04-08/schemas/shopping/fulfillment.json",
|
|
Description: "Shipping and delivery options — carrier selection, pickup points, delivery pricing",
|
|
}},
|
|
"dev.ucp.shopping.buyer_consent": {{
|
|
Version: ucpVersion,
|
|
Extends: "dev.ucp.shopping.checkout",
|
|
Spec: "https://ucp.dev/2026-04-08/specification/buyer-consent",
|
|
Schema: "https://ucp.dev/2026-04-08/schemas/shopping/buyer_consent.json",
|
|
Description: "Explicit consent capture — order confirmation viewed, terms acceptance tracking",
|
|
}},
|
|
},
|
|
PaymentHandlers: map[string][]ucp.PaymentHandlerDecl{
|
|
"com.adyen.checkout": {{
|
|
ID: "adyen",
|
|
Version: ucpVersion,
|
|
Spec: "https://docs.adyen.com/api-explorer",
|
|
Schema: paymentURL,
|
|
Description: "Adyen payment gateway — credit/debit card, PayPal, Swish, and local payment methods via Adyen Web Drop-in",
|
|
}},
|
|
"com.klarna.payments": {{
|
|
ID: "klarna",
|
|
Version: ucpVersion,
|
|
Spec: "https://docs.klarna.com/api/payments",
|
|
Schema: paymentURL,
|
|
Description: "Klarna Payments — Pay Now, Pay Later, Slice It (installments) via Klarna API",
|
|
}},
|
|
},
|
|
},
|
|
SigningKeys: []ucp.SigningKey{{
|
|
Kid: keyID,
|
|
Kty: "EC",
|
|
Crv: "P-256",
|
|
X: "pnPksDSSMcNgUYT4--Z65LRXanpM0xKNYGyBc66-ajk",
|
|
Y: "Esoux-Cmy-C84ty5VUAdEpoDyNfWMeaAlHKGo-FjiQ",
|
|
Alg: "ES256",
|
|
}},
|
|
}
|
|
}
|
|
|
|
func buildConfigMapYAML(profile, customer, auth, payment, openapi []byte) []byte {
|
|
var b strings.Builder
|
|
b.WriteString("# Code generated by go run ./cmd/ucp-artifacts; DO NOT EDIT.\n")
|
|
b.WriteString("apiVersion: v1\n")
|
|
b.WriteString("kind: ConfigMap\n")
|
|
b.WriteString("metadata:\n")
|
|
b.WriteString(" name: ucp-profile-generated\n")
|
|
b.WriteString(" namespace: ecommerce\n")
|
|
b.WriteString("data:\n")
|
|
writeBlock(&b, "profile.json", profile)
|
|
writeBlock(&b, "customer.json", customer)
|
|
writeBlock(&b, "authentication.json", auth)
|
|
writeBlock(&b, "processor_tokenizer.json", payment)
|
|
writeBlock(&b, "shopping-rest.openapi.json", openapi)
|
|
return []byte(b.String())
|
|
}
|
|
|
|
func writeBlock(b *strings.Builder, key string, data []byte) {
|
|
b.WriteString(" " + key + ": |\n")
|
|
for _, line := range strings.Split(strings.TrimRight(string(data), "\n"), "\n") {
|
|
b.WriteString(" " + line + "\n")
|
|
}
|
|
}
|
|
|
|
const customerSchemaJSON = `
|
|
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "https://shop.tornberg.me/.well-known/ucp/schemas/shopping/customer.json",
|
|
"name": "dev.ucp.shopping.customer",
|
|
"title": "Customer Profile",
|
|
"description": "Customer profile with stored addresses and identity linking across carts, checkouts, and orders.",
|
|
"version": "2026-04-08",
|
|
"type": "object",
|
|
"required": ["id", "addresses", "orders", "emailVerified"],
|
|
"properties": {
|
|
"id": { "type": "string", "description": "Base62-encoded profile identifier." },
|
|
"name": { "type": "string" },
|
|
"email": { "type": "string", "format": "email" },
|
|
"phone": { "type": "string" },
|
|
"language": { "type": "string", "description": "BCP-47 language tag." },
|
|
"currency": { "type": "string", "description": "ISO 4217 currency code." },
|
|
"avatarUrl": { "type": "string", "format": "uri" },
|
|
"emailVerified": { "type": "boolean" },
|
|
"addresses": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/$defs/address" }
|
|
},
|
|
"orders": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/$defs/orderRef" }
|
|
}
|
|
},
|
|
"$defs": {
|
|
"address": {
|
|
"type": "object",
|
|
"required": ["id", "addressLine1", "city", "zip", "country"],
|
|
"properties": {
|
|
"id": { "type": "integer", "minimum": 0 },
|
|
"label": { "type": "string" },
|
|
"fullName": { "type": "string" },
|
|
"addressLine1": { "type": "string" },
|
|
"addressLine2": { "type": "string" },
|
|
"city": { "type": "string" },
|
|
"state": { "type": "string" },
|
|
"zip": { "type": "string" },
|
|
"country": { "type": "string", "description": "ISO 3166-1 alpha-2 country code." },
|
|
"phone": { "type": "string" },
|
|
"isDefaultShipping": { "type": "boolean" },
|
|
"isDefaultBilling": { "type": "boolean" }
|
|
}
|
|
},
|
|
"orderRef": {
|
|
"type": "object",
|
|
"required": ["orderReference"],
|
|
"properties": {
|
|
"orderReference": { "type": "string" },
|
|
"status": { "type": "string" }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
`
|
|
|
|
const authenticationSchemaJSON = `
|
|
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "https://shop.tornberg.me/.well-known/ucp/schemas/shopping/authentication.json",
|
|
"name": "dev.ucp.shopping.authentication",
|
|
"title": "Customer Authentication",
|
|
"description": "Password-based customer authentication capability with signed session cookies, email verification, password reset, and identity-linking helpers.",
|
|
"version": "2026-04-08",
|
|
"type": "object",
|
|
"properties": {
|
|
"status": {
|
|
"type": "string",
|
|
"enum": ["ok", "sent", "verified"]
|
|
},
|
|
"error": {
|
|
"type": "string"
|
|
},
|
|
"customer": {
|
|
"$ref": "https://shop.tornberg.me/.well-known/ucp/schemas/shopping/customer.json"
|
|
},
|
|
"emailVerified": {
|
|
"type": "boolean"
|
|
}
|
|
},
|
|
"additionalProperties": true,
|
|
"$defs": {
|
|
"registerRequest": {
|
|
"type": "object",
|
|
"required": ["email", "password"],
|
|
"properties": {
|
|
"email": { "type": "string", "format": "email" },
|
|
"password": { "type": "string", "minLength": 8 },
|
|
"name": { "type": "string" },
|
|
"phone": { "type": "string" }
|
|
}
|
|
},
|
|
"loginRequest": {
|
|
"type": "object",
|
|
"required": ["email", "password"],
|
|
"properties": {
|
|
"email": { "type": "string", "format": "email" },
|
|
"password": { "type": "string", "minLength": 8 }
|
|
}
|
|
},
|
|
"tokenRequest": {
|
|
"type": "object",
|
|
"required": ["token"],
|
|
"properties": {
|
|
"token": { "type": "string" }
|
|
}
|
|
},
|
|
"resetRequest": {
|
|
"type": "object",
|
|
"required": ["email"],
|
|
"properties": {
|
|
"email": { "type": "string", "format": "email" }
|
|
}
|
|
},
|
|
"resetCompleteRequest": {
|
|
"type": "object",
|
|
"required": ["token", "password"],
|
|
"properties": {
|
|
"token": { "type": "string" },
|
|
"password": { "type": "string", "minLength": 8 }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
`
|
|
|
|
const processorTokenizerSchemaJSON = `
|
|
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "https://shop.tornberg.me/.well-known/ucp/schemas/payments/processor_tokenizer.json",
|
|
"name": "dev.ucp.processor_tokenizer",
|
|
"title": "Processor Tokenizer Payment Handler",
|
|
"description": "Payment handler that tokenizes a buyer-supplied instrument through a payment processor (Adyen, Klarna) and returns a processor token used to authorize the checkout.",
|
|
"version": "2026-04-08",
|
|
"type": "object",
|
|
"required": ["id", "instrument"],
|
|
"properties": {
|
|
"id": { "type": "string", "description": "Handler instance id distinguishing multiple processor configurations." },
|
|
"instrument": {
|
|
"type": "object",
|
|
"required": ["type"],
|
|
"properties": {
|
|
"type": {
|
|
"type": "string",
|
|
"enum": ["card", "wallet", "bank_transfer", "invoice", "installment"],
|
|
"description": "Instrument class presented by the buyer."
|
|
},
|
|
"scheme": { "type": "string", "description": "Card or wallet scheme, e.g. visa, mastercard, swish, klarna." }
|
|
}
|
|
},
|
|
"paymentToken": {
|
|
"type": "string",
|
|
"description": "Opaque processor token issued after tokenizing the instrument; authorizes the checkout session."
|
|
},
|
|
"processor": {
|
|
"type": "string",
|
|
"enum": ["adyen", "klarna"],
|
|
"description": "Backing payment processor that issued the token."
|
|
}
|
|
}
|
|
}
|
|
`
|
|
|
|
const shoppingRESTOpenAPIJSON = `
|
|
{
|
|
"openapi": "3.1.0",
|
|
"info": {
|
|
"title": "K6N UCP REST API",
|
|
"version": "2026-04-08",
|
|
"description": "Authoritative REST contract for the K6N UCP surface served from /.well-known/ucp."
|
|
},
|
|
"servers": [
|
|
{ "url": "https://shop.tornberg.me", "description": "Production edge" },
|
|
{ "url": "http://localhost:8080", "description": "Local compose edge" }
|
|
],
|
|
"paths": {
|
|
"/.well-known/ucp": {
|
|
"get": {
|
|
"summary": "Fetch the UCP business profile",
|
|
"responses": {
|
|
"200": {
|
|
"description": "UCP profile JSON",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/UCPProfile" }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/carts/": {
|
|
"post": {
|
|
"summary": "Create a cart",
|
|
"requestBody": {
|
|
"required": false,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CreateCartRequest" }
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"201": {
|
|
"description": "Cart created",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CartResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"500": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/carts/{id}": {
|
|
"get": {
|
|
"summary": "Get a cart",
|
|
"parameters": [{ "$ref": "#/components/parameters/Id" }],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Cart state",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CartResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"404": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
},
|
|
"put": {
|
|
"summary": "Replace cart contents",
|
|
"parameters": [{ "$ref": "#/components/parameters/Id" }],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/UpdateCartRequest" }
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Updated cart",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CartResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"500": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/carts/{id}/cancel": {
|
|
"post": {
|
|
"summary": "Cancel a cart",
|
|
"parameters": [{ "$ref": "#/components/parameters/Id" }],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Cleared cart",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CartResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"500": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/checkout-sessions/": {
|
|
"post": {
|
|
"summary": "Create a checkout session",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CreateCheckoutRequest" }
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"201": {
|
|
"description": "Checkout session created",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CheckoutResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"500": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/checkout-sessions/{id}": {
|
|
"get": {
|
|
"summary": "Get a checkout session",
|
|
"parameters": [{ "$ref": "#/components/parameters/Id" }],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Checkout session state",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CheckoutResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"404": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
},
|
|
"put": {
|
|
"summary": "Update a checkout session",
|
|
"parameters": [{ "$ref": "#/components/parameters/Id" }],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/UpdateCheckoutRequest" }
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Updated checkout session",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CheckoutResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"500": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/checkout-sessions/{id}/complete": {
|
|
"post": {
|
|
"summary": "Complete a checkout session",
|
|
"parameters": [{ "$ref": "#/components/parameters/Id" }],
|
|
"requestBody": {
|
|
"required": false,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CompleteCheckoutRequest" }
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Completed checkout session",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CheckoutResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"404": { "$ref": "#/components/responses/Error" },
|
|
"500": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/checkout-sessions/{id}/cancel": {
|
|
"post": {
|
|
"summary": "Cancel a checkout session",
|
|
"parameters": [{ "$ref": "#/components/parameters/Id" }],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Cancelled checkout session",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CheckoutResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"404": { "$ref": "#/components/responses/Error" },
|
|
"500": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/orders/{id}": {
|
|
"get": {
|
|
"summary": "Get an order",
|
|
"parameters": [{ "$ref": "#/components/parameters/Id" }],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Order state",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/OrderResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"404": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/orders/{id}/cancel": {
|
|
"post": {
|
|
"summary": "Cancel an order",
|
|
"parameters": [{ "$ref": "#/components/parameters/Id" }],
|
|
"requestBody": {
|
|
"required": false,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"reason": { "type": "string" }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Cancelled order",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/OrderResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"404": { "$ref": "#/components/responses/Error" },
|
|
"422": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/orders/{id}/fulfillments": {
|
|
"post": {
|
|
"summary": "Create a fulfillment",
|
|
"parameters": [{ "$ref": "#/components/parameters/Id" }],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"carrier": { "type": "string" },
|
|
"trackingNumber": { "type": "string" },
|
|
"trackingUri": { "type": "string" },
|
|
"lines": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"required": ["reference", "quantity"],
|
|
"properties": {
|
|
"reference": { "type": "string" },
|
|
"quantity": { "type": "integer" }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Updated order",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/OrderResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"404": { "$ref": "#/components/responses/Error" },
|
|
"422": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/orders/{id}/returns": {
|
|
"post": {
|
|
"summary": "Request a return",
|
|
"parameters": [{ "$ref": "#/components/parameters/Id" }],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"reason": { "type": "string" },
|
|
"lines": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"required": ["reference", "quantity"],
|
|
"properties": {
|
|
"reference": { "type": "string" },
|
|
"quantity": { "type": "integer" }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Updated order",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/OrderResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"404": { "$ref": "#/components/responses/Error" },
|
|
"422": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/orders/{id}/refunds": {
|
|
"post": {
|
|
"summary": "Issue a refund",
|
|
"parameters": [{ "$ref": "#/components/parameters/Id" }],
|
|
"requestBody": {
|
|
"required": false,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"amount": { "type": "integer" },
|
|
"reason": { "type": "string" }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Updated order",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/OrderResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"404": { "$ref": "#/components/responses/Error" },
|
|
"422": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/customers": {
|
|
"post": {
|
|
"summary": "Create a customer profile",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CreateCustomerRequest" }
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"201": {
|
|
"description": "Created customer profile",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CustomerResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"500": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/customers/{id}": {
|
|
"get": {
|
|
"summary": "Get a customer profile",
|
|
"parameters": [{ "$ref": "#/components/parameters/Id" }],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Customer profile",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CustomerResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"404": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
},
|
|
"put": {
|
|
"summary": "Update a customer profile",
|
|
"parameters": [{ "$ref": "#/components/parameters/Id" }],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/UpdateCustomerRequest" }
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Updated customer profile",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CustomerResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"404": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
},
|
|
"delete": {
|
|
"summary": "Anonymize a customer profile",
|
|
"parameters": [{ "$ref": "#/components/parameters/Id" }],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Anonymized customer profile",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CustomerResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"404": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/customers/{id}/addresses": {
|
|
"post": {
|
|
"summary": "Add a customer address",
|
|
"parameters": [{ "$ref": "#/components/parameters/Id" }],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/AddressInput" }
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Updated customer profile",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CustomerResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"404": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/customers/{id}/addresses/{addressId}": {
|
|
"put": {
|
|
"summary": "Update a customer address",
|
|
"parameters": [
|
|
{ "$ref": "#/components/parameters/Id" },
|
|
{ "$ref": "#/components/parameters/AddressId" }
|
|
],
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/AddressInput" }
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Updated customer profile",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CustomerResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"404": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
},
|
|
"delete": {
|
|
"summary": "Delete a customer address",
|
|
"parameters": [
|
|
{ "$ref": "#/components/parameters/Id" },
|
|
{ "$ref": "#/components/parameters/AddressId" }
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Updated customer profile",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CustomerResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"404": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/auth/register": {
|
|
"post": {
|
|
"summary": "Register a customer account",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/RegisterRequest" }
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"201": {
|
|
"description": "Registered customer",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CustomerResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"409": { "$ref": "#/components/responses/Error" },
|
|
"500": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/auth/login": {
|
|
"post": {
|
|
"summary": "Log in a customer",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/LoginRequest" }
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Authenticated customer",
|
|
"headers": {
|
|
"Set-Cookie": {
|
|
"schema": { "type": "string" },
|
|
"description": "HTTP-only session cookie."
|
|
}
|
|
},
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CustomerResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"401": { "$ref": "#/components/responses/Error" },
|
|
"403": { "$ref": "#/components/responses/Error" },
|
|
"429": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/auth/logout": {
|
|
"post": {
|
|
"summary": "Log out the current customer",
|
|
"responses": {
|
|
"200": {
|
|
"description": "Logout acknowledged",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/StatusResponse" }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/auth/me": {
|
|
"get": {
|
|
"summary": "Get the current authenticated customer",
|
|
"responses": {
|
|
"200": {
|
|
"description": "Authenticated customer",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CustomerResponse" }
|
|
}
|
|
}
|
|
},
|
|
"401": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/auth/verify-request": {
|
|
"post": {
|
|
"summary": "Request a verification email",
|
|
"responses": {
|
|
"200": {
|
|
"description": "Verification email requested",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/StatusResponse" }
|
|
}
|
|
}
|
|
},
|
|
"401": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/auth/verify": {
|
|
"post": {
|
|
"summary": "Verify an email address",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/TokenRequest" }
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Email verified",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/StatusResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/auth/reset-request": {
|
|
"post": {
|
|
"summary": "Request a password reset",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/ResetRequest" }
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Password reset requested",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/StatusResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" },
|
|
"429": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/auth/reset": {
|
|
"post": {
|
|
"summary": "Complete a password reset",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/ResetCompleteRequest" }
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Password reset complete",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/StatusResponse" }
|
|
}
|
|
}
|
|
},
|
|
"400": { "$ref": "#/components/responses/Error" }
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/catalog/feed": {
|
|
"get": {
|
|
"summary": "Fetch the catalog feed",
|
|
"parameters": [
|
|
{
|
|
"name": "limit",
|
|
"in": "query",
|
|
"schema": { "type": "integer", "minimum": 1, "maximum": 200, "default": 40 }
|
|
},
|
|
{
|
|
"name": "cursor",
|
|
"in": "query",
|
|
"schema": { "type": "string" }
|
|
}
|
|
],
|
|
"responses": {
|
|
"200": {
|
|
"description": "Catalog feed page",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CatalogFeedResponse" }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/catalog/lookup": {
|
|
"post": {
|
|
"summary": "Lookup products by id or SKU",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"ids": {
|
|
"type": "array",
|
|
"items": { "type": "string" }
|
|
},
|
|
"skus": {
|
|
"type": "array",
|
|
"items": { "type": "string" }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Lookup result",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CatalogListResponse" }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/catalog/product": {
|
|
"post": {
|
|
"summary": "Fetch a single product",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": { "type": "string" },
|
|
"sku": { "type": "string" }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Product result",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CatalogObjectResponse" }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"/ucp/v1/catalog/search": {
|
|
"post": {
|
|
"summary": "Search the catalog",
|
|
"requestBody": {
|
|
"required": true,
|
|
"content": {
|
|
"application/json": {
|
|
"schema": {
|
|
"type": "object",
|
|
"properties": {
|
|
"query": { "type": "string" },
|
|
"filters": { "type": "object", "additionalProperties": true },
|
|
"cursor": { "type": "string" },
|
|
"limit": { "type": "integer", "minimum": 1, "maximum": 200 }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"responses": {
|
|
"200": {
|
|
"description": "Search result",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/CatalogFeedResponse" }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"components": {
|
|
"parameters": {
|
|
"Id": {
|
|
"name": "id",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": { "type": "string" }
|
|
},
|
|
"AddressId": {
|
|
"name": "addressId",
|
|
"in": "path",
|
|
"required": true,
|
|
"schema": { "type": "integer", "minimum": 0 }
|
|
}
|
|
},
|
|
"responses": {
|
|
"Error": {
|
|
"description": "Error response",
|
|
"content": {
|
|
"application/json": {
|
|
"schema": { "$ref": "#/components/schemas/Error" }
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"schemas": {
|
|
"UCPProfile": {
|
|
"type": "object",
|
|
"properties": {
|
|
"ucp": { "type": "object", "additionalProperties": true },
|
|
"signing_keys": {
|
|
"type": "array",
|
|
"items": { "type": "object", "additionalProperties": true }
|
|
}
|
|
}
|
|
},
|
|
"Error": {
|
|
"type": "object",
|
|
"required": ["error"],
|
|
"properties": {
|
|
"error": { "type": "string" }
|
|
}
|
|
},
|
|
"StatusResponse": {
|
|
"type": "object",
|
|
"required": ["status"],
|
|
"properties": {
|
|
"status": { "type": "string" }
|
|
}
|
|
},
|
|
"VoucherInput": {
|
|
"type": "object",
|
|
"required": ["code"],
|
|
"properties": {
|
|
"code": { "type": "string" },
|
|
"value": { "type": "integer" }
|
|
}
|
|
},
|
|
"CartItemInput": {
|
|
"type": "object",
|
|
"required": ["sku"],
|
|
"properties": {
|
|
"sku": { "type": "string" },
|
|
"quantity": { "type": "integer", "minimum": 0 },
|
|
"name": { "type": "string" },
|
|
"price": { "type": "integer" },
|
|
"taxRate": { "type": "number" },
|
|
"image": { "type": "string" },
|
|
"storeId": { "type": "string" },
|
|
"customFields": {
|
|
"type": "object",
|
|
"additionalProperties": { "type": "string" }
|
|
},
|
|
"children": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/components/schemas/CartItemInput" }
|
|
}
|
|
}
|
|
},
|
|
"CreateCartRequest": {
|
|
"type": "object",
|
|
"properties": {
|
|
"items": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/components/schemas/CartItemInput" }
|
|
}
|
|
}
|
|
},
|
|
"UpdateCartRequest": {
|
|
"type": "object",
|
|
"properties": {
|
|
"items": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/components/schemas/CartItemInput" }
|
|
},
|
|
"vouchers": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/components/schemas/VoucherInput" }
|
|
},
|
|
"userId": { "type": "string" },
|
|
"country": { "type": "string" }
|
|
}
|
|
},
|
|
"Totals": {
|
|
"type": "object",
|
|
"required": ["totalIncVat", "totalExVat", "totalVat", "currency"],
|
|
"properties": {
|
|
"totalIncVat": { "type": "integer" },
|
|
"totalExVat": { "type": "integer" },
|
|
"totalVat": { "type": "integer" },
|
|
"currency": { "type": "string" },
|
|
"discount": { "type": "integer" }
|
|
}
|
|
},
|
|
"CartItem": {
|
|
"type": "object",
|
|
"required": ["sku", "quantity", "unitPrice", "totalPrice", "taxRate"],
|
|
"properties": {
|
|
"sku": { "type": "string" },
|
|
"quantity": { "type": "integer" },
|
|
"name": { "type": "string" },
|
|
"unitPrice": { "type": "integer" },
|
|
"totalPrice": { "type": "integer" },
|
|
"taxRate": { "type": "integer" },
|
|
"image": { "type": "string" },
|
|
"itemId": { "type": "integer" },
|
|
"customFields": {
|
|
"type": "object",
|
|
"additionalProperties": { "type": "string" }
|
|
}
|
|
}
|
|
},
|
|
"CartResponse": {
|
|
"type": "object",
|
|
"required": ["id", "totals", "status"],
|
|
"properties": {
|
|
"id": { "type": "string" },
|
|
"items": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/components/schemas/CartItem" }
|
|
},
|
|
"totals": { "$ref": "#/components/schemas/Totals" },
|
|
"status": { "type": "string" }
|
|
}
|
|
},
|
|
"CreateCheckoutRequest": {
|
|
"type": "object",
|
|
"properties": {
|
|
"cartId": { "type": "string" },
|
|
"items": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/components/schemas/CartItemInput" }
|
|
},
|
|
"line_items": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/components/schemas/CartItemInput" }
|
|
},
|
|
"country": { "type": "string" },
|
|
"currency": { "type": "string" },
|
|
"customerId": { "type": "string" }
|
|
}
|
|
},
|
|
"DeliveryInput": {
|
|
"type": "object",
|
|
"required": ["provider"],
|
|
"properties": {
|
|
"provider": { "type": "string" },
|
|
"itemIds": {
|
|
"type": "array",
|
|
"items": { "type": "integer" }
|
|
}
|
|
}
|
|
},
|
|
"ContactInput": {
|
|
"type": "object",
|
|
"properties": {
|
|
"email": { "type": "string", "format": "email" },
|
|
"phone": { "type": "string" },
|
|
"name": { "type": "string" },
|
|
"postalCode": { "type": "string" }
|
|
}
|
|
},
|
|
"PickupPointInput": {
|
|
"type": "object",
|
|
"required": ["deliveryId", "id"],
|
|
"properties": {
|
|
"deliveryId": { "type": "integer" },
|
|
"id": { "type": "string" },
|
|
"name": { "type": "string" },
|
|
"address": { "type": "string" },
|
|
"city": { "type": "string" },
|
|
"zip": { "type": "string" }
|
|
}
|
|
},
|
|
"UpdateCheckoutRequest": {
|
|
"type": "object",
|
|
"properties": {
|
|
"delivery": { "$ref": "#/components/schemas/DeliveryInput" },
|
|
"contact": { "$ref": "#/components/schemas/ContactInput" },
|
|
"pickupPoint": { "$ref": "#/components/schemas/PickupPointInput" }
|
|
}
|
|
},
|
|
"CompleteCheckoutRequest": {
|
|
"type": "object",
|
|
"properties": {
|
|
"paymentToken": { "type": "string" },
|
|
"provider": { "type": "string" },
|
|
"currency": { "type": "string" },
|
|
"country": { "type": "string" },
|
|
"customerId": { "type": "string" }
|
|
}
|
|
},
|
|
"PickupPointResponse": {
|
|
"type": "object",
|
|
"required": ["id"],
|
|
"properties": {
|
|
"id": { "type": "string" },
|
|
"name": { "type": "string" },
|
|
"address": { "type": "string" },
|
|
"city": { "type": "string" },
|
|
"zip": { "type": "string" }
|
|
}
|
|
},
|
|
"DeliveryResponse": {
|
|
"type": "object",
|
|
"required": ["id", "provider", "price", "items"],
|
|
"properties": {
|
|
"id": { "type": "integer" },
|
|
"provider": { "type": "string" },
|
|
"price": { "type": "integer" },
|
|
"items": {
|
|
"type": "array",
|
|
"items": { "type": "integer" }
|
|
},
|
|
"pickupPoint": { "$ref": "#/components/schemas/PickupPointResponse" }
|
|
}
|
|
},
|
|
"ContactResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"email": { "type": "string", "format": "email" },
|
|
"phone": { "type": "string" },
|
|
"name": { "type": "string" },
|
|
"postalCode": { "type": "string" }
|
|
}
|
|
},
|
|
"PaymentResponse": {
|
|
"type": "object",
|
|
"required": ["id", "provider", "amount", "currency"],
|
|
"properties": {
|
|
"id": { "type": "string" },
|
|
"provider": { "type": "string" },
|
|
"amount": { "type": "integer" },
|
|
"currency": { "type": "string" },
|
|
"status": { "type": "string" }
|
|
}
|
|
},
|
|
"CheckoutResponse": {
|
|
"type": "object",
|
|
"required": ["id", "cartId", "status", "totals"],
|
|
"properties": {
|
|
"id": { "type": "string" },
|
|
"cartId": { "type": "string" },
|
|
"status": { "type": "string" },
|
|
"items": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/components/schemas/CartItem" }
|
|
},
|
|
"totals": { "$ref": "#/components/schemas/Totals" },
|
|
"deliveries": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/components/schemas/DeliveryResponse" }
|
|
},
|
|
"contact": { "$ref": "#/components/schemas/ContactResponse" },
|
|
"orderId": { "type": "string" },
|
|
"payments": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/components/schemas/PaymentResponse" }
|
|
}
|
|
}
|
|
},
|
|
"OrderResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"id": { "type": "string" },
|
|
"orderId": { "type": "string" },
|
|
"status": { "type": "string" },
|
|
"currency": { "type": "string" },
|
|
"country": { "type": "string" },
|
|
"locale": { "type": "string" },
|
|
"lines": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"additionalProperties": true
|
|
}
|
|
},
|
|
"payments": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"additionalProperties": true
|
|
}
|
|
},
|
|
"fulfillments": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"additionalProperties": true
|
|
}
|
|
},
|
|
"returns": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"additionalProperties": true
|
|
}
|
|
}
|
|
},
|
|
"additionalProperties": true
|
|
},
|
|
"CreateCustomerRequest": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": { "type": "string" },
|
|
"email": { "type": "string", "format": "email" },
|
|
"phone": { "type": "string" },
|
|
"language": { "type": "string" },
|
|
"currency": { "type": "string" },
|
|
"avatarUrl": { "type": "string", "format": "uri" }
|
|
}
|
|
},
|
|
"UpdateCustomerRequest": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": { "type": "string" },
|
|
"email": { "type": "string", "format": "email" },
|
|
"phone": { "type": "string" },
|
|
"language": { "type": "string" },
|
|
"currency": { "type": "string" },
|
|
"avatarUrl": { "type": "string", "format": "uri" }
|
|
}
|
|
},
|
|
"AddressInput": {
|
|
"type": "object",
|
|
"required": ["addressLine1", "city", "zip", "country"],
|
|
"properties": {
|
|
"label": { "type": "string" },
|
|
"fullName": { "type": "string" },
|
|
"addressLine1": { "type": "string" },
|
|
"addressLine2": { "type": "string" },
|
|
"city": { "type": "string" },
|
|
"state": { "type": "string" },
|
|
"zip": { "type": "string" },
|
|
"country": { "type": "string" },
|
|
"phone": { "type": "string" },
|
|
"isDefaultShipping": { "type": "boolean" },
|
|
"isDefaultBilling": { "type": "boolean" }
|
|
}
|
|
},
|
|
"AddressResponse": {
|
|
"type": "object",
|
|
"required": ["id", "addressLine1", "city", "zip", "country"],
|
|
"properties": {
|
|
"id": { "type": "integer" },
|
|
"label": { "type": "string" },
|
|
"fullName": { "type": "string" },
|
|
"addressLine1": { "type": "string" },
|
|
"addressLine2": { "type": "string" },
|
|
"city": { "type": "string" },
|
|
"state": { "type": "string" },
|
|
"zip": { "type": "string" },
|
|
"country": { "type": "string" },
|
|
"phone": { "type": "string" },
|
|
"isDefaultShipping": { "type": "boolean" },
|
|
"isDefaultBilling": { "type": "boolean" }
|
|
}
|
|
},
|
|
"OrderRef": {
|
|
"type": "object",
|
|
"required": ["orderReference"],
|
|
"properties": {
|
|
"orderReference": { "type": "string" },
|
|
"status": { "type": "string" }
|
|
}
|
|
},
|
|
"CustomerResponse": {
|
|
"type": "object",
|
|
"required": ["id", "addresses", "orders", "emailVerified"],
|
|
"properties": {
|
|
"id": { "type": "string" },
|
|
"name": { "type": "string" },
|
|
"email": { "type": "string", "format": "email" },
|
|
"phone": { "type": "string" },
|
|
"language": { "type": "string" },
|
|
"currency": { "type": "string" },
|
|
"avatarUrl": { "type": "string", "format": "uri" },
|
|
"emailVerified": { "type": "boolean" },
|
|
"addresses": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/components/schemas/AddressResponse" }
|
|
},
|
|
"orders": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/components/schemas/OrderRef" }
|
|
}
|
|
}
|
|
},
|
|
"RegisterRequest": {
|
|
"type": "object",
|
|
"required": ["email", "password"],
|
|
"properties": {
|
|
"email": { "type": "string", "format": "email" },
|
|
"password": { "type": "string", "minLength": 8 },
|
|
"name": { "type": "string" },
|
|
"phone": { "type": "string" }
|
|
}
|
|
},
|
|
"LoginRequest": {
|
|
"type": "object",
|
|
"required": ["email", "password"],
|
|
"properties": {
|
|
"email": { "type": "string", "format": "email" },
|
|
"password": { "type": "string", "minLength": 8 }
|
|
}
|
|
},
|
|
"TokenRequest": {
|
|
"type": "object",
|
|
"required": ["token"],
|
|
"properties": {
|
|
"token": { "type": "string" }
|
|
}
|
|
},
|
|
"ResetRequest": {
|
|
"type": "object",
|
|
"required": ["email"],
|
|
"properties": {
|
|
"email": { "type": "string", "format": "email" }
|
|
}
|
|
},
|
|
"ResetCompleteRequest": {
|
|
"type": "object",
|
|
"required": ["token", "password"],
|
|
"properties": {
|
|
"token": { "type": "string" },
|
|
"password": { "type": "string", "minLength": 8 }
|
|
}
|
|
},
|
|
"CatalogObject": {
|
|
"type": "object",
|
|
"additionalProperties": true
|
|
},
|
|
"CatalogListResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"products": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/components/schemas/CatalogObject" }
|
|
}
|
|
},
|
|
"additionalProperties": true
|
|
},
|
|
"CatalogObjectResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"product": { "$ref": "#/components/schemas/CatalogObject" }
|
|
},
|
|
"additionalProperties": true
|
|
},
|
|
"CatalogFeedResponse": {
|
|
"type": "object",
|
|
"properties": {
|
|
"products": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/components/schemas/CatalogObject" }
|
|
},
|
|
"cursor": { "type": "string" },
|
|
"hasNextPage": { "type": "boolean" },
|
|
"totalCount": { "type": "integer" }
|
|
},
|
|
"additionalProperties": true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
`
|