Skip to content
120 changes: 67 additions & 53 deletions rest/python/client/flower_shop/simple_happy_path_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@
from pathlib import Path
import uuid
import httpx
from ucp_sdk.models.schemas.shopping import checkout_create_req
from ucp_sdk.models.schemas.shopping import checkout_update_req
from ucp_sdk.models.schemas.shopping import payment_create_req
from ucp_sdk.models.schemas.shopping.types import buyer
from ucp_sdk.models.schemas.shopping.types import item_create_req
from ucp_sdk.models.schemas.shopping.types import item_update_req
from ucp_sdk.models.schemas.shopping.types import line_item_create_req
from ucp_sdk.models.schemas.shopping.types import line_item_update_req
from ucp_sdk.models.schemas.shopping import checkout_create_request
from ucp_sdk.models.schemas.shopping import checkout_update_request
from ucp_sdk.models.schemas.shopping import payment_create_request
from ucp_sdk.models.schemas.shopping.types import buyer_create_request
from ucp_sdk.models.schemas.shopping.types import item_create_request
from ucp_sdk.models.schemas.shopping.types import item_update_request
from ucp_sdk.models.schemas.shopping.types import line_item_create_request
from ucp_sdk.models.schemas.shopping.types import line_item_update_request


def get_headers() -> dict[str, str]:
Expand Down Expand Up @@ -237,7 +237,9 @@ def main() -> None:

discovery_data = response.json()

supported_handlers = discovery_data.get("payment", {}).get("handlers", [])
supported_handlers = []
for handlers in discovery_data.get("payment_handlers", {}).values():
supported_handlers.extend(handlers)

logger.info(
"Merchant supports %d payment handlers:", len(supported_handlers)
Expand All @@ -256,33 +258,33 @@ def main() -> None:

# We start with one item: "Red Rose"

item1 = item_create_req.ItemCreateRequest(
id="bouquet_roses", title="Red Rose"
)
item1 = item_create_request.ItemCreateRequest(id="bouquet_roses")

line_item1 = line_item_create_req.LineItemCreateRequest(
line_item1 = line_item_create_request.LineItemCreateRequest(
quantity=1, item=item1
)

# We initialize the payment section with the handlers we discovered.

# We do NOT select an instrument yet (selected_instrument_id=None).

payment_req = payment_create_req.PaymentCreateRequest(
payment_request = payment_create_request.PaymentCreateRequest(
instruments=[],
selected_instrument_id=None,
handlers=supported_handlers, # Pass back what we found (or a subset)
)

# We include the buyer to trigger address lookup on the server

buyer_req = buyer.Buyer(full_name="John Doe", email="john.doe@example.com")
buyer_request = buyer_create_request.BuyerCreateRequest(
full_name="John Doe", email="john.doe@example.com"
)

create_payload = checkout_create_req.CheckoutCreateRequest(
create_payload = checkout_create_request.CheckoutCreateRequest(
currency="USD",
line_items=[line_item1],
payment=payment_req,
buyer=buyer_req,
payment=payment_request,
buyer=buyer_request,
)

headers = get_headers()
Expand Down Expand Up @@ -352,30 +354,27 @@ def main() -> None:

# Update Item 1 (Roses) - Keep quantity 1

item1_update = item_update_req.ItemUpdateRequest(
id="bouquet_roses", title="Red Rose"
)
item1_update = item_update_request.ItemUpdateRequest(id="bouquet_roses")

line_item1_update = line_item_update_req.LineItemUpdateRequest(
line_item1_update = line_item_update_request.LineItemUpdateRequest(
id=checkout_data["line_items"][0]["id"],
quantity=1,
item=item1_update,
)

# Add Item 2 (Ceramic Pot) - Quantity 2

item2_update = item_update_req.ItemUpdateRequest(
id="pot_ceramic", title="Ceramic Pot"
)
item2_update = item_update_request.ItemUpdateRequest(id="pot_ceramic")

line_item2_update = line_item_update_req.LineItemUpdateRequest(
line_item2_update = line_item_update_request.LineItemUpdateRequest(
id=str(uuid.uuid4()),
quantity=2,
item=item2_update,
)

# Construct the Update Payload

update_payload = checkout_update_req.CheckoutUpdateRequest(
update_payload = checkout_update_request.CheckoutUpdateRequest(
id=checkout_id,
line_items=[line_item1_update, line_item2_update],
currency=checkout_data["currency"],
Expand Down Expand Up @@ -459,29 +458,25 @@ def main() -> None:
if li["item"]["id"] == "pot_ceramic"
)

item1_update = item_update_req.ItemUpdateRequest(
id="bouquet_roses", title="Red Rose"
)
item1_update = item_update_request.ItemUpdateRequest(id="bouquet_roses")

line_item1_update = line_item_update_req.LineItemUpdateRequest(
line_item1_update = line_item_update_request.LineItemUpdateRequest(
id=li_1["id"],
quantity=1,
item=item1_update,
)

item2_update = item_update_req.ItemUpdateRequest(
id="pot_ceramic", title="Ceramic Pot"
)
item2_update = item_update_request.ItemUpdateRequest(id="pot_ceramic")

line_item2_update = line_item_update_req.LineItemUpdateRequest(
line_item2_update = line_item_update_request.LineItemUpdateRequest(
id=li_2["id"],
quantity=2,
item=item2_update,
)

# Construct the Update Payload

update_payload = checkout_update_req.CheckoutUpdateRequest(
update_payload = checkout_update_request.CheckoutUpdateRequest(
id=checkout_id,
line_items=[line_item1_update, line_item2_update],
currency=checkout_data["currency"],
Expand Down Expand Up @@ -570,37 +565,41 @@ def main() -> None:
if li["item"]["id"] == "pot_ceramic"
)

item1_update = item_update_req.ItemUpdateRequest(
id="bouquet_roses", title="Red Rose"
)
item1_update = item_update_request.ItemUpdateRequest(id="bouquet_roses")

line_item1_update = line_item_update_req.LineItemUpdateRequest(
line_item1_update = line_item_update_request.LineItemUpdateRequest(
id=li_1["id"],
quantity=1,
item=item1_update,
)

item2_update = item_update_req.ItemUpdateRequest(
id="pot_ceramic", title="Ceramic Pot"
)
item2_update = item_update_request.ItemUpdateRequest(id="pot_ceramic")

line_item2_update = line_item_update_req.LineItemUpdateRequest(
line_item2_update = line_item_update_request.LineItemUpdateRequest(
id=li_2["id"],
quantity=2,
item=item2_update,
)

# Construct full update payload

trigger_req = checkout_update_req.CheckoutUpdateRequest(
trigger_request = checkout_update_request.CheckoutUpdateRequest(
id=checkout_id,
line_items=[line_item1_update, line_item2_update],
currency=checkout_data["currency"],
payment=checkout_data["payment"],
fulfillment={"methods": [{"type": "shipping"}]},
fulfillment={
"methods": [
{
"id": "method_1",
"type": "shipping",
"line_item_ids": [li_1["id"], li_2["id"]],
}
]
},
)

trigger_payload = trigger_req.model_dump(
trigger_payload = trigger_request.model_dump(
mode="json", by_alias=True, exclude_none=True
)

Expand Down Expand Up @@ -676,11 +675,18 @@ def main() -> None:

# We must send full payload again

trigger_req.fulfillment = {
"methods": [{"type": "shipping", "selected_destination_id": dest_id}]
trigger_request.fulfillment = {
"methods": [
{
"id": "method_1",
"type": "shipping",
"line_item_ids": [li_1["id"], li_2["id"]],
"selected_destination_id": dest_id,
}
]
}

payload = trigger_req.model_dump(
payload = trigger_request.model_dump(
mode="json", by_alias=True, exclude_none=True
)

Expand Down Expand Up @@ -722,17 +728,25 @@ def main() -> None:

logger.info("STEP 6: Selecting option: %s", option_id)

trigger_req.fulfillment = {
trigger_request.fulfillment = {
"methods": [
{
"id": "method_1",
"type": "shipping",
"line_item_ids": [li_1["id"], li_2["id"]],
"selected_destination_id": dest_id,
"groups": [{"selected_option_id": option_id}],
"groups": [
{
"id": "group_1",
"line_item_ids": [li_1["id"], li_2["id"]],
"selected_option_id": option_id,
}
],
}
]
}

payload = trigger_req.model_dump(
payload = trigger_request.model_dump(
mode="json", by_alias=True, exclude_none=True
)

Expand Down
9 changes: 4 additions & 5 deletions rest/python/server/integration_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import db
import dependencies
from fastapi.testclient import TestClient
from server import app
from server.server import app
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.ext.asyncio import create_async_engine
from sqlalchemy.orm import sessionmaker
Expand Down Expand Up @@ -91,6 +91,7 @@ class IntegrationTest(absltest.TestCase):

def setUp(self) -> None:
"""Set up the test environment, including temporary DBs and dependencies."""
flags.FLAGS(["test"])
super().setUp()
# Create a temporary directory for test databases
self.test_dir = Path(tempfile.mkdtemp())
Expand Down Expand Up @@ -226,10 +227,8 @@ def _create_checkout_payload(
) -> checkout_create_req.CheckoutCreateRequest:
"""Create a checkout payload using SDK models."""
line_items = []
for item_id, item_title, item_price, quantity in items:
item = item_create_req.ItemCreateRequest(
id=item_id, title=item_title, price=item_price
)
for item_id, _item_title, _item_price, quantity in items:
item = item_create_req.ItemCreateRequest(id=item_id)
line_item = line_item_create_req.LineItemCreateRequest(
quantity=quantity, item=item
)
Expand Down
4 changes: 2 additions & 2 deletions rest/python/server/services/checkout_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ async def create_checkout(
id=str(uuid.uuid4()),
item=ItemResponse(
id=li_req.item.id,
title=li_req.item.title,
title="",
price=0, # Will be set by recalculate_totals
),
quantity=li_req.quantity,
Expand Down Expand Up @@ -424,7 +424,7 @@ async def update_checkout(
id=li_req.id or str(uuid.uuid4()),
item=ItemResponse(
id=li_req.item.id,
title=li_req.item.title,
title="",
price=0,
),
quantity=li_req.quantity,
Expand Down
Loading