portage-ucp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +15 -0
- data/LICENSE +21 -0
- data/README.md +97 -0
- data/exe/portage-ucp-check +25 -0
- data/lib/portage/ucp/adapter.rb +58 -0
- data/lib/portage/ucp/authenticator.rb +26 -0
- data/lib/portage/ucp/capabilities/cart.rb +16 -0
- data/lib/portage/ucp/capabilities/catalog.rb +11 -0
- data/lib/portage/ucp/capabilities/checkout.rb +17 -0
- data/lib/portage/ucp/capabilities/identity_linking.rb +13 -0
- data/lib/portage/ucp/capabilities/order.rb +11 -0
- data/lib/portage/ucp/capability.rb +27 -0
- data/lib/portage/ucp/capability_negotiator.rb +40 -0
- data/lib/portage/ucp/capability_registry.rb +21 -0
- data/lib/portage/ucp/check.rb +96 -0
- data/lib/portage/ucp/configuration.rb +35 -0
- data/lib/portage/ucp/dispatcher.rb +39 -0
- data/lib/portage/ucp/errors.rb +12 -0
- data/lib/portage/ucp/manifest.rb +58 -0
- data/lib/portage/ucp/mcp/server.rb +83 -0
- data/lib/portage/ucp/observability.rb +31 -0
- data/lib/portage/ucp/payment_token_guard.rb +41 -0
- data/lib/portage/ucp/rack/manifest_endpoint.rb +49 -0
- data/lib/portage/ucp/rack/webhook_endpoint.rb +54 -0
- data/lib/portage/ucp/rate_limiter.rb +27 -0
- data/lib/portage/ucp/resolver.rb +133 -0
- data/lib/portage/ucp/schema_validator.rb +53 -0
- data/lib/portage/ucp/support/amounts.rb +43 -0
- data/lib/portage/ucp/support/api_error.rb +39 -0
- data/lib/portage/ucp/support/checkout_state.rb +42 -0
- data/lib/portage/ucp/support/http_client.rb +54 -0
- data/lib/portage/ucp/support/idempotency.rb +26 -0
- data/lib/portage/ucp/support/line_item_status.rb +44 -0
- data/lib/portage/ucp/support/not_found.rb +25 -0
- data/lib/portage/ucp/support/token_exchange.rb +43 -0
- data/lib/portage/ucp/support/totals.rb +31 -0
- data/lib/portage/ucp/value_objects.rb +186 -0
- data/lib/portage/ucp/version.rb +5 -0
- data/lib/portage/ucp/wire_envelope.rb +25 -0
- data/lib/portage/ucp.rb +44 -0
- data/schemas/2026-04-08/schemas/capability.json +70 -0
- data/schemas/2026-04-08/schemas/payment_handler.json +67 -0
- data/schemas/2026-04-08/schemas/service.json +190 -0
- data/schemas/2026-04-08/schemas/shopping/cart.json +134 -0
- data/schemas/2026-04-08/schemas/shopping/catalog_lookup.json +207 -0
- data/schemas/2026-04-08/schemas/shopping/catalog_search.json +64 -0
- data/schemas/2026-04-08/schemas/shopping/checkout.json +131 -0
- data/schemas/2026-04-08/schemas/shopping/discount.json +148 -0
- data/schemas/2026-04-08/schemas/shopping/fulfillment.json +154 -0
- data/schemas/2026-04-08/schemas/shopping/order.json +113 -0
- data/schemas/2026-04-08/schemas/shopping/payment.json +16 -0
- data/schemas/2026-04-08/schemas/shopping/types/adjustment.json +69 -0
- data/schemas/2026-04-08/schemas/shopping/types/amount.json +8 -0
- data/schemas/2026-04-08/schemas/shopping/types/attribution.json +11 -0
- data/schemas/2026-04-08/schemas/shopping/types/available_payment_instrument.json +22 -0
- data/schemas/2026-04-08/schemas/shopping/types/business_fulfillment_config.json +38 -0
- data/schemas/2026-04-08/schemas/shopping/types/buyer.json +25 -0
- data/schemas/2026-04-08/schemas/shopping/types/category.json +20 -0
- data/schemas/2026-04-08/schemas/shopping/types/context.json +42 -0
- data/schemas/2026-04-08/schemas/shopping/types/description.json +22 -0
- data/schemas/2026-04-08/schemas/shopping/types/detail_option_value.json +22 -0
- data/schemas/2026-04-08/schemas/shopping/types/error_code.json +17 -0
- data/schemas/2026-04-08/schemas/shopping/types/error_response.json +31 -0
- data/schemas/2026-04-08/schemas/shopping/types/expectation.json +62 -0
- data/schemas/2026-04-08/schemas/shopping/types/fulfillment.json +25 -0
- data/schemas/2026-04-08/schemas/shopping/types/fulfillment_available_method.json +45 -0
- data/schemas/2026-04-08/schemas/shopping/types/fulfillment_destination.json +16 -0
- data/schemas/2026-04-08/schemas/shopping/types/fulfillment_event.json +67 -0
- data/schemas/2026-04-08/schemas/shopping/types/fulfillment_group.json +45 -0
- data/schemas/2026-04-08/schemas/shopping/types/fulfillment_method.json +67 -0
- data/schemas/2026-04-08/schemas/shopping/types/fulfillment_option.json +56 -0
- data/schemas/2026-04-08/schemas/shopping/types/info_code.json +13 -0
- data/schemas/2026-04-08/schemas/shopping/types/input_correlation.json +24 -0
- data/schemas/2026-04-08/schemas/shopping/types/item.json +33 -0
- data/schemas/2026-04-08/schemas/shopping/types/line_item.json +46 -0
- data/schemas/2026-04-08/schemas/shopping/types/link.json +25 -0
- data/schemas/2026-04-08/schemas/shopping/types/media.json +36 -0
- data/schemas/2026-04-08/schemas/shopping/types/message.json +18 -0
- data/schemas/2026-04-08/schemas/shopping/types/message_error.json +49 -0
- data/schemas/2026-04-08/schemas/shopping/types/message_info.json +37 -0
- data/schemas/2026-04-08/schemas/shopping/types/message_warning.json +53 -0
- data/schemas/2026-04-08/schemas/shopping/types/option_value.json +20 -0
- data/schemas/2026-04-08/schemas/shopping/types/order_confirmation.json +26 -0
- data/schemas/2026-04-08/schemas/shopping/types/order_line_item.json +69 -0
- data/schemas/2026-04-08/schemas/shopping/types/pagination.json +62 -0
- data/schemas/2026-04-08/schemas/shopping/types/payment_credential.json +17 -0
- data/schemas/2026-04-08/schemas/shopping/types/payment_instrument.json +58 -0
- data/schemas/2026-04-08/schemas/shopping/types/platform_fulfillment_config.json +14 -0
- data/schemas/2026-04-08/schemas/shopping/types/postal_address.json +44 -0
- data/schemas/2026-04-08/schemas/shopping/types/price.json +22 -0
- data/schemas/2026-04-08/schemas/shopping/types/price_filter.json +17 -0
- data/schemas/2026-04-08/schemas/shopping/types/price_range.json +21 -0
- data/schemas/2026-04-08/schemas/shopping/types/product.json +89 -0
- data/schemas/2026-04-08/schemas/shopping/types/product_option.json +25 -0
- data/schemas/2026-04-08/schemas/shopping/types/rating.json +34 -0
- data/schemas/2026-04-08/schemas/shopping/types/retail_location.json +28 -0
- data/schemas/2026-04-08/schemas/shopping/types/reverse_domain_name.json +8 -0
- data/schemas/2026-04-08/schemas/shopping/types/search_filters.json +20 -0
- data/schemas/2026-04-08/schemas/shopping/types/selected_option.json +25 -0
- data/schemas/2026-04-08/schemas/shopping/types/shipping_destination.json +26 -0
- data/schemas/2026-04-08/schemas/shopping/types/signals.json +22 -0
- data/schemas/2026-04-08/schemas/shopping/types/signed_amount.json +7 -0
- data/schemas/2026-04-08/schemas/shopping/types/total.json +75 -0
- data/schemas/2026-04-08/schemas/shopping/types/totals.json +98 -0
- data/schemas/2026-04-08/schemas/shopping/types/variant.json +193 -0
- data/schemas/2026-04-08/schemas/shopping/types/warning_code.json +13 -0
- data/schemas/2026-04-08/schemas/transports/embedded_config.json +27 -0
- data/schemas/2026-04-08/schemas/ucp.json +364 -0
- data/schemas/2026-04-08/services/shopping/embedded.openrpc.json +634 -0
- data/schemas/2026-04-08/services/shopping/mcp.openrpc.json +492 -0
- metadata +283 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://ucp.dev/2026-04-08/schemas/shopping/checkout.json",
|
|
4
|
+
"name": "dev.ucp.shopping.checkout",
|
|
5
|
+
"title": "Checkout",
|
|
6
|
+
"description": "Base checkout schema. Extensions compose onto this using allOf.",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"required": [
|
|
9
|
+
"ucp",
|
|
10
|
+
"id",
|
|
11
|
+
"line_items",
|
|
12
|
+
"status",
|
|
13
|
+
"currency",
|
|
14
|
+
"totals",
|
|
15
|
+
"links"
|
|
16
|
+
],
|
|
17
|
+
"additionalProperties": true,
|
|
18
|
+
"properties": {
|
|
19
|
+
"ucp": {
|
|
20
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/ucp.json#/$defs/response_checkout_schema",
|
|
21
|
+
"ucp_request": "omit"
|
|
22
|
+
},
|
|
23
|
+
"id": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"description": "Unique identifier of the checkout session.",
|
|
26
|
+
"ucp_request": "omit"
|
|
27
|
+
},
|
|
28
|
+
"line_items": {
|
|
29
|
+
"type": "array",
|
|
30
|
+
"items": {
|
|
31
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/line_item.json"
|
|
32
|
+
},
|
|
33
|
+
"description": "List of line items being checked out.",
|
|
34
|
+
"ucp_request": {
|
|
35
|
+
"create": "required",
|
|
36
|
+
"update": "required",
|
|
37
|
+
"complete": "omit"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"buyer": {
|
|
41
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/buyer.json",
|
|
42
|
+
"description": "Representation of the buyer.",
|
|
43
|
+
"ucp_request": {
|
|
44
|
+
"create": "optional",
|
|
45
|
+
"update": "optional",
|
|
46
|
+
"complete": "omit"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"context": {
|
|
50
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/context.json",
|
|
51
|
+
"ucp_request": {
|
|
52
|
+
"create": "optional",
|
|
53
|
+
"update": "optional",
|
|
54
|
+
"complete": "omit"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"signals": {
|
|
58
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/signals.json",
|
|
59
|
+
"ucp_request": "optional"
|
|
60
|
+
},
|
|
61
|
+
"attribution": {
|
|
62
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/attribution.json",
|
|
63
|
+
"ucp_request": "optional"
|
|
64
|
+
},
|
|
65
|
+
"status": {
|
|
66
|
+
"type": "string",
|
|
67
|
+
"enum": [
|
|
68
|
+
"incomplete",
|
|
69
|
+
"requires_escalation",
|
|
70
|
+
"ready_for_complete",
|
|
71
|
+
"complete_in_progress",
|
|
72
|
+
"completed",
|
|
73
|
+
"canceled"
|
|
74
|
+
],
|
|
75
|
+
"description": "Checkout state indicating the current phase and required action. See Checkout Status lifecycle documentation for state transition details.",
|
|
76
|
+
"ucp_request": "omit"
|
|
77
|
+
},
|
|
78
|
+
"currency": {
|
|
79
|
+
"type": "string",
|
|
80
|
+
"description": "ISO 4217 currency code reflecting the merchant's market determination. Derived from address, context, and geo IP—buyers provide signals, merchants determine currency.",
|
|
81
|
+
"ucp_request": "omit"
|
|
82
|
+
},
|
|
83
|
+
"totals": {
|
|
84
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/totals.json",
|
|
85
|
+
"description": "Different cart totals.",
|
|
86
|
+
"ucp_request": "omit"
|
|
87
|
+
},
|
|
88
|
+
"messages": {
|
|
89
|
+
"type": "array",
|
|
90
|
+
"items": {
|
|
91
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/message.json"
|
|
92
|
+
},
|
|
93
|
+
"description": "List of messages with error and info about the checkout session state.",
|
|
94
|
+
"ucp_request": "omit"
|
|
95
|
+
},
|
|
96
|
+
"links": {
|
|
97
|
+
"type": "array",
|
|
98
|
+
"items": {
|
|
99
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/link.json"
|
|
100
|
+
},
|
|
101
|
+
"description": "Links to be displayed by the platform (Privacy Policy, TOS). Mandatory for legal compliance.",
|
|
102
|
+
"ucp_request": "omit"
|
|
103
|
+
},
|
|
104
|
+
"expires_at": {
|
|
105
|
+
"type": "string",
|
|
106
|
+
"format": "date-time",
|
|
107
|
+
"description": "RFC 3339 expiry timestamp. Default TTL is 6 hours from creation if not sent.",
|
|
108
|
+
"ucp_request": "omit"
|
|
109
|
+
},
|
|
110
|
+
"continue_url": {
|
|
111
|
+
"type": "string",
|
|
112
|
+
"format": "uri",
|
|
113
|
+
"description": "URL for checkout handoff and session recovery. MUST be provided when status is requires_escalation. See specification for format and availability requirements.",
|
|
114
|
+
"ucp_request": "omit"
|
|
115
|
+
},
|
|
116
|
+
"payment": {
|
|
117
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/payment.json",
|
|
118
|
+
"ucp_request": {
|
|
119
|
+
"create": "optional",
|
|
120
|
+
"update": "optional",
|
|
121
|
+
"complete": "required"
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
"order": {
|
|
125
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/order_confirmation.json",
|
|
126
|
+
"description": "Details about an order created for this checkout session.",
|
|
127
|
+
"ucp_request": "omit"
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
"version": "2026-04-08"
|
|
131
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://ucp.dev/2026-04-08/schemas/shopping/discount.json",
|
|
4
|
+
"name": "dev.ucp.shopping.discount",
|
|
5
|
+
"title": "Discount Extension",
|
|
6
|
+
"description": "Extends Cart and Checkout with discount support, including discount codes, automatic discounts, and eligibility-triggered provisional discounts.",
|
|
7
|
+
"$defs": {
|
|
8
|
+
"allocation": {
|
|
9
|
+
"type": "object",
|
|
10
|
+
"description": "Breakdown of how a discount amount was allocated to a specific target.",
|
|
11
|
+
"required": [
|
|
12
|
+
"path",
|
|
13
|
+
"amount"
|
|
14
|
+
],
|
|
15
|
+
"properties": {
|
|
16
|
+
"path": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"description": "JSONPath to the allocation target (e.g., '$.line_items[0]', '$.totals.shipping')."
|
|
19
|
+
},
|
|
20
|
+
"amount": {
|
|
21
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/amount.json",
|
|
22
|
+
"description": "Amount allocated to this target in ISO 4217 minor units."
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"applied_discount": {
|
|
27
|
+
"type": "object",
|
|
28
|
+
"description": "A discount that was successfully applied.",
|
|
29
|
+
"required": [
|
|
30
|
+
"title",
|
|
31
|
+
"amount"
|
|
32
|
+
],
|
|
33
|
+
"properties": {
|
|
34
|
+
"code": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"description": "The discount code. Omitted for automatic discounts."
|
|
37
|
+
},
|
|
38
|
+
"title": {
|
|
39
|
+
"type": "string",
|
|
40
|
+
"description": "Human-readable discount name (e.g., 'Summer Sale 20% Off')."
|
|
41
|
+
},
|
|
42
|
+
"amount": {
|
|
43
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/amount.json",
|
|
44
|
+
"description": "Total discount amount in ISO 4217 minor units."
|
|
45
|
+
},
|
|
46
|
+
"automatic": {
|
|
47
|
+
"type": "boolean",
|
|
48
|
+
"default": false,
|
|
49
|
+
"description": "True if applied automatically by merchant rules (no code required)."
|
|
50
|
+
},
|
|
51
|
+
"method": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"enum": [
|
|
54
|
+
"each",
|
|
55
|
+
"across"
|
|
56
|
+
],
|
|
57
|
+
"description": "Allocation method. 'each' = applied independently per item. 'across' = split proportionally by value."
|
|
58
|
+
},
|
|
59
|
+
"priority": {
|
|
60
|
+
"type": "integer",
|
|
61
|
+
"minimum": 1,
|
|
62
|
+
"description": "Stacking order for discount calculation. Lower numbers applied first (1 = first)."
|
|
63
|
+
},
|
|
64
|
+
"provisional": {
|
|
65
|
+
"type": "boolean",
|
|
66
|
+
"default": false,
|
|
67
|
+
"description": "True if this discount requires additional verification."
|
|
68
|
+
},
|
|
69
|
+
"eligibility": {
|
|
70
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/reverse_domain_name.json",
|
|
71
|
+
"description": "The eligibility claim accepted by the Business for this discount. Corresponds to a value from context.eligibility. Omitted for code-based and non-eligibility automatic discounts."
|
|
72
|
+
},
|
|
73
|
+
"allocations": {
|
|
74
|
+
"type": "array",
|
|
75
|
+
"items": {
|
|
76
|
+
"$ref": "#/$defs/allocation"
|
|
77
|
+
},
|
|
78
|
+
"description": "Breakdown of where this discount was allocated. Sum of allocation amounts equals total amount."
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"discounts_object": {
|
|
83
|
+
"type": "object",
|
|
84
|
+
"description": "Discount codes input and applied discounts output.",
|
|
85
|
+
"properties": {
|
|
86
|
+
"codes": {
|
|
87
|
+
"type": "array",
|
|
88
|
+
"items": {
|
|
89
|
+
"type": "string"
|
|
90
|
+
},
|
|
91
|
+
"description": "Discount codes to apply. Case-insensitive. Replaces previously submitted codes. Send empty array to clear."
|
|
92
|
+
},
|
|
93
|
+
"applied": {
|
|
94
|
+
"type": "array",
|
|
95
|
+
"items": {
|
|
96
|
+
"$ref": "#/$defs/applied_discount"
|
|
97
|
+
},
|
|
98
|
+
"description": "Discounts successfully applied (code-based and automatic).",
|
|
99
|
+
"ucp_request": "omit"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
"dev.ucp.shopping.cart": {
|
|
104
|
+
"title": "Cart with Discount",
|
|
105
|
+
"description": "Cart extended with discount capability.",
|
|
106
|
+
"allOf": [
|
|
107
|
+
{
|
|
108
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/cart.json"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"type": "object",
|
|
112
|
+
"properties": {
|
|
113
|
+
"discounts": {
|
|
114
|
+
"$ref": "#/$defs/discounts_object",
|
|
115
|
+
"ucp_request": {
|
|
116
|
+
"create": "optional",
|
|
117
|
+
"update": "optional"
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
"dev.ucp.shopping.checkout": {
|
|
125
|
+
"title": "Checkout with Discount",
|
|
126
|
+
"description": "Checkout extended with discount capability.",
|
|
127
|
+
"allOf": [
|
|
128
|
+
{
|
|
129
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/checkout.json"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"type": "object",
|
|
133
|
+
"properties": {
|
|
134
|
+
"discounts": {
|
|
135
|
+
"$ref": "#/$defs/discounts_object",
|
|
136
|
+
"ucp_request": {
|
|
137
|
+
"create": "optional",
|
|
138
|
+
"update": "optional",
|
|
139
|
+
"complete": "omit"
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
"version": "2026-04-08"
|
|
148
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://ucp.dev/2026-04-08/schemas/shopping/fulfillment.json",
|
|
4
|
+
"name": "dev.ucp.shopping.fulfillment",
|
|
5
|
+
"title": "Fulfillment Extension",
|
|
6
|
+
"description": "Extends Checkout with fulfillment support using methods, destinations, and groups.",
|
|
7
|
+
"$defs": {
|
|
8
|
+
"fulfillment_option": {
|
|
9
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/fulfillment_option.json"
|
|
10
|
+
},
|
|
11
|
+
"fulfillment_group": {
|
|
12
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/fulfillment_group.json"
|
|
13
|
+
},
|
|
14
|
+
"fulfillment_method": {
|
|
15
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/fulfillment_method.json"
|
|
16
|
+
},
|
|
17
|
+
"fulfillment_available_method": {
|
|
18
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/fulfillment_available_method.json"
|
|
19
|
+
},
|
|
20
|
+
"fulfillment": {
|
|
21
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/fulfillment.json"
|
|
22
|
+
},
|
|
23
|
+
"dev.ucp.shopping.checkout": {
|
|
24
|
+
"title": "Checkout with Fulfillment",
|
|
25
|
+
"description": "Checkout extended with hierarchical fulfillment.",
|
|
26
|
+
"allOf": [
|
|
27
|
+
{
|
|
28
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/checkout.json"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"type": "object",
|
|
32
|
+
"properties": {
|
|
33
|
+
"fulfillment": {
|
|
34
|
+
"$ref": "#/$defs/fulfillment",
|
|
35
|
+
"description": "Fulfillment details.",
|
|
36
|
+
"ucp_request": {
|
|
37
|
+
"create": "optional",
|
|
38
|
+
"update": "optional",
|
|
39
|
+
"complete": "omit"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
"dev.ucp.shopping.fulfillment": {
|
|
47
|
+
"platform_schema": {
|
|
48
|
+
"title": "Fulfillment Capability (Platform)",
|
|
49
|
+
"description": "Platform-level fulfillment capability configuration",
|
|
50
|
+
"allOf": [
|
|
51
|
+
{
|
|
52
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/capability.json#/$defs/platform_schema"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"properties": {
|
|
56
|
+
"config": {
|
|
57
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/platform_fulfillment_config.json",
|
|
58
|
+
"description": "Platform fulfillment configuration"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
"business_schema": {
|
|
65
|
+
"title": "Fulfillment Capability (Business)",
|
|
66
|
+
"description": "Business-level fulfillment capability configuration",
|
|
67
|
+
"allOf": [
|
|
68
|
+
{
|
|
69
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/capability.json#/$defs/business_schema"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"properties": {
|
|
73
|
+
"config": {
|
|
74
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/business_fulfillment_config.json",
|
|
75
|
+
"description": "Business fulfillment configuration"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"embedded": {
|
|
84
|
+
"delegations": [
|
|
85
|
+
"fulfillment.address_change"
|
|
86
|
+
],
|
|
87
|
+
"methods": {
|
|
88
|
+
"ec.fulfillment.change": {
|
|
89
|
+
"name": "ec.fulfillment.change",
|
|
90
|
+
"summary": "Fulfillment details changed",
|
|
91
|
+
"description": "Merchant notifies host that checkout.fulfillment has changed (shipping method selected, delivery options updated).",
|
|
92
|
+
"params": [
|
|
93
|
+
{
|
|
94
|
+
"name": "checkout",
|
|
95
|
+
"required": true,
|
|
96
|
+
"schema": {
|
|
97
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/checkout.json",
|
|
98
|
+
"description": "Current checkout state with updated fulfillment."
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
"ec.fulfillment.address_change_request": {
|
|
104
|
+
"name": "ec.fulfillment.address_change_request",
|
|
105
|
+
"summary": "Request address change",
|
|
106
|
+
"description": "Merchant requests host to present address selection UI for a shipping fulfillment method.",
|
|
107
|
+
"params": [
|
|
108
|
+
{
|
|
109
|
+
"name": "checkout",
|
|
110
|
+
"required": true,
|
|
111
|
+
"schema": {
|
|
112
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/checkout.json",
|
|
113
|
+
"description": "Current checkout state with fulfillment details."
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
],
|
|
117
|
+
"result": {
|
|
118
|
+
"name": "addressChangeResult",
|
|
119
|
+
"schema": {
|
|
120
|
+
"oneOf": [
|
|
121
|
+
{
|
|
122
|
+
"type": "object",
|
|
123
|
+
"description": "Checkout state after address selection.",
|
|
124
|
+
"required": [
|
|
125
|
+
"ucp",
|
|
126
|
+
"checkout"
|
|
127
|
+
],
|
|
128
|
+
"properties": {
|
|
129
|
+
"ucp": {
|
|
130
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/ucp.json#/$defs/success"
|
|
131
|
+
},
|
|
132
|
+
"checkout": {
|
|
133
|
+
"type": "object",
|
|
134
|
+
"description": "Partial checkout update with fulfillment address selection.",
|
|
135
|
+
"properties": {
|
|
136
|
+
"fulfillment": {
|
|
137
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/fulfillment.json",
|
|
138
|
+
"description": "Updated fulfillment with new selected destination and destinations."
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/error_response.json"
|
|
146
|
+
}
|
|
147
|
+
]
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
"version": "2026-04-08"
|
|
154
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://ucp.dev/2026-04-08/schemas/shopping/order.json",
|
|
4
|
+
"name": "dev.ucp.shopping.order",
|
|
5
|
+
"title": "Order",
|
|
6
|
+
"description": "Order schema with line items, buyer-facing fulfillment expectations, and event logs.",
|
|
7
|
+
"$defs": {
|
|
8
|
+
"platform_schema": {
|
|
9
|
+
"title": "Platform Order Schema",
|
|
10
|
+
"description": "Platform's order capability configuration.",
|
|
11
|
+
"type": "object",
|
|
12
|
+
"required": [
|
|
13
|
+
"webhook_url"
|
|
14
|
+
],
|
|
15
|
+
"properties": {
|
|
16
|
+
"webhook_url": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"format": "uri",
|
|
19
|
+
"description": "URL where merchant sends order lifecycle events (webhooks)."
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"type": "object",
|
|
25
|
+
"required": [
|
|
26
|
+
"ucp",
|
|
27
|
+
"id",
|
|
28
|
+
"checkout_id",
|
|
29
|
+
"permalink_url",
|
|
30
|
+
"line_items",
|
|
31
|
+
"fulfillment",
|
|
32
|
+
"currency",
|
|
33
|
+
"totals"
|
|
34
|
+
],
|
|
35
|
+
"properties": {
|
|
36
|
+
"ucp": {
|
|
37
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/ucp.json#/$defs/response_order_schema"
|
|
38
|
+
},
|
|
39
|
+
"id": {
|
|
40
|
+
"type": "string",
|
|
41
|
+
"description": "Unique order identifier."
|
|
42
|
+
},
|
|
43
|
+
"label": {
|
|
44
|
+
"type": "string",
|
|
45
|
+
"description": "Human-readable label for identifying the order. MUST only be provided by the business."
|
|
46
|
+
},
|
|
47
|
+
"checkout_id": {
|
|
48
|
+
"type": "string",
|
|
49
|
+
"description": "Associated checkout ID for reconciliation."
|
|
50
|
+
},
|
|
51
|
+
"permalink_url": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"format": "uri",
|
|
54
|
+
"description": "Permalink to access the order on merchant site."
|
|
55
|
+
},
|
|
56
|
+
"line_items": {
|
|
57
|
+
"type": "array",
|
|
58
|
+
"items": {
|
|
59
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/order_line_item.json"
|
|
60
|
+
},
|
|
61
|
+
"description": "Line items representing what was purchased — can change post-order via edits or exchanges."
|
|
62
|
+
},
|
|
63
|
+
"fulfillment": {
|
|
64
|
+
"type": "object",
|
|
65
|
+
"properties": {
|
|
66
|
+
"expectations": {
|
|
67
|
+
"type": "array",
|
|
68
|
+
"items": {
|
|
69
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/expectation.json"
|
|
70
|
+
},
|
|
71
|
+
"description": "Buyer-facing groups representing when/how items will be delivered. Can be split, merged, or adjusted post-order."
|
|
72
|
+
},
|
|
73
|
+
"events": {
|
|
74
|
+
"type": "array",
|
|
75
|
+
"items": {
|
|
76
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/fulfillment_event.json"
|
|
77
|
+
},
|
|
78
|
+
"description": "Append-only event log of actual shipments. Each event references line items by ID."
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"description": "Fulfillment data: buyer expectations and what actually happened."
|
|
82
|
+
},
|
|
83
|
+
"adjustments": {
|
|
84
|
+
"type": "array",
|
|
85
|
+
"items": {
|
|
86
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/adjustment.json"
|
|
87
|
+
},
|
|
88
|
+
"description": "Post-order events (refunds, returns, credits, disputes, cancellations, etc.) that exist independently of fulfillment."
|
|
89
|
+
},
|
|
90
|
+
"currency": {
|
|
91
|
+
"type": "string",
|
|
92
|
+
"description": "ISO 4217 currency code. MUST match the currency from the originating checkout session.",
|
|
93
|
+
"ucp_request": "omit"
|
|
94
|
+
},
|
|
95
|
+
"totals": {
|
|
96
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/totals.json",
|
|
97
|
+
"description": "Different totals for the order."
|
|
98
|
+
},
|
|
99
|
+
"messages": {
|
|
100
|
+
"type": "array",
|
|
101
|
+
"items": {
|
|
102
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/message.json"
|
|
103
|
+
},
|
|
104
|
+
"description": "Business outcome messages (errors, warnings, informational). Present when the business needs to communicate status or issues to the platform."
|
|
105
|
+
},
|
|
106
|
+
"attribution": {
|
|
107
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/attribution.json",
|
|
108
|
+
"description": "Snapshot of the attribution associated with the originating checkout. Read-only on the order.",
|
|
109
|
+
"ucp_request": "omit"
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
"version": "2026-04-08"
|
|
113
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://ucp.dev/2026-04-08/schemas/shopping/payment.json",
|
|
4
|
+
"title": "Payment",
|
|
5
|
+
"description": "Payment configuration containing handlers.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"instruments": {
|
|
9
|
+
"type": "array",
|
|
10
|
+
"items": {
|
|
11
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/payment_instrument.json#/$defs/selected_payment_instrument"
|
|
12
|
+
},
|
|
13
|
+
"description": "The payment instruments available for this payment. Each instrument is associated with a specific handler via the handler_id field. Handlers can extend the base payment_instrument schema to add handler-specific fields."
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/adjustment.json",
|
|
4
|
+
"title": "Adjustment",
|
|
5
|
+
"description": "Post-order event that exists independently of fulfillment. Typically represents money movements but can be any post-order change. Polymorphic type that can optionally reference line items.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"id",
|
|
9
|
+
"type",
|
|
10
|
+
"occurred_at",
|
|
11
|
+
"status"
|
|
12
|
+
],
|
|
13
|
+
"properties": {
|
|
14
|
+
"id": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"description": "Adjustment event identifier."
|
|
17
|
+
},
|
|
18
|
+
"type": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"description": "Type of adjustment (open string). Typically money-related like: refund, return, credit, price_adjustment, dispute, cancellation. Can be any value that makes sense for the merchant's business."
|
|
21
|
+
},
|
|
22
|
+
"occurred_at": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"format": "date-time",
|
|
25
|
+
"description": "RFC 3339 timestamp when this adjustment occurred."
|
|
26
|
+
},
|
|
27
|
+
"status": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"enum": [
|
|
30
|
+
"pending",
|
|
31
|
+
"completed",
|
|
32
|
+
"failed"
|
|
33
|
+
],
|
|
34
|
+
"description": "Adjustment status."
|
|
35
|
+
},
|
|
36
|
+
"line_items": {
|
|
37
|
+
"type": "array",
|
|
38
|
+
"items": {
|
|
39
|
+
"type": "object",
|
|
40
|
+
"required": [
|
|
41
|
+
"id",
|
|
42
|
+
"quantity"
|
|
43
|
+
],
|
|
44
|
+
"properties": {
|
|
45
|
+
"id": {
|
|
46
|
+
"type": "string",
|
|
47
|
+
"description": "Line item ID reference."
|
|
48
|
+
},
|
|
49
|
+
"quantity": {
|
|
50
|
+
"type": "integer",
|
|
51
|
+
"description": "Signed quantity affected by this adjustment. Negative values represent reductions (e.g. returns); positive values represent additions (e.g. exchanges)."
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"description": "Which line items and quantities are affected (optional)."
|
|
56
|
+
},
|
|
57
|
+
"totals": {
|
|
58
|
+
"type": "array",
|
|
59
|
+
"items": {
|
|
60
|
+
"$ref": "https://ucp.dev/2026-04-08/schemas/shopping/types/total.json"
|
|
61
|
+
},
|
|
62
|
+
"description": "Adjustment totals breakdown. Signed values - negative for money returned to buyer (refunds, credits), positive for additional charges (exchanges)."
|
|
63
|
+
},
|
|
64
|
+
"description": {
|
|
65
|
+
"type": "string",
|
|
66
|
+
"description": "Human-readable reason or description (e.g., 'Defective item', 'Customer requested')."
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/amount.json",
|
|
4
|
+
"title": "Amount",
|
|
5
|
+
"description": "Monetary amount in the currency's minor unit as defined by ISO 4217. Refer to the currency's exponent to determine minor-to-major ratio (e.g., 2 for USD, 0 for JPY, 3 for KWD).",
|
|
6
|
+
"type": "integer",
|
|
7
|
+
"minimum": 0
|
|
8
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://ucp.dev/2026-04-08/schemas/shopping/types/attribution.json",
|
|
4
|
+
"title": "Attribution",
|
|
5
|
+
"description": "Platform-emitted referral and conversion-event context — campaign identifiers, click IDs, source/medium markers, etc. The same parameters platforms communicate via URL query parameters in browser-based flows.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "URL-style parameter value, encoded as a string. Numeric or boolean values MUST be string-encoded as they would be in a URL query string."
|
|
10
|
+
}
|
|
11
|
+
}
|