shoptet_get_order / shoptet_find_orders
Look up Shoptet orders by order number or email from Python, returning the raw Shoptet order.
shoptet_get_order(context: dict, order_number: str) -> dict | None
shoptet_find_orders(context: dict, email: str, limit: int = 10) -> list[dict]Thin helpers for the most common Shoptet read: finding a customer's order. They read the business's Shoptet connection with get_integration_credentials, call the Shoptet Premium API and return the orders as Shoptet returns them; see the Shoptet API reference for every field. A few fields a support bot should never see are left out: the customer's IP address and browser.
Both helpers raise ValueError if Shoptet isn't connected and requests.HTTPError if Shoptet rejects the request.
The full source is below. Copy it into your own action when you need something it doesn't do.
shoptet_get_order
| Name | Type | Description |
|---|---|---|
context | dict | The context object passed to your action |
order_number | str | The order code as the customer gave it. Spaces and a leading # are ignored |
Returns the matching order, or None.
shoptet_find_orders
| Name | Type | Description |
|---|---|---|
context | dict | The context object passed to your action |
email | str | The customer's email address |
limit | int | Maximum number of orders, newest first (10) |
Returns a list of orders, newest first. Empty if there are none.
Example
def execute_action(context):
order = shoptet_get_order(context, context["args"]["orderId"])
if order is None:
return {"success": False, "message": "The order could not be found."}
return {"success": True, "orders": [order]}Businesses moved off the built-in order lookups get this as their getOrderDetailsByOrderId action, together with a getOrderDetailsByEmail action that calls shoptet_find_orders. They are ordinary Python actions you can read and change.
Read-only sidebar
shoptet_order_widget(context) renders the saved order ID and customer email lookups as a basic sidebar panel without order buttons. See Order widgets for setup, custom mappings and the shared presentation source.
Source
import re
import requests
# Never returned: the customer's IP address and the client's browser.
_SHOPTET_ORDER_HIDDEN = {"clientIPAddress", "clientUserAgent"}
def _shoptet_api_key(context):
business = context.get("business") or {}
slug = business.get("slug") or (context.get("conversation") or {}).get("businessSlug")
if not slug:
raise ValueError("The business is not available in the context")
shoptet = (get_integration_credentials(context).get(slug) or {}).get("shoptetPremium")
if not shoptet:
raise ValueError("Shoptet is not connected for this business")
return shoptet["apiKey"]
def _shoptet_get(api_key, path, params=None):
response = requests.get(
f"https://api.myshoptet.com/api/{path}",
headers={"Shoptet-Private-API-Token": api_key, "Content-Type": "application/json"},
params=params or {},
timeout=20,
)
if response.status_code == 404:
return None
response.raise_for_status()
return response.json().get("data") or {}
def _shoptet_order(api_key, code):
data = _shoptet_get(api_key, f"orders/{code}")
order = (data or {}).get("order")
return {k: v for k, v in order.items() if k not in _SHOPTET_ORDER_HIDDEN} if order else None
def shoptet_get_order(context, order_number):
"""The Shoptet order with this code, or None."""
code = re.sub(r"\s+", "", str(order_number)).lstrip("#")
return _shoptet_order(_shoptet_api_key(context), code) if code else None
def shoptet_find_orders(context, email, limit=10):
"""The customer's Shoptet orders by email, newest first."""
api_key = _shoptet_api_key(context)
listed = (_shoptet_get(api_key, "orders", {"email": email.strip()}) or {}).get("orders") or []
listed.sort(key=lambda o: o.get("creationTime") or "", reverse=True)
return [order for order in (_shoptet_order(api_key, o["code"]) for o in listed[:limit]) if order]
def _shoptet_widget_order(order):
return {
"id": order.get("guid") or order.get("code"), "number": order.get("code"),
"status": (order.get("status") or {}).get("name"), "email": order.get("email"),
"total": (order.get("price") or {}).get("withVat"), "currency": (order.get("price") or {}).get("currencyCode"),
"placed_at": order.get("creationTime"),
"products": [{"name": p.get("name"), "quantity": p.get("amount"), "sku": p.get("code")}
for p in order.get("items") or []],
"shipments": [{"carrier": (s.get("shipping") or {}).get("name")}
for s in order.get("shippings") or []],
}
def shoptet_order_widget(context):
"""Read-only sidebar orders from the saved order ID and customer's email."""
return order_widget(context, get_order=shoptet_get_order, find_orders=shoptet_find_orders, map_order=_shoptet_widget_order)