Developer guide

Diagrams

All the diagrams scattered across these pages, gathered in one place

6. Diagrams

All the diagrams scattered across these pages, gathered in one place for reference. They render directly in any markdown viewer that supports Mermaid (GitHub, GitLab, modern IDEs, …).

6.1 System overview

mermaid
flowchart LR
    subgraph Platform["AI commerce platform"]
        agent[Agent runtime<br/>ChatGPT / Gemini / Perplexity / …]
        agentProfile[Platform profile JSON]
    end

    subgraph Sim["UCP Simulator<br/>(this repo's simulator/)"]
        simUI[3-pane UI]
        simRunner[Scenario runner]
    end

    subgraph Shop["Shopware shop"]
        wellKnown["/.well-known/ucp"]
        ucpRoutes["/ucp/v1/* + /ucp/mcp"]
        caps[CapabilityRegistry]
        pay[PaymentHandlerRegistry]
        storeApi[Store-API]
        admin[Admin UI<br/>sw-settings-ucp]
        db[(Per-Sales-Channel<br/>UCP config + keys)]
    end

    agent <--> wellKnown
    agent <--> ucpRoutes
    simRunner <--> wellKnown
    simRunner <--> ucpRoutes
    wellKnown -.-> caps
    wellKnown -.-> pay
    wellKnown -.-> db
    ucpRoutes --> storeApi
    admin --> db

6.2 Per-request resolution

mermaid
flowchart TD
    A[HTTP request to /ucp/v1/*] --> B{Domain<br/>matches a<br/>SalesChannelDomain?}
    B -- no --> Z[404]
    B -- yes --> C[Resolve SalesChannelContext]
    C --> D{UCP active<br/>for this channel?}
    D -- no --> Z
    D -- yes --> E[Load ucp_sales_channel_config]
    E --> F{UCP-Agent<br/>header present?}
    F -- no --> Y[400]
    F -- yes --> G[Fetch + cache platform profile]
    G --> H[Compute capability intersection]
    H --> I{Required<br/>capabilities<br/>negotiated?}
    I -- no --> X[capabilities_incompatible response]
    I -- yes --> J[Dispatch to capability controller]
    J --> K[Delegate to Store-API]
    K --> L[Wrap response in UCP envelope]
    L --> M[200 OK]

6.3 Capability negotiation (intersection algorithm)

mermaid
flowchart LR
    A[Business capabilities] --> M{intersect by name}
    P[Platform capabilities] --> M
    M --> V{pick highest<br/>mutual version}
    V -- empty --> X[exclude]
    V -- non-empty --> N[include]
    N --> O{extends ≠ null?}
    O -- no --> R[result set]
    O -- yes --> O2{≥ 1 parent<br/>in result?}
    O2 -- yes --> R
    O2 -- no --> X
    X --> Q[loop: re-prune<br/>until stable]
    Q --> R

6.4 Discovery & happy-path checkout sequence

mermaid
sequenceDiagram
    participant Agent
    participant Shop as Shopware

    Agent->>Shop: GET /.well-known/ucp
    Shop-->>Agent: { ucp: { version, capabilities, payment_handlers }, signing_keys }
    Agent->>Agent: compute intersection vs platform profile

    Agent->>Shop: POST /ucp/v1/catalog/search<br/>UCP-Agent: profile="..."<br/>{ query }
    Shop-->>Agent: { products: [...] }

    Agent->>Shop: POST /ucp/v1/carts<br/>{ line_items: [...] }
    Shop-->>Agent: { id: cart_xyz, totals }

    Agent->>Shop: POST /ucp/v1/checkout-sessions<br/>{ cart_id: cart_xyz }
    Shop-->>Agent: { id: chk_xyz, status: "incomplete", payment_handlers }

    Agent->>Shop: POST /ucp/v1/checkout-sessions/chk_xyz/complete<br/>{ buyer, payment: { instruments: [...] } }
    Shop-->>Agent: 200 OK { order_id }

    Note over Shop: order state-machine transitions
    Shop->>Agent: POST {platform.webhook_url}<br/>+ RFC 9421 Signature
    Agent-->>Shop: 200 OK

6.5 OAuth PKCE flow (Identity Linking)

mermaid
sequenceDiagram
    participant Agent as Platform agent
    participant Buyer
    participant Shop as Shopware OAuth AS<br/>(per Sales Channel)

    Agent->>Shop: GET /.well-known/oauth-authorization-server
    Shop-->>Agent: { authorization_endpoint, token_endpoint, scopes_supported, code_challenge_methods_supported: ["S256"], authorization_response_iss_parameter_supported: true, ... }

    Agent->>Agent: generate code_verifier + code_challenge (S256)<br/>+ state

    Agent->>Buyer: open authorization URL (S256 PKCE, state, scopes)
    Buyer->>Shop: sign in & consent
    Shop-->>Agent: redirect (code, state, iss)
    Agent->>Agent: validate state + iss

    Agent->>Shop: POST /token (code + code_verifier)
    Shop-->>Agent: { access_token, refresh_token, scope }

    Agent->>Shop: GET /ucp/v1/orders/...  Authorization: Bearer ...
    Shop->>Shop: verify token (iss, aud, exp, scope, azp)
    Shop-->>Agent: 200 OK { … }

6.6 AP2 mandate flow

mermaid
sequenceDiagram
    participant Buyer
    participant Agent as Platform agent
    participant Wallet as User wallet
    participant Shop as Shopware<br/>(AP2 plugin loaded)

    Note over Shop: ap2_mandate negotiated → session security-locked
    Agent->>Shop: POST /ucp/v1/checkout-sessions { cart_id }
    Shop->>Shop: build checkout payload, JCS canonicalise (without ap2)<br/>sign with sales-channel ES256 key
    Shop-->>Agent: 200 OK { …, ap2: { merchant_authorization: "header..sig" } }

    Agent->>Agent: verify merchant_authorization against signing_keys[kid]

    Agent->>Wallet: please authorise this checkout
    Wallet-->>Agent: ap2.checkout_mandate (SD-JWT+KB)<br/>covering full checkout payload inc. merchant_authorization
    Agent->>Wallet: please authorise payment
    Wallet-->>Agent: payment_mandate (SD-JWT+KB)

    Agent->>Shop: POST /complete<br/>{ ap2: { checkout_mandate }, payment: { instruments: [{ credential: { token: payment_mandate } }] } }
    Shop->>Shop: verify mandates cover the exact checkout state
    Shop->>Shop: capture payment via PSP
    Shop-->>Agent: 200 OK { order_id }

6.7 Capability extension contract (plugins)

mermaid
flowchart LR
    subgraph Plugin[Your plugin]
        cap[YourCapability<br/>implements UcpCapability]
        ctrl[YourController<br/>routes under /ucp/v1/*]
        srv[services.xml]
    end

    subgraph Core[Shopware UCP core]
        pass[UcpCapabilityCompilerPass]
        reg[CapabilityRegistry]
        wk["/.well-known/ucp builder"]
        neg[NegotiationOrchestrator]
        admin[sw-settings-ucp module]
    end

    srv -- "ucp.capability tag" --> pass
    cap --> pass
    pass --> reg
    reg --> wk
    reg --> neg
    reg --> admin
    ctrl -.-> Core

6.8 Payment handler integration contract

mermaid
flowchart LR
    subgraph Plugin[Your payment plugin]
        ph[YourUcpHandler<br/>implements UcpPaymentHandlerInterface]
        psp[Existing PaymentHandlerInterface<br/>(unchanged)]
        srv[services.xml]
    end

    subgraph Core[Shopware UCP core]
        pass[UcpPaymentHandlerCompilerPass]
        reg[UcpPaymentHandlerRegistry]
        wk["/.well-known/ucp builder"]
        checkout[CheckoutController]
        proc[PaymentProcessor]
    end

    srv -- "ucp.payment_handler tag" --> pass
    ph --> pass
    pass --> reg
    reg --> wk
    checkout -- prepareInstrument() --> ph
    ph -- paymentMethodId + token --> proc
    proc --> psp

← Back to developer index · See also end-user docs