portage-ucp 0.12.0 → 0.13.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 +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/portage/ucp/support/checkout_state.rb +73 -2
- data/lib/portage/ucp/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1e47e8018ba5966b67205cb9046efdf0e8f0edbe9ab58eef1e7613232a5b6b27
|
|
4
|
+
data.tar.gz: c5eaa266f8d88a7fda16a822e0eb0b6aad82465b1e6adbf36abe08e7d2c859c4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '053845855d29f395fb001b78d13622798aadf54c8dc087c88bdf32a943e65e992e7d6d79a3f9a5c86232ebfb8f65f36eb1137888bd9a806e2ceeeef045a57789'
|
|
7
|
+
data.tar.gz: 6e1cec328b2d07567d4441340fe177367db3bbe7e094aa93388446cb062ea948e600abeb353dcf31b3833f7f76d2ccc189c275a44ab4c5ea546b94e4f3c152d7
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,10 @@ pre-1.0, so APIs may still shift between minor versions.
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.13.0] - 2026-10-07
|
|
10
|
+
|
|
11
|
+
- **Added: `Support::CheckoutState` can ask the platform about a checkout this process doesn't track.** An adapter may define a private `platform_checkout_order(checkout_id)` that returns the `Order` its platform placed from that checkout, or nil. `#checkout_status` then reports `completed` for an id with no in-process record, the new `#checkout_order` returns its `OrderConfirmation`, and the new `#checkout_from_platform_order` rebuilds a completed `Checkout` from the order when the platform has already dropped the cart. A found order is cached through `#record_checkout_status`/`#record_order_checkout`; no order, no hook, or a lookup error keeps today's `incomplete`. This lets `portage orders reconcile`, which runs in a new process, see a checkout the shopper paid for in the browser (design-log §55). The `Adapter` contract is unchanged. Minor-level.
|
|
12
|
+
|
|
9
13
|
## [0.12.0] - 2026-10-05
|
|
10
14
|
|
|
11
15
|
- **Removed the unused `services/shopping/embedded.openrpc.json` schema.** Nothing loaded or listed it (`SchemaValidator` only reads `mcp.openrpc.json`); it just shipped in the gem. Patch-level.
|
|
@@ -14,7 +14,9 @@ module Portage
|
|
|
14
14
|
#
|
|
15
15
|
# Both default rather than raise on an unknown id ("incomplete" and "",
|
|
16
16
|
# respectively): a checkout this process didn't create is still
|
|
17
|
-
# schema-valid to report, just not information-complete.
|
|
17
|
+
# schema-valid to report, just not information-complete. An adapter
|
|
18
|
+
# can add a platform lookup for the unknown-id case (see
|
|
19
|
+
# #platform_order).
|
|
18
20
|
module CheckoutState
|
|
19
21
|
# Dispatcher wraps each adapter call in .with_observability rather
|
|
20
22
|
# than writing [logger, correlation_id] onto an instance variable on
|
|
@@ -49,8 +51,77 @@ module Portage
|
|
|
49
51
|
|
|
50
52
|
private
|
|
51
53
|
|
|
54
|
+
# A checkout this process has no record of falls back to the
|
|
55
|
+
# platform: `portage orders reconcile` runs in a new process, after
|
|
56
|
+
# the shopper paid in their browser, and the in-process hash alone
|
|
57
|
+
# would always say "incomplete" there (design-log §55). See
|
|
58
|
+
# #platform_order.
|
|
52
59
|
def checkout_status(checkout_id)
|
|
53
|
-
(@checkout_status ||= {})
|
|
60
|
+
recorded = (@checkout_status ||= {})[checkout_id]
|
|
61
|
+
return recorded if recorded
|
|
62
|
+
|
|
63
|
+
platform_order(checkout_id) ? "completed" : "incomplete"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# The order_confirmation for a checkout #platform_order found an order
|
|
67
|
+
# for, nil otherwise (an in-process #complete_checkout hands its own
|
|
68
|
+
# back directly).
|
|
69
|
+
def checkout_order(checkout_id)
|
|
70
|
+
order = (@platform_orders ||= {})[checkout_id]
|
|
71
|
+
order && Portage::Ucp::OrderConfirmation.new(id: order.id, permalink_url: order.permalink_url)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# For a #get_checkout whose cart read came back not-found: most
|
|
75
|
+
# platforms drop the cart once it becomes an order (BigCommerce
|
|
76
|
+
# deletes it on payment, Magento deactivates the quote), so a paid
|
|
77
|
+
# checkout would otherwise only ever read as not-found. This builds
|
|
78
|
+
# the completed Checkout from the order the platform reports for it.
|
|
79
|
+
# No order means nil: a vanished cart on its own is never read as a
|
|
80
|
+
# completion (docs/plans/handoff-reconcile.md, "Settle only on a
|
|
81
|
+
# `completed` status the store actually reports").
|
|
82
|
+
def checkout_from_platform_order(checkout_id)
|
|
83
|
+
order = platform_order(checkout_id)
|
|
84
|
+
return nil unless order
|
|
85
|
+
|
|
86
|
+
line_items = order.line_items.map do |li|
|
|
87
|
+
Portage::Ucp::LineItem.new(id: li.id, item: li.item, quantity: li.quantity[:total], totals: li.totals)
|
|
88
|
+
end
|
|
89
|
+
Portage::Ucp::Checkout.new(id: checkout_id, status: "completed", line_items: line_items,
|
|
90
|
+
currency: order.currency, totals: order.totals, links: [],
|
|
91
|
+
order: checkout_order(checkout_id))
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# The optional per-adapter hook: an adapter that can ask its platform
|
|
95
|
+
# "did this checkout become a placed order?" defines a private
|
|
96
|
+
# `platform_checkout_order(checkout_id)` returning that Portage::Ucp::
|
|
97
|
+
# Order, or nil. Without the hook (or when this process already
|
|
98
|
+
# tracks the checkout) nothing changes. A found order is cached
|
|
99
|
+
# through #record_checkout_status/#record_order_checkout so the rest
|
|
100
|
+
# of this process agrees with it. A lookup error is swallowed: the
|
|
101
|
+
# caller gets today's in-process answer, which reconcile reads as
|
|
102
|
+
# "still pending", never as a settle. The hook is a private method
|
|
103
|
+
# rather than a new Adapter method or kwarg for the same §9/§23
|
|
104
|
+
# reason as .with_observability above.
|
|
105
|
+
def platform_order(checkout_id)
|
|
106
|
+
orders = (@platform_orders ||= {})
|
|
107
|
+
return orders[checkout_id] if orders.key?(checkout_id)
|
|
108
|
+
|
|
109
|
+
order = ask_platform(checkout_id)
|
|
110
|
+
return nil unless order
|
|
111
|
+
|
|
112
|
+
orders[checkout_id] = order
|
|
113
|
+
record_order_checkout(order.id, checkout_id)
|
|
114
|
+
record_checkout_status(checkout_id, "completed")
|
|
115
|
+
order
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def ask_platform(checkout_id)
|
|
119
|
+
return nil if (@checkout_status ||= {}).key?(checkout_id)
|
|
120
|
+
return nil unless respond_to?(:platform_checkout_order, true)
|
|
121
|
+
|
|
122
|
+
platform_checkout_order(checkout_id)
|
|
123
|
+
rescue StandardError
|
|
124
|
+
nil
|
|
54
125
|
end
|
|
55
126
|
|
|
56
127
|
def record_checkout_status(checkout_id, status)
|
data/lib/portage/ucp/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: portage-ucp
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.13.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tom Whitbread
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-10-
|
|
11
|
+
date: 2026-10-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: base64
|