Shopware field mappings
This document maps UCP response/request fields to the Shopware data that
UCP To Shopware Field Mappings
This document maps UCP response/request fields to the Shopware data that currently backs them. It focuses on production runtime behavior and calls out test-only conformance behavior explicitly where relevant.
1. Discovery Profile
Source: UcpProfileBuilder.
| UCP field | Shopware source | Notes |
|---|---|---|
ucp.version | ucp_sales_channel_config.ucp_version | Defaults to current UCP version for the Sales Channel. |
ucp.services[].transport | ucp_sales_channel_config.enabled_transports | REST, MCP, A2A and Embedded are included only if enabled. |
ucp.services[].endpoint | Current Sales Channel domain URL + transport path | Example: {domain}/ucp/v1, {domain}/ucp/mcp. |
ucp.capabilities | ucp_sales_channel_config.enabled_capabilities + CapabilityRegistry | Capability metadata is provided by registered UcpCapability services. |
ucp.payment_handlers | UcpPaymentHandlerRegistry::describeForSalesChannel() | Each registered payment handler contributes descriptors and instrument types. |
ucp.supported_versions | SupportedVersionsRegistry | Version-pinned well-known profile URLs. |
signing_keys[] | ucp_signing_key.public_jwk | Only publishable active/retiring public JWKs are exposed. |
2. Platform Profile And Negotiation
| UCP concept | Shopware source | Notes |
|---|---|---|
| Platform profile URI | UCP-Agent: profile="..." | Parsed by UcpAgentHeader. |
| Platform allowlist | ucp_sales_channel_config.platform_allowlist | Enforced while fetching profiles. |
| Negotiated capabilities | Business enabled_capabilities intersected with platform ucp.capabilities | Stored in UcpRequestContext. |
| Protocol version | Platform profile ucp.version matched against current/historical versions | Unsupported versions reject before controllers. |
3. Catalog Product Mapping
Source: ProductMapper.
| UCP field | Shopware source | Notes |
|---|---|---|
product.id | SalesChannelProductEntity.productNumber, fallback id | UCP-facing product IDs prefer the merchant SKU/product number. |
product.title | Translated product name, fallback product name | Uses Shopware translation fallback. |
product.description.plain | Translated product description stripped of HTML | Omitted when no description exists. |
product.brand | Product manufacturer translated name | Omitted when no manufacturer exists. |
product.media[].url | Product media URLs | Emitted with type: image. |
variant.id | Product/variant product number, fallback UUID | Same ID policy as product. |
variant.sku | product.productNumber | Business-assigned stock/SKU identifier. |
variant.title | Translated product/variant name | |
variant.description.plain | Translated description stripped of HTML | |
variant.price.amount | CalculatedPrice.unitPrice * 100 | Minor units. |
variant.price.currency | Sales Channel context currency ISO code | |
variant.availability.available | availableStock > 0 | |
variant.availability.status | in_stock or out_of_stock | Based on available stock. |
variant.availability.available_quantity | availableStock | |
variant.inputs[].id | UCP product ID | Used for lookup correlation. |
variant.inputs[].match | Static exact | Current lookup implementation returns exact matches. |
4. Catalog Request Mapping
Source: CatalogController, SearchCatalogTool, LookupProductsTool,
GetProductTool, ProductIdentifierResolver.
| UCP input | Shopware target | Notes |
|---|---|---|
search.query | Store API product search search query | Uses ProductSearchRoute. |
search.filters.price.min/max | DAL range filter on product price | UCP minor units converted to major-unit float. |
search.filters.category_id | DAL categoryIds filter | |
search.cursor | CursorCodec state | HMAC signed, TTL-bound and query-fingerprint-bound. |
lookup.ids[] | Product UUID or product number | Non-UUIDs are matched against productNumber. |
get_product.id | Product UUID or product number | Returns single product detail response. |
Cart/checkout line_items[].item.id | Product UUID resolved through ProductIdentifierResolver | Accepts product number/SKU or UUID. |
5. Cart Mapping
Source: CartMapper.
| UCP field | Shopware source | Notes |
|---|---|---|
cart.id | Cart.token | UCP cart/checkout session ID is the Shopware cart token. |
cart.line_items[] | Shopware cart non-promotion line items | Promotion line items are surfaced through discounts. |
line_items[].id | Shopware cart line item ID | |
line_items[].item.id | Line item payload productNumber, fallback referencedId, fallback line item ID | Keeps UCP-visible item IDs stable. |
line_items[].item.title | Line item label | |
line_items[].item.price | Unit price in minor units | Duplicated as legacy price.amount. |
line_items[].quantity | Line item quantity | |
line_items[].price.amount | Unit price in minor units | Legacy compatibility. |
line_items[].line_total.amount | Total line price in minor units | Legacy compatibility. |
line_items[].totals[] | Unit/line total breakdown | Emits subtotal and total. |
cart.currency | Sales Channel context currency ISO code | |
cart.totals[].subtotal | CartPrice.positionPrice * 100 | Minor units. |
cart.totals[].tax | Calculated tax amount * 100 | Minor units. |
cart.totals[].discount | Sum of promotion line item totals * 100 | Negative value. |
cart.totals[].total | CartPrice.totalPrice * 100 | Minor units. |
cart.context.address_country | Shipping location country ISO | |
cart.context.address_region | Shipping location country state short code | Optional. |
cart.context.postal_code | Shipping address ZIP | Optional. |
cart.context.currency | Sales Channel context currency ISO code | |
cart.context.language | Sales Channel context language ID | Shopware UUID. |
cart.messages[] | Shopware cart errors | Promotion errors are mapped separately by DiscountMapper. |
cart.expires_at | Computed now + 24h | Shopware carts do not have a fixed TTL. |
cart.continue_url | Optional controller-provided continue URL | Checkout uses ContinueUrlBuilder. |
6. Cart Request Mapping
Source: CartController.
| UCP input | Shopware target | Notes |
|---|---|---|
line_items[].item.id | LineItemFactoryRegistry product referencedId | UCP ID is resolved to Shopware UUID first. |
line_items[].quantity | Shopware product line item quantity | Defaults to 1 when omitted. |
Update existing line_items[].id | CartItemUpdateRoute item ID | Existing line item quantity is changed. |
New line item without id | CartItemAddRoute | |
| Removed line item in full update | CartItemRemoveRoute | Cart update treats submitted list as desired state. |
discounts.codes[] | Promotion placeholder line items | Spec path; dedicated /carts/{id}/discounts remains as shortcut. |
7. Checkout Mapping
Source: CheckoutMapper, CheckoutController.
| UCP field | Shopware source | Notes |
|---|---|---|
checkout.id | Cart token | Same ID as cart/session token. |
checkout.status | CheckoutStatusResolver from cart/order state | Values include incomplete, ready, escalation, completed, canceled. |
checkout.line_items | Same as cart line item mapping | Delegates to CartMapper. |
checkout.currency | Sales Channel context currency | Delegates to CartMapper. |
checkout.totals | Cart totals | Delegates to CartMapper. |
checkout.messages | Checkout/cart status messages | Built by CheckoutStatusResolver. |
checkout.continue_url | ContinueUrlBuilder | Usually storefront checkout confirmation URL with cart token. |
checkout.links | Empty list currently | Reserved for policy/help links. |
checkout.buyer.email | Sales Channel customer email when customer is attached | Guest checkout may create synthetic buyer data at complete time. |
checkout.buyer.first_name | Sales Channel customer first name | |
checkout.buyer.last_name | Sales Channel customer last name | |
checkout.buyer.consent | ConsentStore snapshot | Only when Buyer Consent extension is negotiated. |
checkout.fulfillment | FulfillmentMapper::fromCart() | Only when Fulfillment extension is negotiated. |
checkout.available_instruments[] | AvailableInstrumentResolver | Intersects platform-accepted instruments with Shopware payment handlers. |
checkout.payment.instruments[] | Same as available_instruments[] | Added for SDK/conformance compatibility. |
checkout.order_id | Order ID after complete | Present when order was placed. |
checkout.order.id | Order ID after complete | Compatibility shape for official conformance suite. |
checkout.order.permalink_url | Storefront order/account URL | Compatibility shape. |
checkout.attribution | AttributionExtractor from request | Echoes normalized attribution input. |
checkout.signals | SignalsExtractor from request | Only when request signature is verified. |
8. Checkout Request Mapping
| UCP input | Shopware target | Notes |
|---|---|---|
cart_id | Rebind SalesChannelContext and cart token | Converts an existing cart to checkout. |
line_items[] on create | Product line items added to a fresh cart | Ignored when cart_id is provided. |
line_items[] on update | Existing line item quantities or new line items | Uses CartItemUpdateRoute and CartItemAddRoute. |
buyer on complete | GuestCustomerProvisioner | Creates guest customer if no customer is attached. |
payment.instruments[0].handler_id | UcpPaymentHandlerRegistry::get() | Falls back to first handler if omitted/unmatched. |
payment.instruments[0].credential | Payment handler prepareInstrument() | Handler-specific. |
fulfillment | FulfillmentMapper::resolveSelection() | Selects a Shopware shipping method when ID is a real Shopware UUID. |
discounts.codes[] | Promotion placeholders or conformance helpers in test mode | Production uses Shopware promotion processing. |
ap2.checkout_mandate | AP2 mandate verifier | Required when AP2 was negotiated. |
ap2.payment_mandate or credential token | AP2 payment mandate verifier | Used by AP2 plugin. |
9. Discount Mapping
Source: DiscountMapper.
| UCP field | Shopware source | Notes |
|---|---|---|
discounts.applied[].title | Promotion line item label | |
discounts.applied[].code | Promotion payload code | Omitted for automatic promotions. |
discounts.applied[].amount | Absolute promotion line item total * 100 | Positive discount amount. |
discounts.applied[].automatic | No code present | |
discounts.applied[].method | Static across | |
discounts.applied[].priority | Static 1 | |
discounts.applied[].allocations[].path | Promotion composition target IDs | Best-effort JSONPath. |
messages[] for rejected codes | Shopware promotion cart errors | Mapped to UCP discount error codes. |
Conformance-only discount codes such as 10OFF, WELCOME20 and FIXED500
are active only with UCP_CONFORMANCE_MODE=1.
10. Fulfillment Mapping
Source: FulfillmentMapper.
| UCP field | Shopware source | Notes |
|---|---|---|
fulfillment.methods[].id | Current Shopware shipping method ID | |
fulfillment.methods[].method_type | Static shipping | |
fulfillment.methods[].name | Shipping method translated name | |
fulfillment.methods[].line_item_ids[] | Delivery position identifiers | |
fulfillment.methods[].destinations[].id | Shipping method ID + _destination | Production Shopware single-address stream. |
fulfillment.methods[].destinations[].address | Delivery location shipping address | Includes country, region, postal code, city and street when available. |
fulfillment.methods[].groups[].id | Shipping method ID + _default | |
fulfillment.methods[].groups[].options[] | Active shipping methods for Sales Channel | Alternative method prices are estimated unless selected. |
options[].id | Shipping method ID | |
options[].title | Shipping method translated name | |
options[].price.amount | Selected delivery cost * 100, alternatives 0 estimated | |
options[].fulfillable_on | Delivery earliest date | |
options[].arrives_by | Delivery latest date |
11. Buyer Consent Mapping
Source: BuyerConsentMapper, ConsentStore.
| UCP input/output | Shopware source | Notes |
|---|---|---|
buyer.consent.terms_of_service | ucp_buyer_consent.consent_json | Supported field. |
buyer.consent.gdpr_data_processing | ucp_buyer_consent.consent_json | Supported field. |
buyer.consent.data_sharing_agent | ucp_buyer_consent.consent_json | Supported field. |
buyer.consent.marketing_email | ucp_buyer_consent.consent_json | Supported field. |
buyer.consent.marketing_sms | ucp_buyer_consent.consent_json | Supported field. |
buyer.consent.data_retention_extended | ucp_buyer_consent.consent_json | Supported field. |
buyer.consent.profiling | ucp_buyer_consent.consent_json | Supported field. |
granted_at | Incoming value or current timestamp | Set only when granted. |
denied_at | Incoming value or current timestamp | Set on denials. |
scope, jurisdiction, basis, policy_version | Incoming passthrough | Whitelisted optional metadata. |
Unknown consent fields are ignored.
12. Loyalty Mapping
Source: LoyaltyAggregator.
| UCP field | Shopware source | Notes |
|---|---|---|
loyalty[] | Tagged ucp.loyalty_provider services | Empty unless a plugin/provider contributes loyalty data. |
13. Order Mapping
Source: OrderMapper, OrderController.
| UCP field | Shopware source | Notes |
|---|---|---|
order.id | OrderEntity.id | Shopware UUID. |
order.checkout_id | Order custom field ucp_checkout_id, fallback order ID | Set when UCP completes checkout. |
order.order_number | OrderEntity.orderNumber | |
order.status | Order state machine technical name | Mapped for common states. |
order.created_at | Order date time | RFC 3339/ATOM. |
order.permalink_url | Storefront base + deep link when available | Fallback account order URL. |
order.currency | Order currency ISO code | |
order.line_items[].id | Order line item ID | |
order.line_items[].item.id | Order line item payload productNumber, fallback referenced/product ID | Mirrors cart item ID behavior. |
order.line_items[].item.title | Order line item label | |
order.line_items[].item.price | Unit price * 100 | Minor units. |
order.line_items[].quantity.original | Ordered quantity | |
order.line_items[].quantity.total | Current quantity | |
order.line_items[].quantity.fulfilled | Currently 0 unless fulfillment event state is known | |
order.line_items[].totals[] | Order line item price/tax totals | Minor units. |
order.totals[].subtotal | OrderEntity.positionPrice * 100 | |
order.totals[].tax | Calculated tax amount * 100 | |
order.totals[].total | OrderEntity.amountTotal * 100 | |
order.buyer.email | OrderCustomer.email | |
order.buyer.first_name | OrderCustomer.firstName | |
order.buyer.last_name | OrderCustomer.lastName | |
order.fulfillment.expectations[] | Order deliveries | Includes line item references, shipping dates and destination when known. |
order.fulfillment.events[] | Delivery state shipped or conformance order update extras | Production events currently come from Shopware delivery state. |
order.adjustments[] | Conformance order update extras | Persistent adjustment ledger is currently test-mode only. |
14. Payment And Tokenization Mapping
| UCP field | Shopware source | Notes |
|---|---|---|
ucp.payment_handlers | UcpPaymentHandlerRegistry descriptors | One or more handlers per registered handler name. |
available_instruments[].id | Payment handler descriptor ID | |
available_instruments[].handler_id | Same handler descriptor ID | Used in complete-checkout requests. |
available_instruments[].type | Handler instrument type, e.g. invoice | |
complete.payment.instruments[].handler_id | Lookup in UcpPaymentHandlerRegistry | Falls back to first handler if absent. |
complete.payment.instruments[].credential | Passed to UcpPaymentHandlerInterface::prepareInstrument() | Handler-specific credential preparation. |
/ucp/v1/tokenize.credential | Passed to handler tokenize() | Only handlers with tokenization support respond. |
/ucp/v1/tokenize.binding.checkout_id | Validated request binding | Accepted for spec compatibility. |
15. OAuth Identity Mapping
| UCP/OAuth concept | Shopware source | Notes |
|---|---|---|
| OAuth issuer | Sales Channel domain URL | OAuthDiscoveryController. |
| Authorization endpoint | /ucp/v1/oauth/authorize | Renders login/consent flow. |
| Token endpoint | /ucp/v1/oauth/token | Issues access and refresh tokens. |
| OAuth client | ucp_oauth_client | Auto-registration/lookup repository. |
| Authorization code | ucp_oauth_auth_code | League OAuth2 Server repository. |
| Access token | ucp_oauth_access_token | JWT signed with Sales Channel UCP key. |
| Refresh token | ucp_oauth_refresh_token | Rotated by League server. |
private_key_jwt replay | ucp_oauth_client_assertion | Requires unique jti. |
| OAuth user subject | Shopware customer ID | Stored through UcpUserEntity. |
| Scopes | UcpScopeRegistry | Advertised in metadata and enforced by UcpScopeGuard. |
16. AP2 Mapping
Source: SwagUcpAp2Mandates.
| AP2/UCP field | Shopware source | Notes |
|---|---|---|
| Business AP2 capability | Profile mutation via UcpEvents::PROFILE_BUILT | Plugin must be active and capability enabled. |
ap2.merchant_authorization | Active Sales Channel UCP signing key | Detached JWS over JCS checkout response without ap2. |
ap2.checkout_mandate | Platform request payload | Compact JWS or SD-JWT VC + KB-JWT. |
ap2.payment_mandate | ap2.payment_mandate or payment credential token | Compact JWS or SD-JWT VC + KB-JWT. |
| Mandate issuer | Negotiated platform profile URI | Exact issuer pinning. |
| Mandate public key | Platform profile signing_keys or SD-JWT cnf.jwk | Depends on format. |
| Mandate replay log | swag_ucp_ap2_mandate_log | Stores mandate IDs, user subject and payment mandate ID, not full PII payload. |
| Intent items | Current Shopware cart line items | Matches both Shopware UUIDs and product numbers. |
| Intent total/currency | Current Shopware cart total and currency | Minor-unit comparison with small rounding tolerance. |
| Intent merchant | Sales Channel domain host | Exact host match. |
17. Conformance Test Mode Mapping
Only active when all conditions are true:
APP_ENV != prod
UCP_CONFORMANCE_MODE=1Additional optional secret:
UCP_SIMULATION_SECRET=<secret>In this mode only, Shopware accepts upstream conformance assumptions such as
request-signature: test, profile="...", flower-shop product IDs, fixed
test discount codes, deterministic fulfillment destinations and simulation
shipping webhooks.
These mappings are isolated test bridge behavior and must not be used to infer production Shopware business logic.