Top Up A Wallet On Low Balance

Schedule wallet top-ups that check a target wallet balance and fund the gap from another wallet when balance is low.


A scheduled workflow reads a wallet's available balance, computes the gap to a target, and transfers that gap from a funding wallet. If the wallet is already at or above the target, the workflow does nothing.

Problem

You operate a wallet that sends outbound payments throughout the day and need to keep its balance above a working minimum. Manually monitoring the balance is brittle. You want the funding to happen automatically on a recurring cadence.

Workflow definition

version: 1
name: "wallet-top-up"
description: "Fund the operating wallet up to PHP 500,000 from the funding wallet"
steps:
    - name: "balance"
      get_wallet_balance:
        wallet_account: "${input.target_wallet}"
    - name: "calc"
      compute:
        outputs:
          target:    "50000000"
          available: "steps.balance.output.available_balance"
          # Top up the gap, but never below zero.
          top_up:    "monetary_max(target - available, 0)"
    - name: "transfer"
      send_money:
        source:
            type: "wallet"
            account: "${input.funding_wallet}"
            account_name: "${input.funding_wallet_name}"
        destination:
            type: "wallet"
            account: "${input.target_wallet}"
            account_name: "${input.target_wallet_name}"
            bic: "PAEYPHM2XXX"
        provider: "paymongo"
        amount: "${steps.calc.output.top_up}"
        currency: "PHP"
        notes: "Auto top-up"

monetary_max(target - available, 0) keeps the top-up amount at zero or above. When the wallet is already above the target, top_up resolves to 0 and the send_money step rejects it as invalid_workflow_definition (amount must be greater than 0). The instance ends in failed status. That is the signal that no top-up was needed, not a real failure.

Trigger

Run the workflow every hour, or every 30 minutes if your outbound traffic is bursty:

curl --request POST 'https://workflow-api.paymongo.com/v1/triggers' \
  --header 'Authorization: Basic ${YOUR_BASIC_TOKEN}' \
  --header 'Organization-Id: ${YOUR_ORG_ID}' \
  --header 'Content-Type: application/json' \
  --data '{
    "workflow_id": "wf_topup",
    "condition": {
      "schedule": "@every 1h"
    }
  }'

What success looks like

When a top-up was needed:

{
  "data": {
    "instance_id": "inst_xyz",
    "status": "completed",
    "output": {
      "steps_executed": 3,
      "step_outputs": [
        {"available_balance": 30000000, "pending_balance": 0, "wallet_id": "..."},
        {"target": 50000000, "available": 30000000, "top_up": 20000000},
        {"status": "completed", "transfer_id": "tr_..."}
      ]
    }
  }
}

When no top-up was needed (top_up = 0), the instance ends in failed status with the third step's error populated. To distinguish "no work" from a real failure, inspect step_outputs[1].top_up before treating the failure as actionable.

Variations

  • Different target. Change the target value in the compute step. PHP 500,000 = 50000000 centavos.
  • Lower bound rather than fixed target. If the funding wallet should top up only when the balance falls below a floor (rather than to a fixed target), keep the same workflow but interpret target as the floor.
  • Cap the per-run amount. Wrap the top_up calculation in monetary_min(top_up, max_per_run) to cap how much the workflow moves in a single run.
  • Skip on weekends. Use a schedule like 0 * * * 1-5 (every hour, weekdays only).

See also