Ai knowledge and logicHelpers

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

NameTypeDescription
contextdictThe context object passed to your action
order_numberstrThe order code as the customer gave it. Spaces and a leading # are ignored

Returns the matching order, or None.

shoptet_find_orders

NameTypeDescription
contextdictThe context object passed to your action
emailstrThe customer's email address
limitintMaximum 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)

On this page