Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Создание и изменение заказов, HPOS

Заказы создаёт не только покупатель на сайте: их заводят по телефону, импортируют из маркетплейса, дополняют трек-номером. Для этого у объекта заказа есть методы изменения. Правило то же, что и у товаров: set_... и save(), никаких прямых запросов к базе.

Создание заказа

// wp-content/plugins/acme-shop/scripts/create-order.php
$order = wc_create_order(['customer_id' => 0]);
 
$order->add_product(wc_get_product(12), 2);
 
$order->set_address([
    'first_name' => 'Anna',
    'last_name' => 'Schmidt',
    'email' => 'anna@example.com',
    'address_1' => 'Hauptstrasse 5',
    'city' => 'Berlin',
    'postcode' => '10115',
    'country' => 'DE',
], 'billing');
 
$order->set_payment_method('cod');
$order->calculate_totals();
$order->update_status('processing', 'Заказ принят по телефону.');
 
echo 'Создан заказ ' . $order->get_id() . PHP_EOL;

wc_create_order() создаёт пустой заказ, add_product() добавляет позицию, calculate_totals() считает суммы и налоги. Запустите файл через wp eval-file: заказ на две кружки появится в «WooCommerce → Заказы» в состоянии «Обработка».

Изменение

// wp-content/plugins/acme-shop/scripts/update-order.php
$order = wc_get_order(1024);
 
$order->set_shipping_city('Hamburg');
$order->set_customer_note('Позвонить за час до доставки.');
$order->save();

Как и у товара, изменения попадают в базу только после save(). Если менялись позиции или доставка, перед сохранением вызывают calculate_totals().

Метаданные заказа

Собственные данные — трек-номер, идентификатор во внешней системе — хранят в метаданных:

// wp-content/plugins/acme-shop/includes/orders.php
add_action('woocommerce_order_status_completed', function (int $orderId, WC_Order $order) {
    if ($order->get_meta('_acme_tracking') === '') {
        $order->update_meta_data('_acme_tracking', 'AB' . $orderId);
        $order->save();
    }
}, 10, 2);

При переводе заказа в «Выполнен» в него записывается трек-номер. Проверка перед записью защищает от повторного срабатывания хука.

Заметки

$order->add_order_note('Трек-номер: AB1024', true);

Второй аргумент true делает заметку видимой покупателю: он получит письмо и увидит её в разделе «Мой аккаунт → Заказы». Без него заметка служебная и видна только в панели.

Поиск по метаданным

$orders = wc_get_orders([
    'limit' => 1,
    'meta_query' => [
        ['key' => '_acme_tracking', 'value' => 'AB1024'],
    ],
]);
 
$order = $orders[0] ?? null;

Так находят заказ по номеру из внешней системы — например, когда служба доставки сообщает о вручении.

Правила HPOS

HPOS хранит заказы в собственных таблицах, а не в wp_posts. Отсюда правила:

ВместоИспользуйте
get_post($orderId)wc_get_order($orderId)
get_post_meta($orderId, $key, true)$order->get_meta($key)
update_post_meta($orderId, $key, $value)$order->update_meta_data($key, $value) и save()
new WP_Query(['post_type' => 'shop_order'])wc_get_orders([...])
get_post_type($id) === 'shop_order'$order instanceof WC_Order

Код, который следует этим правилам, работает при любом способе хранения. Именно это обещает объявление совместимости custom_order_tables из урока о плагине.

Возврат

wc_create_refund([
    'order_id' => 1024,
    'amount' => 9.90,
    'reason' => 'Товар повреждён при доставке.',
]);

Функция создаёт возврат на указанную сумму. Когда возвращена вся сумма заказа, он переходит в состояние «Возвращён».

Частая ошибка

После update_meta_data() забывают save(). Значение есть в объекте до конца запроса, поэтому в отладке всё выглядит правильно, но в базу оно не попадает. Исключение — хуки вроде woocommerce_checkout_create_order, которые вызываются прямо перед сохранением: там save() выполнит сам WooCommerce.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.