Custom order actions in Commerce without a module
When you need Commerce to do something unique for a project, the "official" way is to create a Commerce Module. While modules are powerful, they do require a bit of boilerplate code and can be daunting if you're not familiar with them yet.
If you just need to run a quick task when an order is paid, there is a much faster way.
The Snippet Status Action acts as a hook for snippets. You write a standard MODX snippet and add it to the Commerce status workflows to trigger it. This allows you to add functional code without a full extension.
How to set up the extension
Before you can use this feature, you need to add the extension to your site.
- Download the Snippet Status Action for Commerce from the modmore package provider. It's free!
- In your MODX Manager, go to Commerce > Configuration > Modules.
- Locate the module in the list, and enable it in test and live mode.
- Navigate to Commerce > Configuration > Statuses.
- Choose a status change like Payment Received. Click the status change name, and then click Add Status Change Action.
- Give it a name, select Run a Snippet from the list, type in the name of your MODX snippet, and save.
Every time that status change runs, your snippet runs automatically. Commerce passes the $order object directly to your snippet so you have all the data you need.
Real-world examples
Not sure how to use this yet? Here are some fun examples!
1. The VIP upgrader
You can reward customers who spend over $500 in a single order by adding them to a "VIP" User Group automatically. This ensures they see special pricing the next time they log in.
/** @var comOrder $order */
$total = $order->get('total');
// Only act if they spent more than $500 (totals are in cents)
if ($total >= 50000) {
$user = $order->getOne('User');
if ($user) {
$user->joinGroup('VIP Customers');
$order->log("User added to VIP group due to high order value.");
}
}
return '';
2. The custom Slack alert
While we also have a dedicated Slack integration extension, using a snippet is a great way to learn how to send custom data to external APIs. This example sends a notification to a Slack webhook with curl.
/** @var comOrder $order */
$orderId = $order->get('id');
$amount = $order->get('total_formatted');
$message = "🎉 New Order #{$orderId} just came in for {$amount}!";
$ch = curl_init('https://hooks.slack.com/services/YOUR/WEBHOOK/URL');
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['text' => $message]));
curl_exec($ch);
curl_close($ch);
return '';
3. Identify specific products
Sometimes you need to know if a specific item was purchased to trigger a secondary process. This is useful for notifying a specialized fulfillment partner for high-touch items, notifying your team if bespoke items are purchased, or if you just want to make sure you don't miss certain orders.
/** @var comOrder $order */
$items = $order->getItems();
$targetSku = 'SPECIAL-SERVICE-01';
foreach ($items as $item) {
if ($item->get('sku') === $targetSku) {
// Trigger your custom logic here
$order->log("Special service detected. Triggering external provisioning.");
break;
}
}
return '';
4. Create a personalized coupon
You can encourage repeat business by generating a unique discount code the moment a customer’s first order is completed. This snippet creates a 10% coupon and logs the code so it can be included in a follow-up email.
/** @var comOrder $order */
$user = $order->getOne('User');
if (!$user) return '';
// Generate a random 8-character coupon code
$code = 'TY-' . strtoupper(substr(md5(uniqid()), 0, 8));
// Create the coupon using the Commerce API
$coupon = $modx->newObject('comCoupon');
$coupon->fromArray([
'code' => $code,
'discount_percentage' => 10,
'max_uses' => 1,
'active' => true,
]);
$coupon->save();
// Save the coupon to the order properties so you can access it with {{ order.properties.tycoupon_code }} in the email
$order->setProperty('tycoupon_code', $code);
$order->save();
// Log the code to the order
$order->log("Generated unique 10% coupon for customer: {$code}");
return '';
Why this is a developer’s secret weapon
Using snippets as triggers removes the need to learn the full Commerce Module API for simple tasks. If you know how to write a MODX snippet, you already know how to extend Commerce.
Testing automation can be tedious if you have to place a new test order every time you change a line of code. To speed things up, you can create a "test" status change that keeps the status exactly the same... but does trigger your snippet action again. By clicking this status button in the order dashboard, you can run your logic repeatedly on the same order until your snippet works perfectly.
Happy coding!