-
-
Save onetarek/6652c0ceb04c81918b78dca5e495c49a to your computer and use it in GitHub Desktop.
<?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(); | |
I asked chatgpt
can you tell me if the custom woocommerce webhook shown here creates the same payload as the built in "order created" webhook? and it said:
To determine if the custom WooCommerce webhook creates the same payload as the built-in "order created" webhook, we need to compare the payload structures and data they send.
Here's the built-in "order created" webhook payload structure:
{
"id": 123,
"parent_id": 0,
"status": "processing",
"order_key": "wc_order_1234567890abcdef",
"number": "123",
"currency": "USD",
"version": "5.1.0",
"prices_include_tax": false,
"date_created": "2021-04-06T13:17:50",
"date_created_gmt": "2021-04-06T17:17:50",
"date_modified": "2021-04-06T13:17:50",
"date_modified_gmt": "2021-04-06T17:17:50",
"discount_total": "0.00",
"discount_tax": "0.00",
"shipping_total": "10.00",
"shipping_tax": "0.00",
"cart_tax": "0.00",
"total": "60.00",
"total_tax": "0.00",
"customer_id": 2,
"order_currency": "USD",
"meta_data": [],
"line_items": [],
"tax_lines": [],
"shipping_lines": [],
"fee_lines": [],
"coupon_lines": [],
"refunds": [],
"payment_method": "bacs",
"payment_method_title": "Direct Bank Transfer",
"transaction_id": "",
"customer_ip_address": "127.0.0.1",
"customer_user_agent": "Mozilla/5.0",
"created_via": "checkout",
"customer_note": "",
"date_completed": null,
"date_paid": null,
"cart_hash": "",
"number": "123",
"meta_data": [],
"_links": {
"self": [],
"collection": []
}
}
Now let's look at the custom webhook code from the provided link:
<?php
add_action( 'woocommerce_thankyou', 'custom_order_created_webhook', 10, 1 );
function custom_order_created_webhook( $order_id ) {
$order = wc_get_order( $order_id );
$webhook_payload = array(
'id' => $order->get_id(),
'parent_id' => $order->get_parent_id(),
'status' => $order->get_status(),
'order_key' => $order->get_order_key(),
'currency' => $order->get_currency(),
'version' => $order->get_version(),
'prices_include_tax' => $order->get_prices_include_tax(),
'date_created' => $order->get_date_created()->date('Y-m-d\TH:i:s'),
'date_created_gmt' => $order->get_date_created()->date('Y-m-d\TH:i:s\Z'),
'date_modified' => $order->get_date_modified()->date('Y-m-d\TH:i:s'),
'date_modified_gmt' => $order->get_date_modified()->date('Y-m-d\TH:i:s\Z'),
'discount_total' => $order->get_discount_total(),
'discount_tax' => $order->get_discount_tax(),
'shipping_total' => $order->get_shipping_total(),
'shipping_tax' => $order->get_shipping_tax(),
'cart_tax' => $order->get_cart_tax(),
'total' => $order->get_total(),
'total_tax' => $order->get_total_tax(),
'customer_id' => $order->get_customer_id(),
'order_currency' => $order->get_currency(),
'payment_method' => $order->get_payment_method(),
'payment_method_title' => $order->get_payment_method_title(),
'transaction_id' => $order->get_transaction_id(),
'customer_ip_address' => $order->get_customer_ip_address(),
'customer_user_agent' => $order->get_customer_user_agent(),
'created_via' => $order->get_created_via(),
'customer_note' => $order->get_customer_note(),
'date_completed' => $order->get_date_completed() ? $order->get_date_completed()->date('Y-m-d\TH:i:s') : null,
'date_paid' => $order->get_date_paid() ? $order->get_date_paid()->date('Y-m-d\TH:i:s') : null,
'cart_hash' => $order->get_cart_hash(),
'line_items' => array(),
'tax_lines' => array(),
'shipping_lines' => array(),
'fee_lines' => array(),
'coupon_lines' => array(),
'refunds' => array()
);
$webhook_url = 'https://example.com/webhook';
$response = wp_remote_post( $webhook_url, array(
'method' => 'POST',
'body' => json_encode( $webhook_payload ),
'headers' => array(
'Content-Type' => 'application/json'
)
));
}
?>
The custom webhook payload is constructed using data from the WooCommerce order object, similar to the built-in webhook. However, a few differences exist:
-
Field Differences:
- The custom webhook includes 'number' within 'webhook_payload'.
- The built-in webhook includes '_links' which is missing from the custom webhook.
-
Data Formatting:
- Dates in the custom webhook are formatted explicitly using the
date('Y-m-d\TH:i:s')
format, ensuring proper datetime formatting.
- Dates in the custom webhook are formatted explicitly using the
-
Empty Arrays:
- 'meta_data' in the built-in webhook is an empty array, but the custom webhook does not include it in 'webhook_payload'.
- 'line_items', 'tax_lines', 'shipping_lines', 'fee_lines', 'coupon_lines', and 'refunds' are included as empty arrays in the custom webhook. In contrast, these fields are included as empty arrays in the built-in webhook if there is no data.
To summarize, while the custom webhook is similar in structure to the built-in "order created" webhook, there are slight differences in fields and data formatting. Specifically, the custom webhook is missing the '_links' field and includes the 'number' field twice. Other fields such as 'meta_data' and arrays like 'line_items', 'tax_lines', etc., are included but empty.
For complete parity, you would need to ensure all fields match exactly, including the '_links' field and ensure no duplicate fields are present.
So I really don't know what that means, and I don't know if I can use it instead of Order Created ?
Can you tell me if the payload from your custom order complete webhook is the same as the core order created webhook? Thank you