Compute Step

Use the compute step to evaluate expressions, calculate derived amounts, and expose named outputs for downstream workflow steps.

The compute step evaluates expressions and exposes derived values that downstream workflow steps can use.

Use it to split amounts, derive totals, apply percentages, or run small conditional logic. Anything that takes inputs and step outputs and returns a derived number belongs in a compute step.

Parameters

KeyTypeRequiredDescription
outputsmap[string]stringYesNamed expressions. The map preserves the order in which keys are declared, so a later expression can reference an earlier one in the same step.

Expression environment

Inside a compute expression you have access to:

  • input: the workflow's input object (input.field, input.nested.path).
  • steps: every previously-completed step's output (steps.<name>.output.<field> or steps['<name>']['output']['<field>']).
  • Earlier outputs in the same step: referenced as a bare identifier. The map preserves declaration order, so wallet_share defined after bank_share can reference bank_share directly.
  • Monetary helpers: monetary_percent, monetary_split, monetary_div, monetary_mod, monetary_min, monetary_max, monetary_abs. See the table below.

The expression engine is sandboxed: no operating system access, no network, no reflection. The maximum expression length is 1024 characters.

Monetary helpers

All amounts are in centavos. Basis points are used for percentages: 250 bp = 2.5%, 10000 bp = 100%.

HelperReturnsDescription
monetary_percent(amount, bp)int64amount × bp / 10000. Use for percentage splits.
monetary_split(amount, parts)[]int64Splits amount into parts equal centavo amounts. The rounding remainder is distributed to the first elements so the sum is exact.
monetary_div(dividend, divisor)int64Integer division.
monetary_mod(dividend, divisor)int64Integer modulo.
monetary_min(a, b)int64The smaller of two amounts.
monetary_max(a, b)int64The larger of two amounts. Useful with 0 as a floor.
monetary_abs(amount)int64The absolute value of a signed amount.

Outputs

Outputs are dynamic. Whatever you declare in outputs becomes available downstream as ${steps.<name>.output.<key>}. Give the step a name so you can reference it explicitly.

Examples

60/40 split with fee deduction

steps:
    - name: "calc_split"
      compute:
        outputs:
          # 60% to the bank, 40% to the wallet, after a flat 50 PHP fee.
          fee:          "5000"
          net:          "input.payout_amount - fee"
          bank_share:   "monetary_percent(net, 6000)"
          wallet_share: "net - bank_share"
    - send_money:
        source:
            type: "wallet"
            account: "${merchant_account}"
        destination:
            type: "bank"
            account: "${beneficiary_bank_account}"
            account_name: "${beneficiary_name}"
            bic: "${beneficiary_bic}"
        provider: "auto"
        amount: "${steps.calc_split.output.bank_share}"
        currency: "PHP"
    - send_money:
        source:
            type: "wallet"
            account: "${merchant_account}"
        destination:
            type: "wallet"
            account: "${parent_wallet_account}"
            account_name: "${parent_wallet_name}"
            bic: "PAEYPHM2XXX"
        provider: "paymongo"
        amount: "${steps.calc_split.output.wallet_share}"
        currency: "PHP"

Conditional sweep with a reserve floor

Only sweep what's above the reserve. If the wallet is below the reserve, top_up_amount is zero and the next send_money step fails validation. You can pair this with logic upstream that skips the run, or set a floor in your trigger.

steps:
    - name: "balance"
      get_wallet_balance:
        wallet_account: "${source_wallet_account}"
    - name: "calc"
      compute:
        outputs:
          reserve:   "2000000"
          available: "steps.balance.output.available_balance"
          to_sweep:  "monetary_max(available - reserve, 0)"
    - send_money:
        source:
            type: "wallet"
            account: "${source_wallet_account}"
        destination:
            type: "wallet"
            account: "${parent_wallet_account}"
            account_name: "${parent_wallet_name}"
            bic: "PAEYPHM2XXX"
        provider: "paymongo"
        amount: "${steps.calc.output.to_sweep}"
        currency: "PHP"

See Also