Commera

Commera

Open in ChatGPT
Ask ChatGPT about this page
Open in Claude
Ask Claude about this page

SDK

commera.sdk is the stable Python API for plugins. Use it instead of Commera's internal modules, which can change in any release. Every read checks the session user's permissions.

Name What it does
commera.sdk.API_VERSION The API version this Commera supports, 1
commera.sdk.STORE_ORDER_TYPE "Shopping Cart", the Order Type of a store order
commera.sdk.as_plugin_user(app) Runs a block as Commera's plugin user
commera.sdk.orders.get_order Reads one order
commera.sdk.orders.get_orders Reads many orders
commera.sdk.orders.record_shipment Records a shipment for an order
commera.sdk.catalog.get_items Reads items with their store price and stock
commera.sdk.cart.get_cart Reads the session shopper's cart
commera.sdk.cart.set_cart_fields Saves your fields on the cart
commera.sdk.events.CommeraEvent The argument of an event handler. See Events

The return shapes are TypedDicts in commera.sdk.types.

get_order

from commera.sdk import orders

order = orders.get_order("SAL-ORD-2026-00062", extra_fields=["my_app_status"])
Parameter Type Value
sales_order str \| int The Sales Order name
extra_fields list[str] Your own Sales Order fields to read into plugin_fields. Each must start with your app name

Returns an Order dict:

Key Value
name, customer, customer_name, email, phone The order and its customer
shipping_address An Address dict: name, address_title, address_line1, address_line2, city, state, pincode, country, phone. The shipping address, else the billing address. None when there is neither
placed_on The transaction date
order_type The Order Type
currency, total, net_total, grand_total, rounded_total Totals in the order currency
base_grand_total, base_rounded_total Totals in the company currency
payment_mode The checkout payment mode, for example COD
is_paid, is_cancelled Booleans
status The order status that events fire on, for example Shipped
stage { key, label }, the badge that the dashboard shows
plugin_fees A list of { description, amount }, the fees that plugins added
items A list of lines: line_id (the Sales Order Item name), item_code, title, size, qty, delivered_qty, rate, amount, image
tags The order's tags
plugin_fields The values of extra_fields

Throws frappe.PermissionError when the user cannot read the order, frappe.DoesNotExistError when it does not exist, and frappe.ValidationError for a field that your plugin does not own.

get_orders

found = orders.get_orders(["SAL-ORD-2026-00062", "SAL-ORD-2026-00063"])

Returns a dict of Order keyed by the order name as a string. An order that the user cannot read, or that does not exist, is left out.

record_shipment

Records a shipment for an order: Commera creates or updates the order's Shipping Request for the AWB. It makes no Delivery Note. The order status, the order_fulfilled and order_delivered events, and the shopper's tracking page follow from it.

from commera.sdk import orders

orders.record_shipment(
	"SAL-ORD-2026-00062",
	awb="1234567890",
	carrier="Delhivery",
	tracking_url="https://example.com/track/1234567890",
	status="In Transit",
)
Parameter Type Default Value
sales_order str \| int The Sales Order name
awb str Required, keyword only. The tracking number. Commera finds the Shipping Request by order and AWB
provider str \| None None A Shipping Provider Profile name. Leave it empty when a fulfilment partner made the shipment
carrier str \| None None The carrier name the shopper sees
status str "In Transit" One of Draft, Ready To Ship, Pickup Scheduled, In Transit, Out For Delivery, Undelivered, RTO, Delivered, Cancelled, Lost
events list[dict] \| None None Tracking events to add to the shipment
tracking_url str \| None None A link the shopper can open to track the parcel

Returns the Shipping Request name.

  • A status only moves forward. A lower status than the stored one is ignored. Delivered, Cancelled and Lost are final.
  • Call it again with the same AWB to update the status, the tracking events and the tracking_url. Commera does not make a second shipment. A carrier on a later call is ignored: the first call sets it.
  • Without provider, the shipment has no origin address, because the parcel left the partner's warehouse.

Throws ShippingNotInstalled (from commera.sdk.orders) when bwh_shipping is not installed, frappe.ValidationError for an empty AWB, an unknown status or an unknown provider, and frappe.PermissionError when the user cannot read the order.

get_items

from commera.sdk import catalog

items = catalog.get_items(["TSHIRT-RED-M", "TSHIRT-RED-L"])

Returns a dict of CatalogItem keyed by item code. A code that is not an Item is left out.

Key Value
item_code, title The Item
product The template Item, or the item itself when it has no template
is_listed True when a published option on the storefront sells the item
price What a shopper pays. None until the store's price lists are set in Commera Settings
list_price The struck-through price, or None
currency The store currency
available_qty The quantity the store warehouse can sell. For an item that sells without stock, it can be 0 or less. See Gotchas

Throws frappe.PermissionError when the user cannot read Item.

get_cart and set_cart_fields

get_cart() returns the session shopper's cart, a guest's included, or None when they have no cart. The Cart dict has name, customer, currency, items (item_code, title, qty, rate, amount), total, grand_total and plugin_fields (every Quotation field that an installed Commera plugin owns).

set_cart_fields(values) saves your own Quotation fields on the cart, prices your fees again, and returns the checkout summary: subtotal, shipping, cod_charge, plugin_fees, taxes, discount_amount, rounding_adjustment, total, and the same figures for cash on delivery under cash_on_delivery.

import frappe
from commera.sdk import cart


@frappe.whitelist()
def set_gift_wrap(enabled: bool):
	return cart.set_cart_fields({"my_app_gift_wrap": int(enabled)})

set_cart_fields throws frappe.DoesNotExistError when the shopper has no cart, and frappe.ValidationError for a field that your plugin does not own, or when the cart is already paid or a payment for it is in progress.

as_plugin_user

A webhook from a partner arrives as Guest, with no permission to read orders. Run the SDK calls inside as_plugin_user:

import frappe
from commera.sdk import as_plugin_user, orders


@frappe.whitelist(allow_guest=True, methods=["POST"])
def shipment_webhook():
	payload = frappe.parse_json(frappe.request.get_data(as_text=True))
	# verify the partner's signature here before you trust the payload
	with as_plugin_user("my_app"):
		orders.record_shipment(payload["order"], awb=payload["awb"], tracking_url=payload.get("tracking_url"))

The plugin user holds every desk role. Verify the request before you enter the block. as_plugin_user throws when the plugin is not installed.

Next steps

Last updated 3 days ago
Was this helpful?
Thanks!