Skip to content

Instantly share code, notes, and snippets.

@jessepearson
Last active September 14, 2023 10:27
Show Gist options
  • Star 23 You must be signed in to star a gist
  • Fork 9 You must be signed in to fork a gist
  • Save jessepearson/66a0e72706b99c15b52dee7ce59e1d31 to your computer and use it in GitHub Desktop.
Save jessepearson/66a0e72706b99c15b52dee7ce59e1d31 to your computer and use it in GitHub Desktop.
How to add a new custom Webhook topic in WooCommerce, with example of order filtering.
<?php // do not copy this line
/**
* add_new_topic_hooks will add a new webhook topic hook.
* @param array $topic_hooks Esxisting topic hooks.
*/
function add_new_topic_hooks( $topic_hooks ) {
// Array that has the topic as resource.event with arrays of actions that call that topic.
$new_hooks = array(
'order.custom_filter' => array(
'custom_order_filter',
),
);
return array_merge( $topic_hooks, $new_hooks );
}
add_filter( 'woocommerce_webhook_topic_hooks', 'add_new_topic_hooks' );
/**
* add_new_topic_events will add new events for topic resources.
* @param array $topic_events Existing valid events for resources.
*/
function add_new_topic_events( $topic_events ) {
// New events to be used for resources.
$new_events = array(
'custom_filter',
);
return array_merge( $topic_events, $new_events );
}
add_filter( 'woocommerce_valid_webhook_events', 'add_new_topic_events' );
/**
* add_new_webhook_topics adds the new webhook to the dropdown list on the Webhook page.
* @param array $topics Array of topics with the i18n proper name.
*/
function add_new_webhook_topics( $topics ) {
// New topic array to add to the list, must match hooks being created.
$new_topics = array(
'order.custom_filter' => __( 'Order Custom Filter', 'woocommerce' ),
);
return array_merge( $topics, $new_topics );
}
add_filter( 'woocommerce_webhook_topics', 'add_new_webhook_topics' );
/**
* my_order_item_check will check an order when it is created through the checkout form,
* if it has product ID 10603 as one of the items, it will fire off the action `custom_order_filter`
*
* @param int $order_id The ID of the order that was just created.
* @param array $posted_data Array of all of the data that was posted through checkout form.
* @param object $order The order object.
* @return null
*/
function my_order_item_check( $order_id, $posted_data, $order ) {
$order = wc_get_order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
if ( is_a( $item, 'WC_Order_Item_Product' ) ) {
if ( 10603 === $item->get_product_id() ) {
do_action( 'custom_order_filter', $order_id, $posted_data, $order );
return;
}
}
}
}
add_action( 'woocommerce_checkout_order_processed', 'my_order_item_check', 10, 3 );
/**
* The two below actions are what the order.created webhook is tied into, it is up to you to use these if you wish.
*/
// add_action( 'woocommerce_process_shop_order_meta', 'my_order_item_check' );
// add_action( 'woocommerce_api_create_order', 'my_order_item_check' );
@rickysullivan
Copy link

@chris-schertenlieb Thanks for posting back.

@jtisler - We are ignoring the failed order payloads being sent to our endpoint. The issue is if the customer fixes the failed order after getting an error message (e.g. they fat fingered their credit card number or something), the webhook doesn't fire again and we don't get a "good" order payload resent since the order was already created. That's why we wanted to set up a trigger for only when the payment is complete and all is good.

We're planning on circling back to this and do some tests with again (great rainy Memorial Day weekend here) and see if we can create on for Payment Complete status.

@jaxne Did you find a solution? I've got a similar issue. I was using the order created webhook to notify our accounting software of new orders but because the customers card was declined, the webhook only fired once. At the other end of the process I check to see if the order status is "processing" before adding the order details to our accounting system. I've created a custom webhook, it fires when I want it to, but it's not sending any payload.

"bodyRaw": "[]"

@pfriedl
Copy link

pfriedl commented Apr 9, 2021

I'm selling licenses to a web app, and managing licenses in a separate table. So I need to perform a webhook on these events:

  • subscription created at checkout
  • subscription renewal payment failed
  • subscription canceled
  • subscription reactivated

I also need to send a payload of the order ID, billing data (name, email), subscription ID and SKU. Can somebody help with this? Willing to pay for some quick work!

@Meloman-zz
Copy link

Hi all,

Anybody can help me make it for order.cancelled ?
https://stackoverflow.com/questions/68556469/woocommerce-webhook-for-canceled-order-not-fired

Thanks.

@onetarek
Copy link

Thanks for posting this. We need to send the order payload that the Order Created action does now, but only when payment is complete. Can I use this somehow to add a "Payment Complete" action option on the webhook actions dropdown form that is tied to the woocommerce_payment_complete action trigger and send the order payload at that time?

We ran into a scenario that if a customer tries to checkout but the payment fails (i.e. card declined or something else) the failed order is still created and the webhook is fired with the status of "failure". If during this transaction the customer fixes the credit card or issue with payment and the payment is successful, the order is moved to processing BUT the webhook will not resend the payload since the order was already created. That is why we'd like to see if we can tie the order payload being sent when the woocommerce_payment_complete is triggered, i.e. after the payment has gone through and is successful. Any tips or guidance would be appreciated.

Thank you!

I needed to send webhook only on order completed. I solved it in my way.
Here is my gist https://gist.github.com/onetarek/6652c0ceb04c81918b78dca5e495c49a

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment