Commerce Actions
Commerce actions are the operations a journey step performs when a customer advances — the work behind the screen. A single step can run a fraud check, create or update an account, create an order, convert a lead, capture a payment method, record the order in PeakCommerce, and more. Each step runs its actions in order the moment the customer moves forward.
Open them in the journey builder: Content → Journeys → Edit → Steps, expand a step, and look under Commerce actions.
Anatomy of an action
Each action has:
Target — where it runs:
Internal — runs inside PeakCommerce with no external integration attached (
integrationIdstays null). These are PeakCommerce's own writes — for example create organization, update contact, and record order.Integration — calls a connected system (Zuora, Salesforce, SEON, …). You pick the Integration and the Operation it performs.
Operation — the specific operation to run. Common operations include:
create_order— place a new order / subscription. Has an Honor order grouping option.update_order— amend an existing subscription (used by change-plan steps; targets an account + subscription).cancel_order— cancel a subscription via the Orders API, so the cancellation is recorded as an order that can carry custom fields mapped from context (for example the captured cancellation reason →CancellationReason__c).apply_retention_offer— apply a retention Offer to an active subscription; the committing action behind retention save discounts (see below).update_account,fraud_check(integration actions), and the internalcreate organization,update contact, andrecord_order.
Execution mode:
Blocking — must finish before the next action starts. Use when a later action depends on the result (you can't create an order before the account exists).
Async — dispatched in turn without holding up the next action. Use for fire-and-forget side effects.
Order · Condition — the action's position in the run order, plus an optional condition that decides whether it runs (for example always, or only when a given field is present).
Field mapping — how the operation's inputs are filled (see below).
Run order
Actions run top to bottom. Drag the handle to reorder them. Because blocking actions must complete before the next begins, order matters — a typical checkout step runs fraud check → create account → create order → … Async actions are dispatched in turn and don't hold up the sequence.
Field mapping
Each action maps source values into the operation's destination fields:
Source — where the value comes from:
Context — a value produced earlier in the journey (a previous step's output variable).
Literal — a fixed value you type.
Dynamic / Expression — a computed value.
Object / JSON — a structured value.
Destination — the operation field the value fills.
For example, the internal record order action maps totalRecurringCents → netMrrCents, email → customerEmail, and a literal journey → source. The builder validates these routes, so the operation's required destination fields must be supplied before you can save the action.
Required actions (locked)
Some actions are required by the step's role and appear locked with a 🔒 Required badge. You can drag to reorder them, but you can't remove them.
Required actions guarantee that PeakCommerce always performs its own internal writes — creating the organization, updating the contact, and recording the order — so your PeakCommerce records stay correct and complete regardless of what the external billing system does or returns.
"Required" is a posture the step's role assigns: when you give a step a role (for example Payment), the role brings its mandated set of internal actions with it, already configured and locked. See Step Roles.
Internal and integration actions — why both
PeakCommerce models commerce natively and also syncs to your connected systems of record. The integration actions push to whatever billing, CRM, and risk systems you've connected — for example creating the subscription in your billing system (such as Zuora or Stripe), creating the account in your CRM (such as Salesforce), or running a fraud check (such as SEON). The internal actions make sure PeakCommerce's own order, contact, and organization records are written authoritatively. Together they keep PeakCommerce and your downstream systems in lockstep — and let the journey keep working even while a given integration is still being deepened.
Apply a retention offer
apply_retention_offer is the operation that turns an accepted retention offer into an actual discount on the customer's subscription — the committing action of a retention journey. It runs against your billing integration and typically maps three inputs: the offer (from the Offers catalog), the subscription to discount, and the account the grant is recorded against.
What matters is what it does around the billing write:
The offer is the source of truth. The action resolves the Offer's definition — discount type/value, duration, and its pinned discount instrument (a catalog rate plan) — so the terms live in one place. Change the offer, and every journey using it changes with it. The catalog must be synced for the instrument to resolve.
Live conflict / stacking gate. Immediately before applying, the action reads the subscription's current discounts from the billing system and checks them against the offer's conflict rules. This catches discounts added by any other channel (finance, CPQ, mobile) between the moment the offer was shown and the moment it was accepted. The gate fails closed: if the subscription can't be read, nothing is applied.
Per-customer usage caps. The account mapping is mandatory because every confirmed grant is written to the offer's usage ledger — that ledger is what enforces Max Uses Per Customer and Cooldown on future grants. No account, no apply.
Trial-aware activation. On a trial subscription the discount can defer to the paid start; the action's result carries the activation date so the confirmation page can say when the discount begins.
If any guard fails — offer not found, instrument unresolved, conflict blocked, billing rejection — the action fails with the specific reason, and the failure is visible in the action trace like any other (see Failure routing).
Offer definitions, caps, conflict scopes, and instruments are managed under Commerce → Offers — see Offers & Discounts.
Save and assign a payment method
Saving a card and deciding which card pays are two separate actions, so a journey can do one without the other:
add_payment_methodsaves the card. It attaches the payment method your payment form created (the Zuora hosted page or Stripe's card form) to the customer's account in your billing system. It does not change which card is charged. On Zuora, map Payment Method ID to the id the hosted page returned.assign_payment_methoddecides which card pays. Map the account, the saved Payment Method ID, and Assign To:account makes it the card for the whole account. Every subscription that doesn't have its own card uses it.
subscription makes it the card for the one Subscription ID you map, and leaves the account's card and every other subscription alone. This works only where your billing system supports it. Today that is Stripe. Where it isn't supported, or can't be checked right now, the action fails and says so. It never updates the whole account instead.
Both actions only change an account the journey is allowed to change: the customer's own, or one the journey just created. A refusal from your billing system fails the action with that system's reason, including Zuora answers that report success at the HTTP level but success: false in the body.
Add or edit an action
Add action — at the bottom of a step's action list. Choose the target, operation, and execution mode, then map the fields.
Edit action — opens the action editor for an existing action.
Required (locked) actions can be reordered and re-mapped, but not deleted.
Click Done, then Publish the journey to make your changes live.
Test an integration action
Field mappings usually fail at the worst possible moment — on a live customer's order. The Test integration panel lets you catch those failures in the editor instead: it resolves your mappings into the exact payload the operation would send and validates it, without creating anything in the connected system.
Open the action editor for a saved integration action and expand the collapsible Test integration panel at the bottom ("resolve the payload & catch bad picklist values — no order required"):
Sample context (JSON) — the pretend journey context the test resolves context-sourced mappings against. Click Reseed from mappings to generate a starter object with one entry per context mapping, then edit the values to match a realistic session. Literal mappings don't need context — they are validated regardless of what you put here.
Run test — resolves the current (unsaved) mappings, so you can iterate without saving between attempts.
Review the results:
Resolved payload — the full payload the operation would send, so you can see exactly what each destination field receives.
Validation warnings — values that would be rejected by the CRM's restricted picklists. Each warning names the field, the offending value, and the allowed values. For example, with Salesforce a literal
Abandonedmapped into a restricted lead-source field is flagged before any order ever runs. Only restricted picklists are enforced — unrestricted picklists accept arbitrary values, so validating them would produce false positives.A green confirmation when no violations are detected.
The test is read-only end to end: no order, lead, or record is created or modified in the integration.
Honor order grouping (create order)
The Zuora create order action has one option of its own, shown below Order · Condition in the action editor:
Honor order grouping
Checkbox
Off
On: lines set to Its own order line in the product set are each booked as their own order action (an Add Product) in this order. Off: every line is booked in one order action, whatever the product set says.
What to know:
It is still one order and one subscription. Grouping changes how the order is recorded, not how it is invoiced.
Publish after changing it. The checkbox is part of the published journey. The product set's Order grouping values are read live when checkout starts, so changing those doesn't need a publish.
Lines must come from a product set. A create-order action whose rate plans are mapped by hand, with no product set behind the checkout, books everything in one order action even with the box checked.
Per-line start dates need activation offsets. Each line's Effective Date Timing is applied only when the action also has activation offsets turned on. There is no switch for that in the editor today; your PeakCommerce team turns it on. Without it, every line starts on the order date.
Available on Zuora, the integration that places orders today.
For how the order is built, with a worked example, see Guide: Booking a Line as Its Own Order Action.
Failure routing
By default, a failing blocking action halts the step: the visitor stays where they are and sees the action's failure message. That's the right default for anything a later action depends on. But some journeys want a softer landing — for example routing the visitor to a "we'll follow up" page when a non-essential write fails, instead of dead-ending them. Failure routing gives you that, per action and per step:
Per action — "Continue on failure". Each blocking action (in its editor) has a Continue on failure checkbox. When checked, a failure of this action does not halt the step — the advance completes and routing follows the step's failure target (below). The exception is
fraud_check: a fraud block is a security decision and always halts — the checkbox isn't offered.Per step — the failure target. The step's Branching panel has an "On commerce-action failure (optional)" selector: Halt the step (default) or Go to #N <step>. It only takes effect when the failing action has Continue-on-failure enabled — without that opt-in, a failed action always halts, whatever the selector says.
Two things to know:
Failures stay visible. Continue-on-failure changes where the visitor goes, never what gets recorded. The failure is still written to the action trace and surfaced in API Call Stats, exactly as if it had halted — routing around a failure never hides it.
The failure target is a real branch. Journey validation treats the on-failure target as a genuine edge in the flow graph: it keeps a dedicated failure page counted as reachable, and it gets the same broken-target checks as any other route — deleting the target step flags the configuration instead of leaving a dangling path.
Last updated
Was this helpful?
