Fund and spend from a wallet
A Moov wallet holds funds inside Moov. Card and ACH payments settle into a wallet, and payouts are paid from one. In this recipe, a business account (your partner account, or a connected business you manage) checks its wallet, funds it with an ACH debit from its own bank account, pays a recipient from the wallet, and then sets up a sweep so payouts and top-ups happen automatically.
Prerequisites
- Everything in Before you start: test mode API keys, authentication headers, your partner account ID, and a webhook endpoint
- A business account with
wallet.balanceandsend-funds.achenabled. Addsend-funds.instant-bankto pay out with instant payments (RTP or FedNow). - A recipient with a linked bank account for step 5. The bank payout recipe shows how to set one up.
Steps
Find the wallet and check its balance
Accounts with wallet.balance enabled get a default wallet. List the account's wallets with the list wallets endpoint:
curl -X GET "https://api.moov.io/accounts/{accountID}/wallets" \
-H "Authorization: Bearer {token}" \
-H "X-Moov-Version: v2026.07.00"
Each wallet in the response has a walletID, a walletType (default or general), a status, and an availableBalance with value in cents. Only the available balance can be spent; funds from pending ACH debits and card payments don't count until they settle. To get one wallet, use the get wallet endpoint. To keep funds for different purposes apart, create more wallets; see multiple wallets. Deeper guide: wallet balance.
Link and verify the funding bank account
ACH debits need a verified bank account. Link the business's bank account with the link bank account endpoint, then verify it.
curl -X POST "https://api.moov.io/accounts/{accountID}/bank-accounts" \
-H "Authorization: Bearer {token}" \
-H "X-Moov-Version: v2026.07.00" \
-d '{
"account": {
"holderName": "Whole Body Fitness LLC",
"holderType": "business",
"accountNumber": "12345654321",
"bankAccountType": "checking",
"routingNumber": "322271627"
}
}'
Start instant micro-deposit verification with POST /accounts/{accountID}/bank-accounts/{bankAccountID}/verify, then submit the code with PUT on the same path ({"code": "0001"} in test mode). Until the bank account's status is verified, it has no ach-debit-fund payment method. Deeper guide: bank account verification.
Get the funding payment methods
Funding the wallet is a transfer from the bank account's ach-debit-fund payment method to the wallet's moov-wallet payment method, both on the same account. List them with the list payment methods endpoint:
curl -X GET "https://api.moov.io/accounts/{accountID}/payment-methods" \
-H "Authorization: Bearer {token}" \
-H "X-Moov-Version: v2026.07.00"
From the response, save the paymentMethodID with paymentMethodType: ach-debit-fund (its bankAccount.bankAccountID matches your verified account) and the one with paymentMethodType: moov-wallet (its wallet.walletID matches the wallet from step 1). Use ach-debit-fund for moving your own money; ach-debit-collect is for collecting payments from someone else. Deeper guide: payment methods.
Fund the wallet with an ACH debit
Create the funding transfer with the create transfer endpoint:
curl -X POST "https://api.moov.io/accounts/{partnerAccountID}/transfers" \
-H "Authorization: Bearer {token}" \
-H "X-Moov-Version: v2026.07.00" \
-H "X-Idempotency-Key: 3c9d1e7f-5a2b-4c8d-9e0f-1a2b3c4d5e6f" \
-d '{
"source": { "paymentMethodID": "{achDebitFundPaymentMethodID}" },
"destination": { "paymentMethodID": "{walletPaymentMethodID}" },
"amount": { "currency": "USD", "value": 500000 },
"description": "Wallet top-up"
}'
This pulls $5,000.00 from the bank account. Moov processes ACH debits same-day when it can, but with standard processing it holds debited funds for two banking days before they're available in the wallet, to cover possible returns. Accounts approved for faster processing skip the hold. In test mode, weekday ACH transfers complete in about an hour. Deeper guides: fund a wallet and ACH processing speeds.
Pay out from the wallet
Once the funds are available, spend them. A payout uses the wallet as the source and a recipient's bank credit payment method as the destination. Get the recipient's ach-credit-same-day, ach-credit-standard, or instant-bank-credit payment method ID from their list payment methods response, then create the transfer:
curl -X POST "https://api.moov.io/accounts/{partnerAccountID}/transfers" \
-H "Authorization: Bearer {token}" \
-H "X-Moov-Version: v2026.07.00" \
-H "X-Idempotency-Key: 8a7b6c5d-4e3f-4a1b-9c8d-7e6f5a4b3c2d" \
-d '{
"source": { "paymentMethodID": "{walletPaymentMethodID}" },
"destination": { "paymentMethodID": "{recipientAchCreditSameDayPaymentMethodID}" },
"amount": { "currency": "USD", "value": 125000 },
"description": "Weekly instructor payout"
}'
The wallet's available balance drops as soon as the transfer is created. If the balance is too low, the transfer fails with failureReason: wallet-insufficient-funds. You can also pay another Moov account's moov-wallet payment method; wallet-to-wallet transfers complete almost instantly. Review every movement with the list wallet transactions endpoint. Deeper guides: send funds and wallet transactions.
Automate with sweeps
Instead of moving funds by hand, a sweep settles the wallet to a bank account every day. Payment and fee activity accrues during the day; at the daily close (4:00 PM ET by default), Moov pays out the positive balance above your minimum or debits the bank account to cover a negative one. Create one with the create sweep config endpoint:
curl -X POST "https://api.moov.io/accounts/{accountID}/sweep-configs" \
-H "Authorization: Bearer {token}" \
-H "X-Moov-Version: v2026.07.00" \
-d '{
"walletID": "{walletID}",
"status": "enabled",
"pushPaymentMethodID": "{ownAchCreditSameDayPaymentMethodID}",
"pullPaymentMethodID": "{achDebitFundPaymentMethodID}",
"minimumBalance": "1000.00",
"statementDescriptor": "WBF PAYOUT"
}'
pushPaymentMethodID is a credit payment method on the account's own bank account (ach-credit-standard, ach-credit-same-day, or instant-bank-credit). pullPaymentMethodID is the ach-debit-fund payment method Moov uses if the wallet goes negative, for example after a refund or dispute. minimumBalance keeps $1,000.00 in the wallet. Deeper guide: sweeps.
What to watch for
| Signal | What it means | What to do |
|---|---|---|
transfer.updated with source.achDetails.status completed |
The ACH debit cleared | Expect availableBalance to update once any hold ends |
transfer.updated with status failed and source.achDetails.return |
The funding debit was returned during clearing, for example R01 insufficient funds |
No funds were added; fix the bank account or retry later |
transfer.updated with status reversed |
A debit was returned after funds became available | Moov deducts the amount from the wallet, which can go negative |
balance.updated |
The wallet's balance changed | Refresh the balance you show users |
walletTransaction.updated |
A wallet transaction is pending or completed | Reconcile against your ledger |
sweep.created, sweep.updated |
A sweep period opened, or a sweep's status changed | Match the sweep's transfer to your payout records |
To test a funding failure, send an ACH debit for 5501 ($55.01, R01). See ACH returns for how each return code affects the wallet and bank account.