Skip to main content
Version: 2.0.0

Flow Manager — Actions Reference

This page is the developer-level reference for Flow Manager actions in yStore v2.2.1. For an overview of how flows work, see Flow Manager.


Architecture

Class hierarchy

Every built-in action extends AbstractActionDefinition, which implements StepDefinitionInterface. Actions that can be executed also implement ExecutableActionInterface.

StepDefinitionInterface
└── AbstractStepDefinition (shared helpers, toArray())
└── AbstractActionDefinition (TYPE = 'action')
└── YourAction implements ExecutableActionInterface

All class paths are under the yui\craft\flow namespace:

Class / InterfaceNamespace path
StepDefinitionInterfaceyui\craft\flow\steps
AbstractStepDefinitionyui\craft\flow\steps
AbstractActionDefinitionyui\craft\flow\steps
ExecutableActionInterfaceyui\craft\flow\executors
FlowContextyui\craft\flow
NodeResultyui\craft\flow
RegisterFlowDefinitionsEventyui\craft\events

StepDefinitionInterface — required methods

Every action must implement these static methods:

MethodReturn typePurpose
handle()stringMachine-readable identifier used in flow JSON (kebab-case)
name()stringHuman-readable label shown in the flow editor
description()stringLong description shown in the node panel
summary()stringShort one-liner; defaults to description()
when()stringWhen-to-use guidance (optional, defaults to empty)
how()stringHow-it-works text (optional, defaults to empty)
usageExamples()string[]Bullet-point examples shown in the editor
fields()array[]Field definitions — see field schema
toArray()arraySerialised representation for the flow editor API

AbstractStepDefinition provides sensible defaults for all optional methods.

Additional static methods from AbstractStepDefinition:

MethodDefaultPurpose
category()'general'Groups the action in the node picker sidebar
icon()'default'Icon handle shown in the editor
outputVariables()[]Keys this action writes to NodeResult::$data
outputHandles()['default']Connection output slots (e.g. ['true','false'] for branches)
inputHandles()['default']Connection input slots

Field schema

Each element in the fields() array describes one configuration field in the node editor.

KeyTypeDescription
handlestringRequired. Key used in $properties inside execute()
labelstringRequired. Field label in the editor
typestringRequired. See field types below
requiredboolWhether the field must be filled. Default false
defaultmixedPre-filled default value
instructionsstringHelp text below the field
placeholderstringPlaceholder hint inside the input
optionsarrayFor select / selectize — array of ['value'=>…,'label'=>…]
minint|floatFor number — minimum value
maxint|floatFor number — maximum value
stepfloatFor number — step increment

Field types:

TypeRendered as
textSingle-line text input
textareaMulti-line text area
numberNumeric input
selectDropdown
selectizeSearchable select
lightswitchToggle (boolean)
booleanCheckbox
urlURL input with validation
credentialCredential handle picker

All text and textarea fields support Twig tokens referencing the flow context (e.g. {{ customer.email }}, {{ order.reference }}).

FlowContext API

FlowContext is the shared data bus for a flow run. It is passed to execute() and can be read and written by any action.

MethodSignatureDescription
getget(string $key, mixed $default = null): mixedRead a context value
setset(string $key, mixed $value): voidWrite a context value
hashas(string $key): boolCheck key existence
mergemerge(array $data): voidBulk-import an array
allall(): arrayReturn all context data (used for Twig rendering)
isDryRunisDryRun(): boolTrue when the flow is running in test/preview mode

Public properties:

PropertyTypeDescription
$runFlowRunModelThe current flow run record
$flowFlowModelThe flow definition

NodeResult API

Return a NodeResult from execute() to signal success or failure.

Static constructorDescription
NodeResult::success(array $data, string $message, string $outputHandle)Mark node as succeeded; $data keys become output variables
NodeResult::failure(string $message, string $outputHandle)Mark node as failed; stops the current branch
NodeResult::paused(string $message)Pause the run at this node (used by delay / wait nodes)

The outputHandle parameter controls which outgoing connection the flow follows next (e.g. 'default', 'true', 'false'). Default is 'default'.


Built-in actions reference

Actions are grouped by category as they appear in the flow editor node picker.

Communication

send-email — Send Email

Send a personalised email to one or more recipients using a system template, a Marketing Email Template, or a custom Twig template path.

FieldTypeRequiredDescription
recipientstextYesComma-separated addresses or Twig tokens resolving to addresses
subjecttextYesEmail subject line. Twig tokens supported
templateHandleselectizeNoSystem or marketing template handle. Prefix marketing:<id> for marketing templates
templatePathtextNoPath to a custom Twig template (used when templateHandle is empty)
delayMinutesnumberNoMinutes to wait before dispatch. Default 0

Output variables: sentTo (array of addresses), subject

Template resolution

templateHandle takes precedence over templatePath. A value prefixed marketing:<id> resolves to a Marketing Email Template from yStore → Marketing → Flows → Templates. System handles are resolved through EmptyTemplate::getEmailTemplateByHandle().

send-email-template — Send Email Template

Simpler variant that sends a saved marketing template by handle.

FieldTypeRequiredDescription
templateHandletextYesHandle of the marketing email template
totextYesRecipient email address. Twig tokens supported

Output variables: templateHandle, to, sent

send-sms — Send SMS

FieldTypeRequiredDescription
phoneNumbertextYesRecipient phone number. Twig tokens supported
messagetextYesSMS body (max 160 characters recommended). Twig tokens supported
providerselectNotwilio (default), vonage, or generic
fromtextNoSender ID or phone number
providerEndpointurlNoCustom endpoint for generic provider
apiKeytextNoAPI key or account SID. Twig tokens supported
apiSecrettextNoAPI secret or auth token

send-push-notification — Send Push Notification

FieldTypeRequiredDescription
providerselectYesfirebase (FCM), onesignal, or custom
titletextYesNotification title. Twig tokens supported
bodytextareaYesNotification body. Twig tokens supported
urltextNoAction URL opened on tap. Twig tokens supported
recipientstextNoComma-separated user IDs, segment handles, or all

send-telegram-message — Send Telegram Message

FieldTypeRequiredDescription
botTokentextYesTelegram bot API token
chatIdtextYesChat, group, or channel ID. Twig tokens supported
messagetextareaYesMessage text. Twig tokens supported
parseModeselectNoHTML (default) or Markdown

slack-notification — Slack Notification

FieldTypeRequiredDescription
webhookUrltextYesSlack incoming webhook URL
messagetextareaYesMessage text. Twig and Slack markdown supported
channeltextNoOverride the webhook's default channel (e.g. #general)

send-discord-notification — Discord Notification

Sends a message to a Discord channel via webhook.

send-teams-notification — Teams Notification

Posts to a Microsoft Teams channel via incoming webhook.

send-whatsapp — WhatsApp Message

Sends a WhatsApp message via a configured provider.

send-messenger — Messenger Message

Sends a Facebook Messenger message via a configured provider.

send-mailchimp — Add to Mailchimp

Adds or updates a subscriber in a Mailchimp audience. Requires a Mailchimp credential configured under Flows → Credentials.

send-in-app-message — Send In-App Message

Creates an in-app notification for the customer visible in the storefront notification centre.

create-notification — Create Notification

Creates an internal system notification visible in the Craft CP.

notify-team — Notify Team

Sends an internal notification to one or more Craft users or user groups.


Marketing

create-coupon — Create Coupon

Generates a new single-use coupon and attaches it to the flow context.

FieldTypeRequiredDescription
discountTypeselectYespercentage, fixed, or free_shipping
discountValuenumberNoDiscount amount or percentage (not used for free shipping)
expiresInDaysnumberNoDays until expiry. Default 30
prefixtextNoCode prefix (e.g. FLOW-)
usageLimitnumberNoMax uses. Default 1
nametextNoAdmin label. Twig tokens supported
siteIdnumberNoTarget site ID. Defaults to current site
stackablelightswitchNoAllow stacking with other stackable coupons
exclusivelightswitchNoOverride all other coupons when used
prioritynumberNoProcessing priority. Higher = evaluated first

apply-discount — Apply Discount / Incentive

Generates and applies an incentive to the triggering order.

FieldTypeRequiredDescription
incentiveTypeselectYescoupon, gift-card, or store-credit
amountnumberYesIncentive value
expiresInDaysnumberNoDays until the incentive expires

Output variables: incentiveType, amount, code

add-to-segment / remove-from-segment — Segment Membership

FieldTypeRequiredDescription
segmentHandletextYesHandle of the customer segment

The customer ID is resolved automatically from the flow context (customer.id).

Output variables: segmentHandle, customerId

abandoned-cart-sequence-step-1 / -2 / -3 — Abandoned Cart Email (Step 1/2/3)

Renders one of the plugin's built-in abandoned-cart recovery emails. See Abandoned Carts → Built-in 3-step recovery sequence actions for the full sequence and placement rules.

ActionIntended positionContent
abandoned-cart-sequence-step-1Immediately after the Cart Abandoned trigger"Did you forget something?"
abandoned-cart-sequence-step-2After a 24-hour Wait node"Your cart is still waiting for you"
abandoned-cart-sequence-step-3After a further 48-hour Wait node (72 h total)Final reminder with a coupon block — pair with create-abandoned-cart-coupon upstream

Output variables: sentTo for Step 1; sentTo, couponCode for Step 2 and Step 3.

create-abandoned-cart-coupon — Create Abandoned-Cart Coupon

Generates a single-use recovery coupon for an abandoned cart, using the store's abandoned-cart coupon defaults unless overridden.

FieldTypeRequiredDescription
cartIdtextYesUsed to deduplicate — an existing active coupon for the same cart is returned instead of creating a new one
emailtextNoCustomer email, stored for the Coupons admin list
discountTypeselectNopercent or fixed — override the store default
discountValuenumberNoOverride the store default discount value
expiryHoursnumberNoOverride the store default expiry
prefixtextNoOverride the store default code prefix

Output variables: coupon (with coupon.code and coupon.discount available to downstream nodes, e.g. the Step 3 email).

subscribe-to-newsletter — Subscribe to Newsletter

Sets the customer's subscriber status to active. No required fields — customer is resolved from context.

manage-subscriber — Manage Subscriber

Fine-grained subscriber management (status, lists, preferences).

win-back-campaign — Win-Back Campaign

Triggered win-back sequence for lapsed customers.

nps-csat-follow-up — NPS / CSAT Follow-Up

Sends a Net Promoter Score or CSAT survey to the customer.

channel-optimization — Channel Optimization

Selects the best communication channel for a customer based on engagement history.

churn-prediction-triggered — Churn Prediction Triggered

Executes a churn intervention action when the prediction model flags a customer.


Order management

update-order-status — Update Order Status

FieldTypeRequiredDescription
newStatustextYesStatus handle to set on the order
addNotetextareaNoNote appended when changing status. Twig tokens supported

Order is resolved from context (order.id / orderId).

add-order-note — Add Order Note

FieldTypeRequiredDescription
notetextareaYesNote text. Twig tokens supported
orderIdtextNoOrder ID override. Defaults to context order
isCustomerVisiblelightswitchNoWhen enabled, triggers customer notification. Default false

Output variables: orderId, note, isCustomerVisible, saved

add-order-tag / remove-order-tag — Order Tags

FieldTypeRequiredDescription
orderIdtextNoOrder ID. Defaults to context order. Twig tokens supported
tagtextYesTag string. Twig tokens supported

cancel-order — Cancel Order

FieldTypeRequiredDescription
orderIdtextNoOrder ID. Defaults to context order. Twig tokens supported
reasontextareaNoCancellation reason for the audit log. Twig tokens supported
restoreStocklightswitchNoRestore stock levels for cancelled items. Default true

create-refund — Create Refund

FieldTypeRequiredDescription
orderIdtextNoOrder ID. Defaults to context order. Twig tokens supported
amountnumberNoRefund amount. Set to 0 for a full refund
reasontextareaNoReason for the refund. Twig tokens supported

Output variables: orderId, refundAmount, refundId

update-order-shipping-method — Update Shipping Method

FieldTypeRequiredDescription
orderIdtextNoOrder ID override. Twig tokens supported
shippingMethodtextYesShipping method handle
shippingAmountnumberNoOverride the shipping cost

update-order-payment-method — Update Payment Method

FieldTypeRequiredDescription
orderIdtextNoOrder ID override
paymentMethodtextYesPayment method handle
paymentAmountnumberNoOverride the payment amount

update-order-address — Update Order Address

FieldTypeRequiredDescription
orderIdtextNoOrder ID override
addressTypeselectNoshipping (default) or billing
addressJsontextareaYesJSON object with address fields

The JSON object is written directly to shipping_address or billing_address on the order record. Use the same keys as the order address model (e.g. firstName, lastName, address1, city, zipCode, countryCode).

update-order-item-custom-data — Update Order Item Custom Data

FieldTypeRequiredDescription
orderItemIdtextNoItem ID override. Twig tokens supported
skutextNoSKU fallback when item ID is not provided
customDatatextareaYesJSON object to write (e.g. {"giftMessage":"Thanks"})
mergeWithExistinglightswitchNoMerge into existing data instead of replacing. Default true

update-order-customer — Reassign Order Customer

Reassigns the order to a different customer record.

generate-invoice-pdf — Generate Invoice PDF

FieldTypeRequiredDescription
orderIdtextNoOrder ID. Defaults to context order. Twig tokens supported
templateHandletextNoPDF template handle (e.g. invoice, receipt). Default invoice

Output variables: orderId, pdfUrl, pdfPath

recalculate-order — Recalculate Order

Re-runs all price calculations (taxes, discounts, shipping) on the order.

FieldTypeRequiredDescription
orderIdtextNoOrder ID. Defaults to context order

Output variables: orderId, newTotal


Customer management

update-customer — Update Customer

FieldTypeRequiredDescription
customerIdtextYesCustomer ID. Twig tokens supported ({{ customer.id }})
emailtextNoNew email address
firstNametextNoNew first name
lastNametextNoNew last name
phonetextNoNew phone number
customFieldstextareaNoJSON object of custom field updates (keys = field handles)
notestextNoAudit note for this update

Leave any field empty to keep the existing value.

update-user — Update Craft User

FieldTypeRequiredDescription
userIdtextYesCraft user ID. Twig tokens supported
firstNametextNoNew first name
lastNametextNoNew last name
emailtextNoNew email address

create-user — Create Craft User

FieldTypeRequiredDescription
emailtextYesUser email address. Twig tokens supported
usernametextNoUsername. Defaults to email if empty
firstNametextNoFirst name
lastNametextNoLast name
groupHandletextNoUser group handle to assign the new user to

block-customer — Block / Unblock Customer

FieldTypeRequiredDescription
customerIdtextYesCustomer ID. Twig tokens supported
blockedlightswitchNotrue to block, false to unblock. Default true
reasontextNoReason for the action (audit log)

assign-user-group — Assign User Group

FieldTypeRequiredDescription
userIdtextYesCraft user ID. Twig tokens supported
groupHandletextYesUser group handle

remove-user-group — Remove User Group

Same fields as assign-user-group — removes instead of adding.

update-customer-group — Update Customer Group

Updates the customer's yStore customer group.

suspend-user — Suspend User

Suspends the Craft user account. Suspended users cannot log in.

activate-user — Activate User

Activates a pending or suspended Craft user account.


Product

adjust-stock — Adjust Stock

FieldTypeRequiredDescription
productIdtextNoProduct or variant ID. Twig tokens supported. Defaults to context product
adjustmentnumberYesQuantity adjustment. Negative values reduce stock
reasontextNoReason for the adjustment (audit log)

apply-catalog-rule — Apply Catalog Rule

Applies or re-evaluates a catalog pricing rule against a product.


Integration

http-request — HTTP Request

Make an arbitrary HTTP request to any external API.

FieldTypeRequiredDescription
urltextYesRequest URL. Twig tokens supported
methodselectNoGET (default), POST, PUT, PATCH, or DELETE
credentialHandlecredentialNoReusable credential for auth headers
headerstextareaNoOne header per line in Key: Value format. Twig tokens supported
bodytextareaNoRequest body for POST / PUT / PATCH. Twig tokens supported
responseVariabletextNoContext key to store the response data. Default httpResponse
Security

Requests to localhost, 0.0.0.0, .local addresses, and non-http/https schemes are blocked.

send-webhook — Send Webhook

Simplified HTTP action for webhook delivery.

FieldTypeRequiredDescription
urltextYesWebhook endpoint URL. Twig tokens supported
methodselectNoPOST (default), PUT, or GET
headerstextareaNoOne header per line. Twig tokens supported
bodyTemplatetextareaNoCustom JSON body. If empty, the full flow context is sent

crm-sync — CRM Sync

Syncs customer or order data to a configured CRM integration.

ad-audience-sync — Ad Audience Sync

Adds or removes the customer from an ad platform audience (Google, Meta, etc.).

warehouse-erp-sync — Warehouse / ERP Sync

Pushes order data to a configured warehouse or ERP system.

bi-event — BI Event

Emits a structured event to a business intelligence pipeline.

google-sheets-append — Google Sheets Append

Appends a row to a Google Sheets spreadsheet. Requires a Google credential configured under Flows → Credentials.

send-mailchimp — Mailchimp

Adds or updates a subscriber in a Mailchimp audience list.


Entry / Element actions

These actions operate on Craft CMS element types.

HandleAction
create-entryCreate a new entry in a specified section and type
update-entryUpdate fields on an existing entry
delete-entryDelete an entry by ID
change-entry-statusEnable or disable an entry
duplicate-entryDuplicate an entry
set-entry-fieldSet a single field value on an entry
copy-entry-fieldCopy a field value from one entry to another
relate-entriesCreate or remove a relation between entries
lookup-entryFind an entry by query criteria and store it in context

Utility

set-variable — Set Variable

FieldTypeRequiredDescription
variableNametextYesContext key to write
variableValuetextareaYesValue to assign. Twig tokens supported

The value is rendered as a Twig string and stored in context under variableName.

conditional-set-variable — Conditional Set Variable

Sets a variable only when a condition evaluates to true.

log — Log

FieldTypeRequiredDescription
messagetextareaYesLog message. Twig tokens supported
levelselectNoinfo (default), warning, or error

Writes to Craft's application log under the flow category. Useful for debugging flow runs without triggering a failure.

run-flow — Run Flow

Triggers another flow from within the current flow (sub-flow).

FieldTypeRequiredDescription
flowHandletextNoTarget flow handle. Twig tokens supported
flowIdnumberNoFallback flow ID when handle is empty or not found
triggerHandletextNoChild trigger handle. Default manual
mergeTriggerContextbooleanNoMerge current context into the child flow trigger data. Default true

math-expression — Math Expression

Evaluates a mathematical expression and stores the result.

FieldTypeRequiredDescription
expressiontextYesMath expression string. Twig tokens supported
resultVariabletextNoContext key to store the result

Output variables: result

format-date — Format Date

Parses and reformats a date value.

FieldTypeRequiredDescription
inputDatetextYesDate string or Twig token
outputFormattextNoPHP date format string (default Y-m-d H:i:s)
inputFormattextNoInput format for parsing. Auto-detected if empty

Output variables: formattedDate

generate-hash — Generate Hash

Generates a hash or UUID value and stores it in context.

generate-qr-code — Generate QR Code

FieldTypeRequiredDescription
contenttextYesText or URL to encode. Twig tokens supported
sizenumberNoImage size in pixels (64–1024). Default 256

Output variables: qrUrl, qrData

generate-pdf — Generate PDF

Renders a Twig template to PDF.

FieldTypeRequiredDescription
templatePathtextYesTwig template path (e.g. _pdfs/invoice)
filenametextYesOutput filename. Twig tokens supported
variablestextareaNoJSON object of additional template variables

compress-image — Compress Image

Compresses an image asset to reduce file size.

json-parse — JSON Parse

FieldTypeRequiredDescription
jsonStringtextareaYesJSON string to parse. Twig tokens supported
outputVariabletextNoContext key to store parsed data. Default parsedData

Output variables: parsedData, keyCount

json-build — JSON Build

Assembles a JSON string from Twig-rendered key-value pairs.

Output variables: jsonString

string-manipulate — String Manipulate

FieldTypeRequiredDescription
inputtextYesSource string. Twig tokens supported
operationselectYestrim, uppercase, lowercase, replace, substr, slug, etc.

Output variables: result, originalLength, newLength

array-operation — Array Operation

Performs operations on array context variables (filter, map, sort, merge, unique, count, etc.).

Output variables: result, resultCount

cache-operation — Cache Get / Set

Reads or writes a value in the Craft data cache.

FieldTypeRequiredDescription
operationselectYesget or set
cacheKeytextYesCache key. Twig tokens supported
valuetextNoValue to store (only for set)
ttlnumberNoCache TTL in seconds (only for set)

Output variables: cacheKey, cacheValue, cacheHit

transform-data — Transform Data

Applies a Twig template transformation to reshape or extract values from context data.

Output variables: result

export-csv — Export CSV

Generates a CSV file from a context array variable.

FieldTypeRequiredDescription
filenametextYesOutput filename. Twig tokens supported
headerstextYesComma-separated column header names
rowTemplatetextareaYesTwig template for each row. Each line = one row; columns separated by commas
sourceVariabletextNoContext key containing the array to iterate

share-cart — Share Cart

Generates a shareable cart URL from the current order context.

create-task — Create Task

Creates a task in the yStore task management system.


Shopware-specific actions

These actions apply only to stores using the Shopware integration.

HandleAction
shopware-send-voucherSend a Shopware voucher to the customer
shopware-update-customer-groupMove the customer to a different Shopware customer group

Output variable reference

Output variables written by an action are available in subsequent nodes via the Variable Picker ({}). The variable name is prefixed with the node's handle in the editor.

CategoryAction handleOutput variables
Communicationsend-emailsentTo, subject
Communicationsend-email-templatetemplateHandle, to, sent
Marketingapply-discountincentiveType, amount, code
Marketingadd-to-segmentsegmentHandle, customerId
Marketingremove-from-segmentsegmentHandle, customerId
Marketingabandoned-cart-sequence-step-1sentTo
Marketingabandoned-cart-sequence-step-2sentTo, couponCode
Marketingabandoned-cart-sequence-step-3sentTo, couponCode
Marketingcreate-abandoned-cart-couponcoupon
Orderscreate-refundorderId, refundAmount, refundId
Ordersupdate-order-addressorderId, addressType
Ordersrecalculate-orderorderId, newTotal
Ordersgenerate-invoice-pdforderId, pdfUrl, pdfPath
Integrationhttp-requestconfigurable via responseVariable
Utilityset-variablethe named variable itself
Utilitymath-expressionresult
Utilityformat-dateformattedDate
Utilityjson-parseparsedData, keyCount
Utilitystring-manipulateresult, originalLength, newLength
Utilityarray-operationresult, resultCount
Utilitycache-operationcacheKey, cacheValue, cacheHit
Utilitytransform-dataresult
Utilitygenerate-qr-codeqrUrl, qrData

Custom actions

Registering a custom action

Listen to FlowService::EVENT_REGISTER_ACTION_DEFINITIONS and push your class into $event->classList.

use yui\craft\events\RegisterFlowDefinitionsEvent;
use yui\craft\services\marketing\FlowService;
use ycraft\craft\Event;

Event::on(
FlowService::class,
FlowService::EVENT_REGISTER_ACTION_DEFINITIONS,
function (RegisterFlowDefinitionsEvent $event): void {
$event->classList[] = MyCustomAction::class;
}
);

Registration should happen in your plugin or module's init() method.

Implementing a custom action

A minimal executable action:

<?php

namespace my\plugin\flow\actions;

use yui\craft\flow\executors\ExecutableActionInterface;
use yui\craft\flow\FlowContext;
use yui\craft\flow\NodeResult;
use yui\craft\flow\steps\AbstractActionDefinition;
use Craft;

class TagLoyaltyCustomerAction extends AbstractActionDefinition implements ExecutableActionInterface
{
public static function handle(): string
{
return 'tag-loyalty-customer';
}

public static function name(): string
{
return 'Tag Loyalty Customer';
}

public static function description(): string
{
return 'Adds a loyalty tier tag to the customer record.';
}

public static function category(): string
{
return 'customers'; // Groups this action in the node picker
}

public static function outputVariables(): array
{
return ['customerId', 'tag', 'applied'];
}

public static function fields(): array
{
return [
[
'handle' => 'tag',
'label' => 'Loyalty tier tag',
'type' => 'select',
'required' => true,
'options' => [
['value' => 'bronze', 'label' => 'Bronze'],
['value' => 'silver', 'label' => 'Silver'],
['value' => 'gold', 'label' => 'Gold'],
],
'default' => 'bronze',
'instructions' => 'The loyalty tier to assign.',
],
];
}

public function execute(FlowContext $context, array $properties): NodeResult
{
// Bail out during test runs without side effects
if ($context->isDryRun()) {
return NodeResult::success(
['customerId' => null, 'tag' => $properties['tag'], 'applied' => false],
'Dry run — no changes made.'
);
}

$tag = $properties['tag'] ?? '';
if ($tag === '') {
return NodeResult::failure('Tag is required.');
}

$customerId = $context->get('customer.id') ?? $context->get('customerId');
if (!$customerId) {
return NodeResult::failure('No customer ID found in context.');
}

// ... your business logic here ...

Craft::info("Flow: tagged customer #{$customerId} as {$tag}", 'my-plugin');

return NodeResult::success(
['customerId' => $customerId, 'tag' => $tag, 'applied' => true],
sprintf('Customer #%s tagged as %s.', $customerId, $tag)
);
}
}

Available registration events

Event constantClassRegisters
EVENT_REGISTER_ACTION_DEFINITIONSFlowServiceAction nodes
EVENT_REGISTER_TRIGGER_DEFINITIONSFlowServiceTrigger nodes
EVENT_REGISTER_CONDITION_DEFINITIONSFlowServiceCondition nodes
EVENT_REGISTER_LOGIC_DEFINITIONSFlowServiceLogic / control flow nodes

All four events use RegisterFlowDefinitionsEvent with a $classList array of fully-qualified class names.

Testing a custom action

Use the flow editor's Test button to trigger a dry run. Inside execute(), check $context->isDryRun() to skip side-effecting operations and return a NodeResult::success() with mock data.

if ($context->isDryRun()) {
return NodeResult::success(['applied' => false], 'Dry run skipped.');
}

Log detailed information during development with Craft::info($message, 'my-plugin'). Flow run logs are visible at yStore → Logs → Automation.


Audience check

PerspectiveAssessment
Customer / storefrontNo direct customer exposure. Actions run server-side during flow execution
Admin / Craft CPActions are configured in yStore → Marketing → Flows. Each action node renders fields from fields() in the flow editor panel. Flow run results and error messages appear in yStore → Logs → Automation
Developer / integratorFull custom action support via EVENT_REGISTER_ACTION_DEFINITIONS. Implement ExecutableActionInterface, extend AbstractActionDefinition, define fields() and execute(). Use FlowContext for data exchange and return NodeResult