Webhooks are one of the most common ways to integrate two apps or services between each other. Basically, a webhook is a notification that a certain event was triggered. Every webhook consists of the data about the event and the URL to which the data should be sent.
Earlier, we’ve already discussed how to add custom params to WooCommerce REST API requests. Just like many other parts of WooCommerce, the WooCommerce webhooks can be customized and modified through actions and filters.
So, as you might have guessed, today, I’m going to show you how to add custom fields to WooCommerce webhooks.
Introduction
For example, if you choose the Order created topic (event), here’s a piece of the JSON code you’ll receive on your Delivery URL:
{
"id": 70,
"parent_id": 0,
"status": "processing",
"currency": "UAH",
"version": "6.5.1",
"prices_include_tax": false,
"date_created": "2022-05-24T04:23:51",
"date_modified": "2022-05-24T04:23:51",
"discount_total": "0.00",
"discount_tax": "0.00",
"shipping_total": "0.00",
"shipping_tax": "0.00",
"cart_tax": "0.00",
"total": "55.00",
"total_tax": "0.00"
...
This JSON object contains different data about the new order. And we can modify it by adding our own field here.
So, in this post, I’m going to show you how to add custom fields to the payload objects. To make this tutorial more realistic, here’s the goal we’ll try to achieve:
- We’ve got two customer groups: premium and non-premium
- In the webhook payload, I want to check if the custom is premium
- One of the ways to do this is to add a new field to the customer object
- We’re going to add the customer_is_premium field with the boolean value
- The value of the customer_is_premium field will depend on the customer’s meta field
Let’s get started!
How to modify the payload object?
There are many different ways of implementing the logic of splitting users into groups. In our case, we’ve got two groups: premium and non-premium (or regular).
Since we need this logic to demonstrate how to modify webhook payload objects, I’ll go the easiest way: we’ll work with the is_premium user meta field. This field will be boolean, so its value will be true or false.
To add custom fields to WooCommerce webhooks, we can use the woocommerce_webhook_payload filter hook. This filter’s handlers accept four parameters: the payload object, the current resource’s name, the resource’s ID, and the webhook’s ID.
However, we’ll need only two first parameters to modify webhook payloads.
We need to modify orders’ payloads, so, first of all, in our function, we need to check if the current resource is order.
add_filter( 'woocommerce_webhook_payload', 'my_woocommerce_webhook_payload', 10, 4 );
function my_woocommerce_webhook_payload( $payload, $resource, $resource_id, $id ) {
if ( $resource !== 'order' ) {
return $payload;
}
// Our logic will be here
return $payload;
}
The payload object is a regular PHP associative array, so we can easily modify it.
add_filter( 'woocommerce_webhook_payload', 'modify_order_webhook_payload', 10, 4 );
function modify_order_webhook_payload( $payload, $resource, $resource_id, $id ) {
if ( $resource !== 'order' ) {
return $payload;
}
$customer_is_premium = false;
$customer_id = (int) $payload['customer_id'];
// All guest users will have the customer_id field set to 0
if ( $customer_id > 0 ) {
$customer_is_premium = (boolean) get_user_meta( $customer_id, 'is_premium', true );
}
$payload['customer_is_premium'] = $customer_is_premium;
return $payload;
}
Now, if I check the payload of the new order, I’ll see my new field at the end of the object:
...
"_links": {
"self": [
{
"href": "https://test.com/wp-json/wc/v3/orders/81"
}
],
"collection": [
{
"href": "https://test.com/wp-json/wc/v3/orders"
}
],
"customer": [
{
"href": "https://test.com/wp-json/wc/v3/customers/1"
}
]
},
"customer_is_premium": true
}
So, I guess you get the idea: if you’ll need to modify user payloads or coupon payloads, just check the current resource and add your fields to the $payload array.
The same logic can be applied if you need to change any already existing fields.
Summary
As you see, all you need to modify WooCommerce webhook payloads is to know the right hook 🙂
I hope you found the answers you were looking for. Otherwise, feel free to write about your issues in the comments or even contact me directly.
Subscribe to my Twitter account to stay updated with new posts and tweets on things I learn or do.
Thank you for your attention; see you in the next one!
Thanks for the post. I’m completely new to WordPress, so I’m not entirely sure where exactly we’d place this code. Would I put this in the functions.php file?
How would I go about appending all the details of an order on order creation to a woocommerce_payment_complete payload? Thank you kindly.
Hi Alexandros! Yes, you can add this code to functions.php, or you can create a plugin (there’s a lot of tutorials on how to create your first simple plugin). About the woocommerce_payment_complete payload: it really depends on what data you need to add because “all the details” is a pretty vague description. However, my post gives a basic explanation of how to add custom fields to webhook payloads, so you can use my code to add additional fields containing the missing order’s data you need.
Thanks a bunch for the response! I’m slowly starting to get how WordPress works, and I’m honestly impressed by how much customization you can actually do. Was just having a tough time figuring out how to make modifications, but I think I’ve finally figured it out.
Thanks once again!
Thanks for this. It was really helpful.
You’re welcome; glad I could help 🙂
Hi kayart, loved your post, I have a question, what if I want to display data from the product custom attribute that can be added when editing the product in woocommerce?
Hello, Gabriel, thank you for your comment! Do you mean the regular product attributes? Or do you use some custom plugins for editable options?
The regular, I’m trying to stay away from plugins which is why I was looking for a solution for this
Got you. Well, you’ll have to write some custom code depending on what exactly you want to achieve. I don’t think that the comments section is the best place to discuss it, but feel free to email me on @kayart.dev">artemy@kayart.dev
Thanks! I sent you an email
Thank you for the post.
I have a similar problem. I create a webhook under woocommerce to send the content of an order (order.created event webhook).
The content of the json contains ll the fields of the order. I only need a subset of them because there are many fields that I do not use.
How can I filter the json to keep only some fields (id, who ordered, list of items ordered for example) and send only that to the url ?
Any tip would be useful.
Regards,
Hello Alain! In this post, I described how you can add custom fields to they $payload object by using the woocommerce_webhook_payload hook. You can use the same hook and the same object to remove the fields you don’t need. The only difference is that you need to use unset($payload[‘field_name’]) instead of creating a new one.
Thank you very much for the indication. I’ll try that!
Regards
What if I wanted use the payload to display some value from the database?
Hey Gabriel! Talking about your issue, here’s what I think:
1) First of all, you need to get an order item’s attribute value. You can use this answer from WordPress StackExchange as a reference on how to get a variation’s attribute value:
https://wordpress.stackexchange.com/a/380680/191232
2) Now, all you need to do is to use my post and add your custom field to the payload 🙂
Sorry for waiting 🙂
Thanks for the Post , I’ve a Question how to get full country name and full state name in Json response instead of country code and state code
Thanks in Advance
Hi! Take a look at this thread on StackOverflow:
https://stackoverflow.com/questions/25528454/getting-country-name-from-country-code-in-woocommerce