Orders
An order is a record of what the customer bought, for how much and where to deliver it. On the storefront orders are handled by the core model checkout/order: it creates the order, changes its status and keeps the history. An extension usually reads orders and reacts to a status change.
Where to look
| What | Where |
|---|---|
| The model | catalog/model/checkout/order.php |
| The tables | oc_order, oc_order_product, oc_order_total, oc_order_history |
| In the admin panel | Sales → Orders |
Reading an order
$this->load->model('checkout/order');
$order = $this->model_checkout_order->getOrder(1024);
if ($order) {
$email = $order['email'];
$statusId = (int) $order['order_status_id'];
$total = $this->currency->format($order['total'], $order['currency_code'], $order['currency_value']);
}getOrder() returns an array with the order fields or an empty array. The sum is stored in the default currency of the shop, so for output the code and the rate of the order currency are passed — the customer sees the same number as at checkout.
The products of the order are returned by a separate method of the same model, getProducts($orderId).
Statuses
Statuses are edited in System → Localisation → Order Statuses: «Pending», «Processing», «Shipped», «Complete». In code their ids are not written as numbers — they are taken from the shop settings:
$newOrderId = (int) $this->config->get('config_order_status_id');
$processing = (array) $this->config->get('config_processing_status');
$complete = (array) $this->config->get('config_complete_status');The first is the status a new order gets. The other two are lists of ids the shop treats as «being processed» and «completed»; they are set in System → Settings, the Option tab.
Changing the status
$this->model_checkout_order->addHistory(1024, $shippedStatusId, 'Handed to the courier. Tracking number: AB123456789', true);| Argument | Meaning |
|---|---|
| First | Id of the order |
| Second | Id of the new status |
| Third | Comment |
| Fourth | Whether to email the customer |
Open the order in Sales → Orders — the history tab has a new row with the comment. addHistory() does more than write the row: on the first real status it reduces the stock and sends the order email.
When an order counts as placed
The order is written to the database at the confirmation step of the checkout — with the status 0. Such orders are not shown in the admin panel: the customer may still leave. The order becomes placed when the payment method calls addHistory() with a real status.
That is why a «new order» is caught with the event addHistory/after, not addOrder/after:
// trigger: catalog/model/checkout/order.addHistory/after
public function orderHistory(string &$route, array &$args): void
{
[$orderId, $statusId] = $args;
$this->log->write('Order ' . (int) $orderId . ' got status ' . (int) $statusId);
}Place a test order on the storefront — the error log gets a line with its number and status.
Common mistake
The status is changed with a direct query: UPDATE oc_order SET order_status_id = .... The history is not written, the stock is not reduced, the customer gets no email, and events of other extensions do not fire. Change the status only through addHistory().