POST ?action=complete_order
Creates a work order from a confirmed automatic payment and queues it for immediate provisioning. Use this for non-manual gateways (Stripe, PayPal, etc.) where payment is confirmed automatically. The line is provisioned within approximately 1 minute.
For manual payment methods, use create_work_order instead.
An order Panelr already created (its checkout handed the customer to your store with ?panelr_ref and ?panelr_token): send only confirmation_token, payment_transaction_id and payment_amount. The order is marked paid and queued; nothing is created twice, and a repeat call answers already: true.
Request Parameters
| Field | Type | Required | Description |
|---|---|---|---|
confirmation_token | string | Optional | The token of an order Panelr's own checkout created. When sent, every other field but payment_transaction_id, payment_amount and payment_method_id is ignored |
customer_email | string | Required | Customer email address |
payment_method_id | integer | Requiredunless every item is paid with credits, or is_free | Panelr payment method ID — the gateway that took the money. Omit when the whole order is paid with credits (pay_with_points): the debit is the payment |
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 |
customer_address | string | Optional | Customer address |
payment_transaction_id | string | Optional | Your transaction or order 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 | Where the order came from, as the admin sees it (e.g. your site's name). Default: woocommerce |
is_free | boolean | Optional | Set true to skip payment method validation for free orders |
bouquet_ids | array | Optional | Explicit bouquet IDs to assign. Must belong to the same service as the product — ids from another service mean nothing to that panel |
categories | array | Optional | Category filter: live, vod, series |
notes | string | Optional | Internal admin notes |
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 |
status | string | Always queued |
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) |