2026年7月2日
2026年7月2日
WooCommerceの注文ステータスをカスタマイズ・修正する方法
はじめに
WooCommerceの注文ステータスが自動で変わらない・カスタムステータスを追加したい・特定のステータス変更時に処理を実行したい問題は、ステータスの登録方法・フックのタイミング・権限設定が原因です。
症状・原因
- 注文が「保留中」から「処理中」に自動で変わらない
- 独自の注文ステータス(例:「梱包中」)を追加したい
- ステータス変更時に自動でメールを送りたい
- 特定のステータスから他のステータスへの変更を制限したい
解決手順
ステップ1:注文ステータスの現状を確認する
# 現在の注文ステータス一覧を確認
wp eval "
\$statuses = wc_get_order_statuses();
foreach (\$statuses as \$slug => \$label) {
printf('%s: %s' . PHP_EOL, \$slug, \$label);
}
"
# 特定の注文のステータス変更履歴を確認
wp eval "
\$order = wc_get_order(123);
foreach (\$order->get_notes() as \$note) {
if (str_contains(\$note->comment_content, 'ステータス') || str_contains(\$note->comment_content, 'status')) {
echo \$note->comment_date . ': ' . \$note->comment_content . PHP_EOL;
}
}
"
# 特定ステータスの注文数を確認
wp eval "
\$statuses = ['pending', 'processing', 'on-hold', 'completed', 'cancelled', 'refunded', 'failed'];
foreach (\$statuses as \$status) {
\$orders = wc_get_orders(['status' => \$status, 'limit' => -1]);
printf('%s: %d件' . PHP_EOL, \$status, count(\$orders));
}
"
ステップ2:カスタム注文ステータスを追加する
// functions.php: カスタム注文ステータスを登録
// ① WordPress のポストステータスとして登録
add_action('init', function(): void {
register_post_status('wc-packing', [
'label' => '梱包中',
'public' => true,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'exclude_from_search' => false,
'label_count' => _n_noop('梱包中 <span class="count">(%s)</span>', '梱包中 <span class="count">(%s)</span>'),
]);
register_post_status('wc-shipped', [
'label' => '発送済み',
'public' => true,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'exclude_from_search' => false,
'label_count' => _n_noop('発送済み <span class="count">(%s)</span>', '発送済み <span class="count">(%s)</span>'),
]);
});
// ② WooCommerceのステータス一覧に追加
add_filter('woocommerce_order_statuses', function(array $order_statuses): array {
$new_statuses = [];
foreach ($order_statuses as $key => $status) {
$new_statuses[$key] = $status;
// 「処理中」の後に「梱包中」「発送済み」を挿入
if ($key === 'wc-processing') {
$new_statuses['wc-packing'] = '梱包中';
$new_statuses['wc-shipped'] = '発送済み';
}
}
return $new_statuses;
});
// ③ カスタムステータスの色をアイコン付きで設定
add_action('admin_head', function(): void {
echo '<style>
.order-status.status-packing { background: #f0e6ff; color: #7c3aed; }
.order-status.status-shipped { background: #d1fae5; color: #059669; }
mark.order-status.status-packing::before { content: "\\f526"; }
mark.order-status.status-shipped::after { content: " ✈"; }
</style>';
});
ステップ3:ステータス変更時に処理を実行する
// functions.php: 注文ステータス変更時のフック
// ① 特定のステータスに変わったときに処理
add_action('woocommerce_order_status_shipped', function(int $order_id): void {
$order = wc_get_order($order_id);
if (!$order) return;
// 追跡番号メタを確認
$tracking = $order->get_meta('_tracking_number');
// 顧客に発送完了メールを送信
WC()->mailer()->emails['WC_Email_Customer_Completed_Order']->trigger($order_id);
// 注文にメモを追加
$order->add_order_note(
sprintf('発送済みに変更しました。追跡番号: %s', $tracking ?: '未設定'),
true // 顧客に表示
);
});
// ② ステータスが「from」から「to」に変わったとき
add_action('woocommerce_order_status_changed', function(int $order_id, string $from, string $to): void {
if ($from === 'processing' && $to === 'packing') {
// 倉庫システムに通知
$order = wc_get_order($order_id);
wp_remote_post('https://warehouse.example.com/api/orders', [
'body' => json_encode([
'order_id' => $order_id,
'items' => array_map(fn($item) => [
'sku' => $item->get_product()->get_sku(),
'qty' => $item->get_quantity(),
], array_values($order->get_items())),
]),
'headers' => ['Content-Type' => 'application/json'],
]);
}
}, 10, 3);
// ③ カスタムステータスでも在庫を減らす
add_filter('woocommerce_payment_complete_order_status', function(string $status, int $order_id): string {
return 'packing'; // 支払い完了後は「梱包中」に
}, 10, 2);
ステップ4:注文ステータスをプログラムで変更する
// functions.php: 注文ステータスを一括変更
// ① 単一注文のステータスを変更
function update_order_status(int $order_id, string $new_status, string $note = ''): bool {
$order = wc_get_order($order_id);
if (!$order) {
return false;
}
$order->update_status($new_status, $note, true);
return true;
}
// ② 複数注文を一括でステータス変更
function bulk_update_order_status(array $order_ids, string $new_status): int {
$updated = 0;
foreach ($order_ids as $order_id) {
$order = wc_get_order($order_id);
if ($order && $order->update_status($new_status)) {
$updated++;
}
}
return $updated;
}
# 特定条件の注文を一括でステータス変更
wp eval "
// 7日以上「保留中」の注文をキャンセルに
\$old_orders = wc_get_orders([
'status' => 'pending',
'date_before' => date('Y-m-d', strtotime('-7 days')),
'limit' => 50,
]);
foreach (\$old_orders as \$order) {
\$order->update_status('cancelled', '7日以上保留のため自動キャンセル');
}
echo count(\$old_orders) . '件をキャンセルしました';
"
ステップ5:カスタムステータス用のメールを設定する
// functions.php: カスタムステータス用のWooCommerceメールを登録
add_filter('woocommerce_email_classes', function(array $email_classes): array {
require_once get_stylesheet_directory() . '/includes/class-wc-email-shipped.php';
$email_classes['WC_Email_Customer_Shipped'] = new WC_Email_Customer_Shipped();
return $email_classes;
});
// includes/class-wc-email-shipped.php
class WC_Email_Customer_Shipped extends WC_Email {
public function __construct() {
$this->id = 'customer_shipped';
$this->title = '発送済み通知';
$this->description = '注文が発送済みになった時に顧客へ送信';
$this->heading = 'ご注文が発送されました';
$this->subject = '【発送完了】{site_title} ご注文 #{order_number}';
$this->template_html = 'emails/customer-shipped-order.html';
$this->template_plain = 'emails/plain/customer-shipped-order.php';
$this->placeholders = [
'{site_title}' => $this->get_blogname(),
'{order_number}' => '',
];
$this->trigger_on = ['shipped'];
add_action('woocommerce_order_status_shipped_notification', [$this, 'trigger'], 10, 2);
parent::__construct();
}
public function trigger(int $order_id, ?WC_Order $order = null): void {
if (!$order) {
$order = wc_get_order($order_id);
}
$this->recipient = $order->get_billing_email();
$this->send($this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), []);
}
}
注意事項
- カスタムステータスのスラッグは
wc-プレフィックスが必要です(例:wc-packing)。register_post_status()に渡すときもwc-packingで登録し、update_status()に渡すときはpacking(wc-なし)で渡します woocommerce_order_status_{status}フックの{status}部分はwc-プレフィックスなしのステータス名です(例:woocommerce_order_status_shipped)- カスタムステータスに対応したメールクラスを作成する場合、テンプレートファイルもテーマの
woocommerce/emails/ディレクトリに用意する必要があります
まとめ
WooCommerce注文ステータスのカスタマイズは①wc_get_order_statuses()で現状を確認、②register_post_status('wc-packing', [...])で独自ステータスを登録しwoocommerce_order_statusesフィルターで一覧に追加、③woocommerce_order_status_shippedフックでステータス変更時の処理(メール送信・外部API連携)を実装、④order->update_status()で個別・一括ステータス変更を実行、⑤woocommerce_email_classesフィルターでカスタムステータス用のメールクラスを登録します。