From 31660aa14c04ca149339c5ff52c338a921b2a122 Mon Sep 17 00:00:00 2001 From: vishkaty <147529812+vishkaty@users.noreply.github.com> Date: Wed, 29 Jul 2026 11:43:20 -0400 Subject: [PATCH] fix(rest/python): seed valid totals when creating a checkout The SDK now enforces the totals contains cardinality (exactly one subtotal and one total) on the response models. create_checkout constructed the checkout with an empty totals list and filled it in during recalculation, so construction validated the empty list and rejected it, returning 500 on every create. Seed a valid placeholder (one subtotal + one total) at construction so the in-progress model satisfies the constraint; _recalculate_totals overwrites it with the server-authoritative amounts immediately after. Construction stays fully validated, and the emitted wire document is unchanged. Verified against the pinned SDK build with the totals validators active: full conformance suite 69 passing / 0 failures (was 67 failures). Also green without the validators: server integration tests (16) and the happy-path client, so it is safe to land independently. Relates to Universal-Commerce-Protocol/python-sdk#57 --- rest/python/server/services/checkout_service.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/rest/python/server/services/checkout_service.py b/rest/python/server/services/checkout_service.py index c3f445e..a209f23 100644 --- a/rest/python/server/services/checkout_service.py +++ b/rest/python/server/services/checkout_service.py @@ -286,6 +286,12 @@ async def create_checkout( fulfillment_resp = FulfillmentResponseClass(methods=resp_methods) + # The SDK enforces the totals contains cardinality (exactly one subtotal + # and one total) on the response model. The server is the authority for + # totals and computes them in _recalculate_totals below, but that runs + # after construction. Seed a valid placeholder so the in-progress model + # satisfies the constraint at construction; it is overwritten with the + # authoritative amounts immediately. See python-sdk#57. checkout = Checkout( ucp=ResponseCheckout( version=config.get_server_version(), @@ -303,7 +309,10 @@ async def create_checkout( status=CheckoutStatus.IN_PROGRESS, currency=checkout_req.currency, line_items=line_items, - totals=[], + totals=[ + {"type": "subtotal", "amount": 0}, + {"type": "total", "amount": 0}, + ], links=[], payment=PaymentResponse( instruments=checkout_req.payment.instruments