> For the complete documentation index, see [llms.txt](https://docs.peakcommerce.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.peakcommerce.com/product/journeys-and-pages/journey-steps/commerce-actions.md).

# 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**.

{% embed url="<https://youtu.be/JRjwXKeIa5c>" %}

## Anatomy of an action

Each action has:

* **Target** — where it runs:
  * **Internal** — runs inside PeakCommerce with no external integration attached (`integrationId` stays 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.
  * `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](#apply-a-retention-offer)).
  * `update_account`, `fraud_check` (integration actions), and the internal `create organization`, `update contact`, and `record_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) <a href="#required-actions" id="required-actions"></a>

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](/product/journeys-and-pages/journey-steps/journey-step-types.md).

## 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 <a href="#apply-a-retention-offer" id="apply-a-retention-offer"></a>

`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](#failure-routing)).

Offer definitions, caps, conflict scopes, and instruments are managed under **Commerce → Offers** — see [Offers & Discounts](/product/using-peakcommerce/products-and-bundles/offers-and-discounts.md).

## 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"):

1. **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.
2. **Run test** — resolves the **current (unsaved) mappings**, so you can iterate without saving between attempts.
3. 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 `Abandoned` mapped 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.

## Failure routing <a href="#failure-routing" id="failure-routing"></a>

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.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.peakcommerce.com/product/journeys-and-pages/journey-steps/commerce-actions.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
