> ## Documentation Index
> Fetch the complete documentation index at: https://docs.paynext.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Workflows

> Route payments intelligently with no-code rules. Optimize costs, increase acceptance rates, and implement failover logic.

Workflows give you full control over how payments are routed across processors—without writing code. Integrate once, then use the visual builder to update routing logic anytime.

**Key benefits:**

* **Full control** — Decide exactly which processor receives each payment based on any attribute
* **Flexibility** — Update routing rules instantly from the Dashboard, no code deployments needed
* **Higher acceptance** — Implement failover to automatically recover declined payments
* **Data-driven optimization** — A/B test processors and track results to find the best performer

## Getting Started

<Steps>
  <Step title="Connect processors">
    Add at least two processor integrations in **Dashboard → Integrations**
  </Step>

  <Step title="Create workflow">
    Go to **Dashboard → Workflows** and click **Create workflow**
  </Step>

  <Step title="Add a trigger">
    Drag **Payment Pending** onto the canvas and select the payment method (e.g., Cards, Apple Pay)
  </Step>

  <Step title="Build your flow">
    Add conditions, splits, and actions by dragging components and connecting them
  </Step>

  <Step title="Save and publish">
    Click **Save** to create a draft, then **Publish** to make the workflow live
  </Step>
</Steps>

## Building Blocks

Workflows are built from four types of components. You can connect them in any order to create complex routing logic.

### Triggers

Triggers start the workflow when an event occurs. Each workflow has exactly one trigger, and each trigger is tied to a specific payment method.

| Trigger             | Description                                                           |
| ------------------- | --------------------------------------------------------------------- |
| **Payment Pending** | Fires when a new payment is initiated for the selected payment method |

<Note>
  Each payment method can only have one workflow. To route Cards and Apple Pay differently, create separate workflows—one for each payment method.
</Note>

### Conditions

Route payments based on attributes. Can be placed at any point in the workflow. Combine multiple rules with AND/OR logic.

| Condition               | Description                                               |
| ----------------------- | --------------------------------------------------------- |
| **Transaction Type**    | CIT (customer-initiated) or MIT (merchant-initiated)      |
| **BIN**                 | First 6-8 digits of card number                           |
| **Card Network**        | Visa, Mastercard, Amex, Discover, etc.                    |
| **Issuer Country Code** | Issuer country                                            |
| **Currency**            | Payment currency (USD, EUR, etc.)                         |
| **Issuer Name**         | Name of the issuing bank                                  |
| **Customer Country**    | Customer's billing country                                |
| **Metadata**            | Custom metadata from previous workflows or client session |
| **CIT Processor**       | Processor used for the original CIT payment               |

**Combining rules:**

Create complex logic by combining conditions:

* **AND** — All conditions in a group must match
* **OR** — Add a new group; payment matches if any group matches

```
Group 1: Card Network = Visa AND Issuer Country = US
OR
Group 2: Card Network = Mastercard AND Currency = EUR
```

**Condition priority:**

Conditions are evaluated left to right. Only the first matching condition is executed—subsequent matches are ignored.

### Split

Divide traffic by percentage. Can be placed at any point in the workflow.

| Example         | Use Case                                                         |
| --------------- | ---------------------------------------------------------------- |
| 50% / 50%       | Distribute traffic evenly between two paths                      |
| 90% / 10%       | Gradual rollout—send most traffic to primary path, test with 10% |
| 33% / 33% / 34% | Distribute across three paths                                    |

Use Split to run experiments, distribute load across processors, or gradually roll out routing changes.

### Actions

Execute operations on the payment.

| Action                | Description                                    | Placement                                    |
| --------------------- | ---------------------------------------------- | -------------------------------------------- |
| **Authorize Payment** | Send to a specific processor for authorization | Any point (requires Settle Payment in flow)  |
| **Settle Payment**    | Settle a previously authorized payment         | After Authorize Payment                      |
| **Block Payment**     | Block the payment (marked as `BLOCKED` status) | Instead of Authorize Payment                 |
| **Set Metadata**      | Save key-value data to customer or payment     | Any point                                    |
| **Delay**             | Wait before executing the next action          | Between Authorize Payment and Settle Payment |

<Tip>
  Use **Delay** for delayed settlement workflows—for example, authorize immediately but settle after 24 hours to allow for order review or fraud checks.
</Tip>

**Authorize Payment configuration:**

| Setting                       | Description                                      |
| ----------------------------- | ------------------------------------------------ |
| **Primary Merchant Account**  | Processor to send the authorization request      |
| **Fallback Merchant Account** | Backup processor if the primary fails (optional) |
| **3D Secure**                 | Authentication mode for card payments            |

**3D Secure options:**

| Option               | Description                                     |
| -------------------- | ----------------------------------------------- |
| **No 3DS**           | Skip 3D Secure authentication                   |
| **Adaptive 3DS**     | Apply 3DS based on risk and issuer requirements |
| **Frictionless 3DS** | Request frictionless flow when possible         |

See [3D Secure](/guides/payments/3d-secure) for details on each mode.

## Set Metadata

Save custom key-value data at any point in the workflow. Use metadata to track experiments, enable advanced routing, or record decisions.

**Configuration:**

| Field           | Description                        |
| --------------- | ---------------------------------- |
| **Key**         | Metadata field name (required)     |
| **Value**       | Metadata field value               |
| **Destination** | Save to customer, payment, or both |

You can add multiple key-value pairs in a single Set Metadata node.

<Warning>
  Use unique keys. If you set the same key twice, the second value overwrites the first. PayNext does not validate key uniqueness.
</Warning>

**Example metadata on payment object:**

```json theme={"system"}
{
  "id": "pay_f1e2d3c4-b5a6-9788-7c6d-5e4f3a2b1c0d",
  "metadata": {
    "workflow": {
      "experiment_variant": "variant_b"
    }
  }
}
```

**Using metadata in conditions:**

For nested metadata (like `workflow`), use dot notation for the key:

```json theme={"system"}
"metadata": {
  "workflow": {
    "experiment_variant": "variant_b"
  }
}
```

→ Key: `workflow.experiment_variant` Value: `variant_b`

For flat metadata, use the key directly:

```json theme={"system"}
"metadata": {
  "client_tier": "premium"
}
```

→ Key: `client_tier` Value: `premium`

**Common uses:**

| Use Case              | Example                                                           |
| --------------------- | ----------------------------------------------------------------- |
| **A/B test tracking** | Set `variant: a` or `variant: b` after a split                    |
| **Routing audit**     | Record why a processor was selected                               |
| **Future routing**    | Tag customers, then route their future payments based on that tag |

## Common Use Cases

### Geographic Routing

Route payments to regional processors for lower cross-border fees and higher acceptance rates.

<div className="block dark:hidden">
  ```mermaid theme={"system"}
  flowchart LR
      A([Payment Pending]) --> B{Issuer Country}
      B -->|US| C([Authorize Payment:<br/>Processor X])
      B -->|EU| D([Authorize Payment:<br/>Processor Y])
      B -->|Other| E([Authorize Payment:<br/>Processor Z])
      C --> F([Settle Payment])
      D --> F
      E --> F
      
      style A fill:#f1f5f9,stroke:#64748b,color:#334155
      style B fill:#f3e8ff,stroke:#9333ea,color:#581c87
      style C fill:#dcfce7,stroke:#16a34a,color:#14532d
      style D fill:#dcfce7,stroke:#16a34a,color:#14532d
      style E fill:#dcfce7,stroke:#16a34a,color:#14532d
      style F fill:#dcfce7,stroke:#16a34a,color:#14532d
  ```
</div>

<div className="hidden dark:block">
  ```mermaid theme={"system"}
  flowchart LR
      A([Payment Pending]) --> B{Issuer Country}
      B -->|US| C([Authorize Payment:<br/>Processor X])
      B -->|EU| D([Authorize Payment:<br/>Processor Y])
      B -->|Other| E([Authorize Payment:<br/>Processor Z])
      C --> F([Settle Payment])
      D --> F
      E --> F
      
      style A fill:#1e293b,stroke:#475569,color:#cbd5e1
      style B fill:#581c87,stroke:#9333ea,color:#e9d5ff
      style C fill:#14532d,stroke:#16a34a,color:#bbf7d0
      style D fill:#14532d,stroke:#16a34a,color:#bbf7d0
      style E fill:#14532d,stroke:#16a34a,color:#bbf7d0
      style F fill:#14532d,stroke:#16a34a,color:#bbf7d0
  ```
</div>

### Automatic Failover

Retry with another processor when the first one fails. Recovers payments that would otherwise be lost to temporary processor issues.

<div className="block dark:hidden">
  ```mermaid theme={"system"}
  flowchart LR
      A([Payment Pending]) --> B([Authorize Payment:<br/>Processor X])
      B -->|Success| C([Settle Payment])
      B -->|Declined| D([Authorize Payment:<br/>Processor Y])
      D -->|Success| C
      D -->|Declined| E([Declined])
      
      style A fill:#f1f5f9,stroke:#64748b,color:#334155
      style B fill:#dcfce7,stroke:#16a34a,color:#14532d
      style C fill:#dcfce7,stroke:#16a34a,color:#14532d
      style D fill:#dcfce7,stroke:#16a34a,color:#14532d
      style E fill:#fee2e2,stroke:#dc2626,color:#7f1d1d
  ```
</div>

<div className="hidden dark:block">
  ```mermaid theme={"system"}
  flowchart LR
      A([Payment Pending]) --> B([Authorize Payment:<br/>Processor X])
      B -->|Success| C([Settle Payment])
      B -->|Declined| D([Authorize Payment:<br/>Processor Y])
      D -->|Success| C
      D -->|Declined| E([Declined])
      
      style A fill:#1e293b,stroke:#475569,color:#cbd5e1
      style B fill:#14532d,stroke:#16a34a,color:#bbf7d0
      style C fill:#14532d,stroke:#16a34a,color:#bbf7d0
      style D fill:#14532d,stroke:#16a34a,color:#bbf7d0
      style E fill:#7f1d1d,stroke:#dc2626,color:#fecaca
  ```
</div>

<Note>
  Failover triggers for processor-level failures (technical errors, temporary declines). Card-level declines like insufficient funds are not retried—they would fail at any processor.
</Note>

### A/B Testing

Compare processor performance by splitting traffic and tracking results with metadata.

<div className="block dark:hidden">
  ```mermaid theme={"system"}
  flowchart LR
      A([Payment Pending]) --> B{Split 50/50}
      B -->|50%| C([Set Metadata: variant_a])
      B -->|50%| D([Set Metadata: variant_b])
      C --> E([Authorize Payment:<br/>Processor X])
      D --> F([Authorize Payment:<br/>Processor Y])
      E --> G([Settle Payment])
      F --> G
      
      style A fill:#f1f5f9,stroke:#64748b,color:#334155
      style B fill:#f3e8ff,stroke:#9333ea,color:#581c87
      style C fill:#f1f5f9,stroke:#64748b,color:#334155
      style D fill:#f1f5f9,stroke:#64748b,color:#334155
      style E fill:#dcfce7,stroke:#16a34a,color:#14532d
      style F fill:#dcfce7,stroke:#16a34a,color:#14532d
      style G fill:#dcfce7,stroke:#16a34a,color:#14532d
  ```
</div>

<div className="hidden dark:block">
  ```mermaid theme={"system"}
  flowchart LR
      A([Payment Pending]) --> B{Split 50/50}
      B -->|50%| C([Set Metadata: variant_a])
      B -->|50%| D([Set Metadata: variant_b])
      C --> E([Authorize Payment:<br/>Processor X])
      D --> F([Authorize Payment:<br/>Processor Y])
      E --> G([Settle Payment])
      F --> G
      
      style A fill:#1e293b,stroke:#475569,color:#cbd5e1
      style B fill:#581c87,stroke:#9333ea,color:#e9d5ff
      style C fill:#1e293b,stroke:#475569,color:#cbd5e1
      style D fill:#1e293b,stroke:#475569,color:#cbd5e1
      style E fill:#14532d,stroke:#16a34a,color:#bbf7d0
      style F fill:#14532d,stroke:#16a34a,color:#bbf7d0
      style G fill:#14532d,stroke:#16a34a,color:#bbf7d0
  ```
</div>

After collecting data, filter payments by `workflow.experiment_variant` to compare acceptance rates and costs.

### MIT Routing

Route merchant-initiated transactions (renewals, recurring charges) based on the processor that handled the original customer-initiated transaction.

**Option 1: Use CIT Processor checkbox (recommended)**

In the **Authorize Payment** node, tick **Use CIT Processor**. This automatically routes MITs to the same processor that was used for the first payment—no additional conditions needed.

**Option 2: Use CIT Processor condition**

Add a **CIT Processor** condition to route MITs to a different processor. For example, route all MITs where the original CIT was processed by Processor A to Processor B instead.

**Option 3: Use metadata**

For more control, set metadata on the first payment identifying the processor used, then add a condition checking that metadata value for subsequent MITs.

### Block Payments

Block payments before they reach a processor based on any condition. Blocked payments are marked with `BLOCKED` status and never sent for authorization.

**Common use cases:**

* Block specific BINs associated with fraud or chargebacks
* Block payments from high-risk issuer countries

<div className="block dark:hidden">
  ```mermaid theme={"system"}
  flowchart LR
      A([Payment Pending]) --> B{BIN in block list?}
      B -->|Yes| C([Block Payment])
      B -->|No| D([Authorize Payment])
      D --> E([Settle Payment])
      
      style A fill:#f1f5f9,stroke:#64748b,color:#334155
      style B fill:#f3e8ff,stroke:#9333ea,color:#581c87
      style C fill:#fee2e2,stroke:#dc2626,color:#7f1d1d
      style D fill:#dcfce7,stroke:#16a34a,color:#14532d
      style E fill:#dcfce7,stroke:#16a34a,color:#14532d
  ```
</div>

<div className="hidden dark:block">
  ```mermaid theme={"system"}
  flowchart LR
      A([Payment Pending]) --> B{BIN in block list?}
      B -->|Yes| C([Block Payment])
      B -->|No| D([Authorize Payment])
      D --> E([Settle Payment])
      
      style A fill:#1e293b,stroke:#475569,color:#cbd5e1
      style B fill:#581c87,stroke:#9333ea,color:#e9d5ff
      style C fill:#7f1d1d,stroke:#dc2626,color:#fecaca
      style D fill:#14532d,stroke:#16a34a,color:#bbf7d0
      style E fill:#14532d,stroke:#16a34a,color:#bbf7d0
  ```
</div>

Use the **Block Payment** action in your workflow to block payments that match your conditions.

## Lists

Lists let you create reusable collections of values to use across workflows. Instead of adding conditions for each blocked BIN individually, create a list and reference it in your workflow conditions.

**Currently supported list types:**

| Type         | Description                               |
| ------------ | ----------------------------------------- |
| **Card BIN** | Block or route based on card BIN prefixes |

### Create a List

1. Go to **Dashboard → Workflows → Lists**
2. Click **Create list**
3. Select **Card BIN** as the list type
4. Add BINs to the list

### List Details

When you add a BIN to a Card BIN list, PayNext automatically enriches it with card details:

| Field       | Description                                |
| ----------- | ------------------------------------------ |
| **Value**   | The BIN prefix (first 6-8 digits)          |
| **Country** | Issuer country code                        |
| **Brand**   | Card network (Visa, Mastercard, etc.)      |
| **Funding** | Card funding type (Credit, Debit, Prepaid) |
| **Issuer**  | Issuing bank name                          |
| **Author**  | Team member who added the BIN              |

### Use Lists in Workflows

Reference a list in workflow conditions:

1. Add a **Condition** node
2. Select **BIN** as the condition type
3. Choose **is in list** or **is not in list**
4. Select your list

<Tip>
  Use lists to maintain a central block list. When you update the list, all workflows using it are automatically updated—no need to edit each workflow individually.
</Tip>

## Version History

Workflows support versioning so you can track changes and roll back if needed.

**Workflow states:**

| State                    | Description                                                   |
| ------------------------ | ------------------------------------------------------------- |
| **Draft**                | Saved but not live. Edit freely without affecting production. |
| **Published**            | Currently active. All payments flow through this version.     |
| **Previously Published** | Archived versions you can preview or restore.                 |

**How to publish:**

1. Make changes in the visual editor
2. Click **Save** to create a draft
3. Click **Publish** to make the workflow live

**History tab:**

View all versions of a workflow in the **History** tab. For each version, you can see:

* Version number and ID
* Status (Draft, Published, Previously Published)
* Author who published
* Date published
* Preview button to view the workflow

## Workflow Runs

Every payment that reaches a workflow creates a run — a record of each step the payment took, in order, with its outcome. Use runs to see exactly why a payment routed the way it did, without re-tracing the workflow definition by hand.

### View all runs

Go to **Dashboard → Workflows → Runs**.

Filter runs by:

| Filter            | Description                                        |
| ----------------- | -------------------------------------------------- |
| **Workflow**      | Limit to one workflow                              |
| **Date and time** | Limit to a time range                              |
| **Status**        | One or more of Completed, Failed, Waiting, Running |

The counter row above the table shows totals for Failed, Waiting, Running, and Completed within the current workflow and date filter.

Each row shows the run ID, status, workflow, workflow version, trigger, amount, start time, and duration. Click a row to open the run.

<Tip>
  From inside a workflow, click **See workflow runs** to jump to the Runs tab pre-filtered to that workflow.
</Tip>

<Note>
  A payment's own page also shows the run (or runs) it went through, under **Workflow Runs**—no need to search the Runs tab for it.
</Note>

### View a run

A run's page shows:

|                                      |                                                                                         |
| :----------------------------------- | :-------------------------------------------------------------------------------------- |
| **Workflow**                         | Name and the exact version that executed—not necessarily the workflow's current version |
| **Trigger**                          | The event that started the run                                                          |
| **Started at / Completed at**        | Timestamps in UTC. Completed at is omitted while the run is still in progress           |
| **Duration**                         | Elapsed time, or time elapsed so far if the run is still running                        |
| **Transaction type**                 | CIT or MIT                                                                              |
| **Payment method, amount, currency** | The payment the run was triggered for                                                   |
| **Payment, customer, subscription**  | Links to the related records, when available                                            |

Below that, the **Execution path** lists every step the run took, in order. Click a step to open its details.

### Step details

Every step shows its status (completed, failed, or skipped), start time, and duration. What else appears depends on the step type:

| Step type              | Shows                                                                                                              |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------ |
| **Condition**          | Every route the workflow evaluated, and why each did or didn't match—see [Condition evidence](#condition-evidence) |
| **Authorize / Settle** | The processor used and its reference                                                                               |
| **Block**              | The decline reason, decline code, advice code, and PSP reference, when available                                   |
| **Set Metadata**       | The keys written and their destination (customer, payment, or both)                                                |
| **Split**              | The percentage split and which path the run took                                                                   |
| **Delay**              | The wait duration                                                                                                  |

<Note>
  `Failed` on a step or run means the workflow itself hit an error—for example, no processor configured. A declined or blocked payment is a normal outcome and still reports as `Completed`.
</Note>

### Condition evidence

A condition step shows every route the workflow checked, not only the one that matched, so you can see why the others lost too:

* The selected route is expanded by default; every other route stays collapsed but can be opened
* Each route is labeled **Selected**, **Not selected**, or **No match**
* Inside a route, each condition group shows its own outcome, and each field shows the actual value from the payment next to the value the condition expected

Groups within a route combine with OR; fields within a group combine with AND—matching how you build conditions in the canvas.

<Note>
  Sensitive values, like masked card or metadata fields, appear as `*** Hidden ***` in the evidence instead of the real value.
</Note>

## Best Practices

<AccordionGroup>
  <Accordion title="Start simple">
    Begin with a default processor and basic failover. Add complex routing after you have payment data to analyze.
  </Accordion>

  <Accordion title="Always tag A/B tests">
    Set metadata when running experiments. Without tags, you can't analyze results by variant.
  </Accordion>

  <Accordion title="Route MITs consistently">
    In the Authorize Payment node, tick **Use CIT Processor** to automatically route recurring payments to the processor that was used for the first payment.
  </Accordion>

  <Accordion title="Test before publishing">
    Save as draft first. Review the workflow logic, then publish when ready.
  </Accordion>
</AccordionGroup>
