POST ?action=create_work_order
Creates a work order from an external source such as WooCommerce. Accepts multiple cart items each with their own intent. Does not provision lines — the work order is created for admin review or passed to submit_payment or complete_order.
Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
customer_email | string | Required | Customer email address |
status | string | Required | Initial status: pending, pending_payment, payment_submitted, completed, canceled, or payment_failed. With pending_payment on an automated gateway (Atlos, Stripe, CoinGate and the rest), the order is held out of the admin's hands until that gateway's webhook lands — the same as an order started from Panelr's own checkout. The response says so in awaiting_webhook. Hand the gateway the reference_code this call returns: that is what the webhook matches on. |
items | array | Required | One or more cart item objects — see Item Object below |
customer_name | string | Optional | Customer full name |
customer_phone | string | Optional | Customer phone number |
payment_method_id | integer | Optional | Panelr payment method ID |
payment_amount | float | Optional | Amount paid |
wc_order_id | string | Optional | WooCommerce or external order ID — attached to each cart item |
source | string | Optional | Defaults to woocommerce |
adjustment_direction | string | Optional | fee or discount. Leave all three adjustment fields out and Panelr computes the fee or discount of payment_method_id itself, from that method's settings, on the total after the coupon — the safest choice. Send them only when your checkout already charged a different amount |
adjustment_label | string | Optional | Shown on the order next to the amount |
adjustment_amount | float | Optional | The fee or discount in the store currency; recorded on the order and returned by get_work_order as adjustment |
referral_code | string | Optional | Invite code the customer arrived with (?ref). Stale codes are dropped silently; attribution happens when their login is created |
coupon_code | string | Optional | A coupon to apply to the order's money total. Unlike a stale invite code, a bad coupon fails the request (422) — it changes what the customer pays. Check first with validate_coupon. Applied as its own negative line in cart_json; credit-paid items carry no money and are not discounted |
idempotency_key | string | Optional | Your own reference for this request (defaults to wc_order_id, then payment_transaction_id). Send the same key again after a timeout or retry and you get the original order back with already: true instead of a second order |
Item Object
| Field | Type | Required | Description |
|---|---|---|---|
product_id | integer | Required | Panelr product ID |
intent | string | Required | new_activation, renewal, or trial_upgrade |
activation_id | integer | Optional* | Required for renewal and trial_upgrade |
qty | integer | Optional | Defaults to 1 |
pay_with_points | boolean | Optional | Pay for this item with the customer’s credits. The plan must be credit-priced on a participating service and the balance must cover every credit-paid item — no partial payments |
Response Fields
| Field | Type | Description |
|---|---|---|
work_order_id | integer | Work order ID |
already | boolean | true when this call matched an earlier one by idempotency_key and the original order is being returned |
reference_code | string | Human-readable reference code e.g. WO-2026-00042 |
confirmation_token | string | Unique token for use with submit_payment or get_work_order |
status | string | Work order status as submitted |
type | string | Derived from item intents — new_activation takes priority in mixed carts |
item_count | integer | Number of items in the cart |
credits_spent | integer | Credits debited for credit-paid items (0 when none) |
coupon_code | string|null | The coupon that was applied, or null |
coupon_discount | decimal | What the coupon took off the money total (0 when none) |
adjustment | object|null | The payment method's fee or discount on this order: direction, label, amount — sent by you or computed from the method; null when there is none |
order_total | decimal | What the customer pays in money: items minus coupon, then the fee or discount, never below zero. Credit-paid items are not in it |