Commit 00e37fea518 for woocommerce
commit 00e37fea518432e9c2706809b7bb67f9f0dc6950
Author: Thomas Roberts <5656702+opr@users.noreply.github.com>
Date: Wed Sep 16 10:43:58 2026 +0100
Clarify checkout hook payment timing (#68757)
* Clarify Store API checkout hook payment timing
* Add changelog entry for Store API hook docs
* Document classic checkout hook payment timing
* Update changelog for classic checkout hook docs
diff --git a/plugins/woocommerce/changelog/wooplug-7682-clarify-store-api-order-processed-hook b/plugins/woocommerce/changelog/wooplug-7682-clarify-store-api-order-processed-hook
new file mode 100644
index 00000000000..dce85203a21
--- /dev/null
+++ b/plugins/woocommerce/changelog/wooplug-7682-clarify-store-api-order-processed-hook
@@ -0,0 +1,3 @@
+Significance: patch
+Type: dev
+Comment: Clarify that the classic and Store API checkout order processed hooks fire before payment and must not run payment-completion logic.
diff --git a/plugins/woocommerce/client/blocks/docs/third-party-developers/extensibility/hooks/actions.md b/plugins/woocommerce/client/blocks/docs/third-party-developers/extensibility/hooks/actions.md
index 7b505716b8c..c22d42738dd 100644
--- a/plugins/woocommerce/client/blocks/docs/third-party-developers/extensibility/hooks/actions.md
+++ b/plugins/woocommerce/client/blocks/docs/third-party-developers/extensibility/hooks/actions.md
@@ -867,7 +867,7 @@ do_action( 'woocommerce_store_api_checkout_order_processed', \WC_Order $order )
### Description
-The action runs before payment is processed, so callbacks can still act on the order on its way to the gateway.
+The action runs before payment is processed, so callbacks can still act on the order on its way to the gateway. Do not use this action for payment-completion logic or to call WC_Order::payment_complete(). Use woocommerce_payment_complete or woocommerce_order_status_completed instead.
This is similar to existing core hook woocommerce_checkout_order_processed. We're using a new action:
diff --git a/plugins/woocommerce/includes/class-wc-checkout.php b/plugins/woocommerce/includes/class-wc-checkout.php
index 418d0e7d579..e7a1f17b843 100644
--- a/plugins/woocommerce/includes/class-wc-checkout.php
+++ b/plugins/woocommerce/includes/class-wc-checkout.php
@@ -1438,6 +1438,18 @@ class WC_Checkout {
array( 'order_object' => $order )
);
+ /**
+ * Fires after the checkout creates the order, but before payment is processed.
+ *
+ * Do not use this action for payment-completion logic or to call WC_Order::payment_complete().
+ * Use woocommerce_payment_complete or woocommerce_order_status_completed instead.
+ *
+ * @since 1.1.0
+ *
+ * @param int $order_id Order ID.
+ * @param array $posted_data Posted checkout data.
+ * @param WC_Order|WC_Order_Refund $order Order object.
+ */
do_action( 'woocommerce_checkout_order_processed', $order_id, $posted_data, $order );
wc_log_order_step(
diff --git a/plugins/woocommerce/src/StoreApi/Routes/V1/Checkout.php b/plugins/woocommerce/src/StoreApi/Routes/V1/Checkout.php
index 0010020a7b5..013d662ef3e 100644
--- a/plugins/woocommerce/src/StoreApi/Routes/V1/Checkout.php
+++ b/plugins/woocommerce/src/StoreApi/Routes/V1/Checkout.php
@@ -688,7 +688,9 @@ class Checkout extends AbstractCartRoute {
* Fires after the Checkout Block/Store API request has populated and validated the order.
*
* The action runs before payment is processed, so callbacks can still act on the order
- * on its way to the gateway.
+ * on its way to the gateway. Do not use this action for payment-completion logic or to
+ * call WC_Order::payment_complete(). Use woocommerce_payment_complete or
+ * woocommerce_order_status_completed instead.
*
* This is similar to existing core hook woocommerce_checkout_order_processed. We're using a new action:
* - To keep the interface focused (only pass $order, not passing request data).
diff --git a/plugins/woocommerce/src/StoreApi/Routes/V1/CheckoutOrder.php b/plugins/woocommerce/src/StoreApi/Routes/V1/CheckoutOrder.php
index db93be762f4..87868393ce3 100644
--- a/plugins/woocommerce/src/StoreApi/Routes/V1/CheckoutOrder.php
+++ b/plugins/woocommerce/src/StoreApi/Routes/V1/CheckoutOrder.php
@@ -144,7 +144,9 @@ class CheckoutOrder extends AbstractCartRoute {
* Fires after the Checkout Block/Store API request has populated and validated the order.
*
* The action runs before payment is processed, so callbacks can still act on the order
- * on its way to the gateway.
+ * on its way to the gateway. Do not use this action for payment-completion logic or to
+ * call WC_Order::payment_complete(). Use woocommerce_payment_complete or
+ * woocommerce_order_status_completed instead.
*
* This is similar to existing core hook woocommerce_checkout_order_processed. We're using a new action:
* - To keep the interface focused (only pass $order, not passing request data).