---
updatedAt: 2026-06-18T05:19:11.000Z
agentTools:
  projectIndex: https://docs.paymongo.com/llms.txt
---

# Sweeps Wallet On A Schedule

Schedule wallet sweeps that keep a reserve balance, calculate the sweep amount, and transfer funds to a bank account or parent wallet.

<br />

A scheduled trigger periodically reads a wallet's available balance, computes the amount above a reserve floor, and sweeps it elsewhere. The reserve protects against zero-balance transfers that would fail validation, and against draining the wallet below the per-transfer fee that PayMongo charges.

# Problem

You operate a PayMongo wallet that accumulates balance over time and want to move it to a bank account (settlement) or to a parent wallet (consolidation) on a recurring cadence. The minimum reserve you keep on the source wallet must be honoured every run.

# Workflow definition

```yaml Sweep to bank with reserve floor
version: 1
name: "daily-sweep-wallet-balance"
description: "Daily sweep from merchant wallet to bank, keeping a reserve"
steps:
    - name: "check_balance"
      get_wallet_balance:
        wallet_account: "${input.source_wallet}"
    - name: "calc"
      compute:
        outputs:
          # Keep PHP 100 (10000 centavos) on the source wallet to cover the transfer fee.
          min_reserve:  "10000"
          balance:      "steps.check_balance.output.available_balance"
          sweep_amount: "monetary_max(balance - min_reserve, 0)"
    - name: "send"
      send_money:
        source:
            type: "wallet"
            account: "${input.source_wallet}"
            account_name: "${input.source_wallet_name}"
        destination:
            type: "bank"
            account: "${input.bank_account}"
            account_name: "${input.bank_account_name}"
            bic: "${input.bank_bic}"
        provider: "auto"
        amount: "${steps.calc.output.sweep_amount}"
        currency: "PHP"
        notes: "Daily sweep"
```
```yaml Sweep to parent PayMongo wallet
version: 1
name: "daily-sweep-to-parent-wallet"
description: "Daily sweep from sub-wallet to parent wallet"
steps:
    - name: "check_balance"
      get_wallet_balance:
        wallet_account: "${input.source_wallet}"
    - send_money:
        source:
            type: "wallet"
            account: "${input.source_wallet}"
            account_name: "${input.source_wallet_name}"
        destination:
            type: "wallet"
            account: "${input.parent_wallet}"
            account_name: "${input.parent_wallet_name}"
            bic: "PAEYPHM2XXX"
        provider: "paymongo"
        amount: "${steps.check_balance.output.available_balance}"
        currency: "PHP"
        notes: "Sweep to parent"
```

A wallet-to-wallet sweep does not need a reserve floor. There is no per-transfer fee for `provider: paymongo` transfers between PayMongo wallets, so sweeping the full available balance is safe.

# Trigger

A schedule trigger runs the workflow on a cron expression. Use a Manila-time prefix if you want the cron evaluated locally:

```shell Daily sweep at 02:00 Manila time
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_abc123",
    "condition": {
      "schedule": "CRON_TZ=Asia/Manila 0 2 * * *"
    }
  }'
```

# What success looks like

A completed instance run by the trigger:

```json
{
  "data": {
    "instance_id": "inst_xyz",
    "workflow_id": "wf_abc123",
    "status": "completed",
    "output": {
      "steps_executed": 3,
      "step_outputs": [
        {"available_balance": 5000000, "pending_balance": 0, "wallet_id": "..."},
        {"sweep_amount": 4990000, "balance": 5000000, "min_reserve": 10000},
        {"status": "completed", "transfer_id": "tr_..."}
      ]
    }
  }
}
```

If the wallet balance is below the reserve, `sweep_amount` 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. To avoid this you can short-circuit the workflow upstream with a guard.

# Variations

* **Different cadence.** Switch the cron expression: every hour at minute 5 (`5 * * * *`), every Monday at 09:00 Manila (`CRON_TZ=Asia/Manila 0 9 * * 1`).
* **Sub-hourly recurrence.** Use the interval shorthand: `"schedule": "@every 30m"`.
* **Different reserve.** Adjust the `min_reserve` value in the `compute` step. Higher reserves leave more cushion for the per-transfer fee.
* **Multiple beneficiaries.** Add more `send_money` steps after the sweep. See [Split a Payout](https://docs.paymongo.com/docs/fiaas-workflows-split-a-payout).

# See also

* [Get Wallet Balance Step](https://docs.paymongo.com/docs/fiaas-workflows-get-wallet-balance-step): parameters and outputs.
* [Compute Step](https://docs.paymongo.com/docs/fiaas-workflows-compute): the monetary helper reference.
* [Schedule-Based Triggers](https://docs.paymongo.com/docs/fiaas-workflows-schedule-based-triggers): cron format and time zones.
* [Top Up a Wallet on Low Balance](https://docs.paymongo.com/docs/fiaas-workflows-top-up-a-wallet-on-low-balance): the inverse pattern.

<br />