Custom WooCommerce Webhook Topic

I need to send WooCommerce webhook requests only when an order is completed. But WooCommerce does not have any webhook topic for order completion. I created the custom topic ‘Custom Order Completed‘. Here is my code below.

<?php
/*
Custom WC Webhook Manager
Add new webhook topic only for WC order completed.
Developed by Md Jahidul Islam ( oneTarek ) https://onetarek.com
*/
//Don't allow direct access
if( ! defined( 'ABSPATH' ) ) exit;
if( ! class_exists( 'Custom_WC_Webhook_Manager' ) ) :
class Custom_WC_Webhook_Manager {
public function __construct() {
add_filter('woocommerce_webhook_topics', array( $this, 'add_custom_webhook_topics' ), 10, 1 );
add_action('woocommerce_order_status_completed', array( $this, 'on_woocommerce_order_status_completed' ), 10, 2 );
add_filter('woocommerce_webhook_payload', array( $this, 'add_custom_webhook_payload' ), 10, 4 );
}
/*
Custom topics must start with 'action.woocommerce_' or 'action.wc_'
described in the function wc_is_webhook_valid_topic
If the topic name starts with 'action' then there must has a wp hook named with the string used after dot(.)
So for this Topic we must have a wp hook 'wc_custom_order_completed'.
Adding custom topic hooks using filter 'woocommerce_webhook_topic_hooks' does not work here.
*/
public function add_custom_webhook_topics( $topics ){
$topics['action.wc_custom_order_completed'] = 'Custom Order completed';
return $topics;
}
//Trigger wc_custom_order_completed hook on woocommerce_order_status_completed hook.
public function on_woocommerce_order_status_completed( $order_id, $order ){
//We could use 'woocommerce_order_status_completed' hook name directly with the topic name.
//But we are not using that direclty because , if in future WC pluign add new topic using that hook.
do_action('wc_custom_order_completed', $order_id, $order );
}
/*
* Set payload for our custom topic.
*/
public function add_custom_webhook_payload( $payload, $resource, $resource_id, $webhook_id ) {
if( isset( $payload['action'] ) && $payload['action'] == 'wc_custom_order_completed' && !empty( $payload['arg'] ) ) {
$webhook = wc_get_webhook( $webhook_id );
// Build the payload with the same user context as the user who created
// the webhook — this avoids permission errors as background processing
// runs with no user context.
//See build_payload() in woocommerce/includes/class-wc-webhook.php
$current_user = get_current_user_id();
wp_set_current_user( $webhook->get_user_id() );
$version = str_replace( 'wp_api_', '', $webhook->get_api_version() );
$resource = 'order';
$payload = wc()->api->get_endpoint_data( "/wc/{$version}/{$resource}s/{$resource_id}" );
// Restore the current user.
wp_set_current_user( $current_user );
}
return $payload;
}
}//end class
endif;
$Custom_WC_Webhook_Manager = new Custom_WC_Webhook_Manager();

3 Comments


  1. Thank you very much for the information.

    I am looking for how to send the information found in the cart, product name, quantity, price.

    I wish you could create a template to add any action that is not in the default woocommerce webhooks

    Reply

  2. Thank you for the code, but where have i to place it?

    I successfully tried the Plugin “Code Snippets” to integrate this code easily.

    Also i use the Plugin “Ni WooCommerce Custom Order Status”

    Any idea how to get the user defined order status in the webhook?

    (AND i forget how to get/create the woocommerce webhook secret, but this will woocomerce automaticaly insert 🙂 … next time i hope to remember if i read this again )

    Thank you very much.

    Reply

  3. Need to send order data to third party URL when order created in woocommerce

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

 

This site uses Akismet to reduce spam. Learn how your comment data is processed.