Manage payout destinations

Control where your money goes. This guide walks you through setting up payout destinations—the financial accounts that receive your earnings when Commerce automatically settles your balance. You'll connect your existing accounts to Commerce, configure them as destinations, and verify everything routes correctly.


Understanding payout destinations

When customers pay you through Commerce, those funds accumulate in your available balance. Periodically—weekly by default, though you can trigger manual payouts anytime—Commerce bundles settled transactions and transfers them to your financial accounts. That's a payout.

Each payout needs a destination: a financial account that receives the funds. Since you might accept payments in multiple currencies (GHS from Ghana, USD internationally, etc.), Commerce lets you configure one destination per currency. Each currency routes to its own financial account—the account type doesn't matter as long as it matches the currency. This currency-matching requirement prevents expensive cross-currency conversions and routing failures. (Note: If you need cross-currency payouts, see the Payouts FX conversion guide for information on enabling foreign exchange conversion.)

Think of payout destinations as your standing settlement instructions. Once configured, automatic payouts just work—funds flow from your balance to the right account without manual intervention. You'll typically set these up once during onboarding, then only touch them when opening accounts in new currencies or switching to different financial accounts.

For complete details on payout mechanics, timing, and how balance transactions bundle into payouts, see the Payouts reference.


Before you start

You'll need:

  • A Commerce account with API credentials (secret key for server requests, session token for authenticated calls)
  • Financial accounts in each currency you want to receive payouts for—these must already exist with your financial service provider
  • Push capability enabled on those accounts (so Commerce can send funds to them)

If you don't have financial accounts connected yet, you'll connect them in Step 1. If you already have them connected, skip straight to Step 2.


Step 1: Connect your financial accounts

Payout destinations must be financial accounts you own and control. Before configuring destinations, you need to connect each existing account to Commerce—this tells the platform where to route funds and establishes push permissions.

Why connect accounts first?

Commerce validates every destination to ensure funds can actually reach it. When you set a payout destination, the API checks:

  1. The financial account exists in your Commerce account
  2. You own it (it's tied to your authenticated session)
  3. The account's currency matches the payout currency
  4. Push operations are enabled (Commerce can send money out to it)

Attempting to configure an unconnected account as a destination fails immediately with a clear error—saving you from discovering routing problems when your first payout runs.

Connecting a financial account

Let's connect an existing financial account for GHS payouts. This example uses an MTN Mobile Money account, but the same pattern works for any financial account type you already have—other mobile money providers, bank accounts, or any supported wallet type.

Connect financial account

POST
/financial_accounts/connect
curl https://api.zebo.dev/financial_accounts/connect \
  -H "Authorization: Bearer YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "wallet",
    "currency": "ghs",
    "label": "MTN Settlement Wallet",
    "reference": "SETTLEMENT-GHS-001",
    "wallet": {
      "type": "mobile_money",
      "mobile_money": {
        "network": "mtn",
        "account": "0244123456"
      }
    },
    "push_configuration": {
      "enabled": true
    }
  }'

Response

{
  "financial_account": {
    "id": "fa_H3cNv7pQf9WbLt2mJs6yXrPq4Kz1Vd5G0aEiUo",
    "type": "wallet",
    "currency": "ghs",
    "label": "MTN Settlement Wallet",
    "reference": "SETTLEMENT-GHS-001",
    "created_at": "2025-04-14T10:22:30.000Z",
    "push_configuration": {
      "id": "push_cfg_Xyz789",
      "enabled_at": "2025-04-14T10:22:30.000Z"
    },
    "wallet": {
      "id": "wal_Abc123",
      "type": "mobile_money",
      "mobile_money": {
        "network": "mtn",
        "account": "0244123456"
      }
    }
  }
}

Key attributes explained

  • currency: Must match the payout currency you're configuring. Use ghs for Ghana Cedis, usd for US Dollars, etc. See supported currencies.
  • label: Human-readable name for your team and dashboard. Be descriptive: "MTN Settlement Wallet" beats "Wallet 1".
  • reference: Your internal identifier for reconciliation—use it to match this account in your systems.
  • push_configuration.enabled: true: Critical. This grants Commerce permission to send funds to this account. Without it, the account can't receive payouts.
  • Response id: Save this—you'll use it when configuring the destination in Step 2.

Connecting bank accounts

For bank accounts you already have, the structure is similar but uses bank-specific fields:

{
  "type": "bank",
  "currency": "usd",
  "label": "Chase Business Checking",
  "reference": "SETTLEMENT-USD-001",
  "bank": {
    "name": "John Smith",
    "account_number": "123456789",
    "routing_number": "021000021",
    "country": "us",
    "account_type": "checking"
  },
  "push_configuration": {
    "enabled": true
  }
}

The key difference: bank accounts need routing numbers and country codes for wire transfers or ACH, while mobile money just needs network and phone number.


Step 2: Configure payout destinations

With your financial accounts connected to Commerce, you're ready to map currencies to destinations. This tells Commerce exactly where to send funds for each currency.

Set payout destinations

POST
/payouts/set_destinations
curl https://api.zebo.dev/payouts/set_destinations \
  -H "Authorization: Bearer YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "destinations": {
      "ghs": "fa_H3cNv7pQf9WbLt2mJs6yXrPq4Kz1Vd5G0aEiUo"
    }
  }'

Response

{
  "settings": {
    "schedule": {
      "name": "weekly",
      "type": "automatic",
      "interval": "weekly",
      "schedule_on": "sunday",
      "description": "Automatic weekly payout. Default."
    },
    "destinations": {
      "ghs": "fa_H3cNv7pQf9WbLt2mJs6yXrPq4Kz1Vd5G0aEiUo"
    }
  }
}

What just happened

Commerce validated three things:

  1. Currency support: ghs is a supported payout currency
  2. Account ownership: Financial account fa_H3cNv7... exists in your Commerce account and belongs to you
  3. Currency match: The account's currency (ghs) matches the map key (ghs)

If any check failed, you'd get an immediate error with specific details about what's wrong. Since everything passed, the destination is now active. Your next automatic GHS payout will route to this account.

Configuring multiple currencies

If you accept payments in multiple currencies, set all destinations in one call:

{
  "destinations": {
    "ghs": "fa_H3cNv7pQf9WbLt2mJs6yXrPq4Kz1Vd5G0aEiUo",
    "usd": "fa_P8kWm2nRf5JxVc9Tb1QsYzLu7D4GhNa0Eq"
  }
}

Commerce maps each currency independently. Your GHS payouts go to one account, USD payouts to another. No cross-currency conversions, no routing confusion.

Updating destinations

Need to switch accounts? Call the same endpoint with the new financial account ID:

{
  "destinations": {
    "ghs": "fa_NewAccountID"
  }
}

Commerce overwrites the previous value. Your next payout uses the new destination. Currencies you don't include in the request remain unchanged—updating GHS doesn't affect your USD destination.

Removing destinations

To remove a currency's destination (disabling automatic payouts for that currency), send an empty string:

{
  "destinations": {
    "ghs": ""
  }
}

Automatic payouts for GHS will stop until you configure a new destination. Manual payouts (via /payouts/schedule) still work—you just need to specify the destination explicitly in each request.


Step 3: Verify your configuration

Always confirm destinations are set correctly before relying on automatic payouts. This prevents surprises when your first settlement runs.

Get payout settings

POST
/payouts/settings
curl https://api.zebo.dev/payouts/settings \
  -H "Authorization: Bearer YOUR_SECRET_KEY"

Response

{
  "settings": {
    "schedule": {
      "name": "weekly",
      "type": "automatic",
      "interval": "weekly",
      "schedule_on": "sunday",
      "description": "Automatic weekly payout. Default."
    },
    "destinations": {
      "ghs": "fa_H3cNv7pQf9WbLt2mJs6yXrPq4Kz1Vd5G0aEiUo"
    }
  }
}

What to check

  1. Schedule cadence: The schedule object shows when automatic payouts run. Default is weekly on Sundays. If you need daily or monthly settlements, contact support to adjust your schedule.

  2. Destinations map: Verify each currency you accept appears in destinations with the correct financial account ID. Missing currencies won't receive automatic payouts.

  3. Account IDs match: Cross-reference the financial account IDs against your records. A typo here means funds route to the wrong account (though Commerce validates ownership, so they'll still land at one of your accounts—just maybe not the right one).

Viewing in the dashboard

Your payout configuration also appears in the Commerce Business dashboard at business.zebo.dev. Navigate to Settings → Payouts to see:

  • Active payout schedule (when settlements run)
  • Configured destinations by currency
  • Recent payout history with status and amounts
  • Financial account details (masked account numbers for security)

The dashboard gives your team a visual confirmation that everything's wired correctly, without needing API access. Use it for quick sanity checks and to onboard non-technical teammates who need visibility into settlement flows.


How automatic payouts work

With destinations configured, here's what happens during each settlement cycle:

  1. Balance accumulation: As customers pay you, successful payments create balance transactions. These transactions settle (usually within minutes to hours) and become part of your available balance.

  2. Payout scheduling: On your configured schedule (e.g., every Sunday at midnight UTC), Commerce checks your available balance for each currency. For each currency with a positive balance and configured destination, Commerce creates a payout.

  3. Transaction bundling: Commerce identifies all settled balance transactions for that currency and bundles them into the payout. The total amount is the sum of all bundled transactions, capped at your configured maximum payout threshold (if set).

  4. Transfer execution: Commerce initiates the transfer to your destination financial account. For mobile money, this typically completes within minutes. For bank transfers, allow 1-3 business days depending on the receiving bank and country.

  5. Status updates: The payout status progresses from scheduledexecutingsucceeded. You can poll /payouts/lookup for real-time status or rely on webhooks (if configured) to get notified when the payout completes.

  6. Balance deduction: Once the payout succeeds, the transferred amount leaves your available balance. The balance transactions included in that payout are marked with the payout_id, creating a clear audit trail from payment to settlement.

Manual payouts

Don't want to wait for the next scheduled payout? Trigger one manually with /payouts/schedule. This is useful for:

  • Cash flow needs: Pull funds immediately when you need working capital
  • Testing: Verify your destination works before the first automatic settlement
  • Threshold-based settlements: Trigger payouts when your balance hits a certain amount

Manual payouts follow the same flow as automatic ones but execute on-demand rather than on a schedule. See the Schedule a payout documentation for details.


Security and best practices

Validate account ownership

Commerce enforces strict ownership checks—you can only configure financial accounts tied to your Commerce account as destinations. This prevents accidentally (or maliciously) routing funds to someone else's account. If you try to use an account you don't own, the API rejects the request immediately.

Use descriptive labels

Future you will thank present you for clear financial account labels. "MTN Settlement - GHS" beats "Account 1" when you're debugging a routing issue at 2am or explaining settlement flows to your finance team.

Monitor payout status

Don't assume payouts always succeed. Network issues, account closures, and provider outages can cause failures. Monitor payout status via:

  • API polling: Call /payouts/lookup periodically for critical payouts
  • Webhooks: Configure payout.succeeded and payout.failed webhooks for real-time notifications
  • Dashboard: Check the Business dashboard for visual status and failure alerts

When a payout fails, Commerce provides a detailed error (account closed, insufficient balance, provider timeout, etc.) so you can diagnose and fix the issue quickly.

Separate operating and settlement accounts

Consider using separate financial accounts for daily operations versus payout settlements. This isolates settlement flows from operating expenses, simplifies bookkeeping, and makes reconciliation easier. Your mobile money account might handle settlements while a separate account covers business expenses.

Test before going live

Before your first production payout, test the full flow:

  1. Connect a test financial account (use a real account you control)
  2. Configure it as a destination for test mode
  3. Trigger a manual payout with a small amount
  4. Verify funds arrive at the correct account

This catches configuration errors, validates your financial account details, and builds confidence in the settlement flow before real customer funds move.


Common issues and solutions

"Currency not supported" error

Cause: You're trying to configure a destination for a currency Commerce doesn't support yet.

Solution: Check the supported currencies list. If you need a specific currency, contact support—we regularly add new currencies based on demand.

"Financial account not found" error

Cause: The financial account ID doesn't exist in your Commerce account, or you've made a typo.

Solution: List your financial accounts via /financial_accounts/page and verify the ID. If the account exists but you're still getting this error, check that you're using the correct API credentials (secret key for your account, not test mode credentials).

"Currency mismatch" error

Cause: You're trying to map a GHS destination to a USD financial account (or vice versa).

Solution: Connect a financial account in the correct currency first. Each destination must match its map key—GHS destinations need GHS accounts.

"Push configuration not enabled" error

Cause: The financial account exists but doesn't have push permissions enabled.

Solution: Update the financial account to enable push configuration. You can't receive payouts to an account that doesn't allow outbound transfers from Commerce.

Payout fails with "account closed" error

Cause: The destination financial account was closed at your financial service provider.

Solution: Connect a different financial account and update the destination mapping. If you recently closed the account, the provider may take 24-48 hours to fully process the closure—wait until that completes before attempting new payouts.

Payout takes longer than expected

Cause: Bank transfers inherently take time—1-3 business days is normal for many banks, especially international transfers.

Solution: Check the payout status via /payouts/lookup. If it's still executing after the expected timeframe, the provider may be experiencing delays. Mobile money transfers typically complete within minutes; bank transfers take longer. Contact support if a payout has been executing for more than 5 business days.


Next steps

With payout destinations configured, you're ready to receive settlements automatically. Here's what to explore next:

Questions? Check the Payouts reference for complete API details, or contact support at support@zebo.dev.

Was this page helpful?