Disbursements
Money to your recipients' accounts, one transfer or a thousand at once, in real-time or by the next banking day.
Overview
PayMongo Disbursements is how you move money out of your PayMongo Wallet to destinations you choose: bank accounts, e-wallets, or other PayMongo Wallets. It is designed for any outbound flow where your business needs to pay someone — payroll, vendor settlements, contractor fees, refunds, rebates, incentives, or customer cash-outs.
Disbursements run on the same Transfers infrastructure that powers the rest of PayMongo's money movement layer, giving you one consistent API and Dashboard experience regardless of the rail you choose.
What you can do
- Send one-off transfers to a single recipient, or send to up to 1,000 recipients in a single batch.
- Route each transfer over the right rail — InstaPay for real-time, low-value payouts; PESONet for same- or next-banking-day bulk settlements.
- Pay or receive via QR Ph for person-to-person, person-to-merchant, or person-to-biller flows.
- Track status in real time through the Wallet Dashboard, webhooks, or callback URLs.
- Control authorization with email-based OTP confirmation on Dashboard-initiated transfers.
Supported rails
| Rail | Type | Speed | Per-transaction limit | Best for |
|---|---|---|---|---|
| InstaPay | Domestic EFT | Real-time (up to 20 min for final status) | PHP 50,000 | Small-value, time-sensitive payouts, 24/7 |
| PESONet | Domestic EFT | Same / next banking day (cycle-based) | PHP 10,000,000 | Bulk payouts, larger amounts, scheduled disbursements |
| Wallet-to-Wallet | Internal | Instant | No interbank limit | Closed-loop transfers between PayMongo Wallets |
| QR Ph | Domestic QR | Real-time | Follows underlying rail (InstaPay) | P2P, P2M, and P2B flows using scanned or generated QR codes |
| Cross-border (coming soon) | International | TBD | TBD | Global payouts via fiat or stablecoin rails |
Pricing
- InstaPay and PESONet transfers have a standard rate of PHP 10.00 per transaction.
- Every account is entitled to one free transfer per week.
- Volume-based preferential rates are available. Contact your PayMongo account manager or [email protected] to request a custom rate.
Local disbursements
Local disbursements cover every outbound transfer within the Philippines. They move from your PayMongo Wallet to a receiving bank account, e-wallet, or another PayMongo Wallet using InstaPay, PESONet, or QR Ph.
Before you start
To initiate a local disbursement, make sure you have:
- An activated PayMongo Wallet.
- Sufficient balance to cover the transfer amount plus the PHP 10.00 fee per transaction.
- Correct recipient details — bank or e-wallet name, account name, and account number. Mismatched names or invalid account numbers are the most common cause of failed transfers.
- Access to the registered email associated with your account — Dashboard transfers require an email-delivered One-Time PIN (OTP).
- If you plan to integrate programmatically, valid API keys for your environment (test mode and live mode).
Understanding the rails
InstaPay — instant, 24/7, lower limit
InstaPay is a real-time electronic fund transfer service between Philippine banks and e-wallets.
- Transactions are typically instant.
- Runs 24/7, including weekends and holidays.
- Hard cap of PHP 50,000 per transaction.
- If a transaction is stuck in a pending state, allow up to 20 minutes for the final status to reflect on your Dashboard or webhook.
Use InstaPay for single contractor payments, customer rebates, refunds, or any payout under PHP 50,000 that needs to arrive quickly.
PESONet — batch, scheduled, higher limit
PESONet is a batch-based electronic fund transfer service designed for higher-value or bulk transactions.
- Transactions are aggregated and settled in cycles on banking days.
- Hard cap of PHP 10,000,000 per transaction.
- Transactions initiated on non-banking days (weekends, holidays) are processed on the next banking day.
PESONet cycles:
| Cycle | Cut-off time | Processed by |
|---|---|---|
| 1st Cycle | Before 10:00 AM | 1:00 PM the same banking day |
| 2nd Cycle | Before 1:00 PM | 4:00 PM the same banking day |
| 3rd Cycle | Before 4:00 PM | 7:00 PM the same banking day |
Note: The receiving bank or e-wallet may apply its own internal schedule, so the exact time funds appear in the recipient's account can vary slightly from the cycle end.
Use PESONet for payroll runs, supplier batch payments, or any disbursement that exceeds InstaPay's PHP 50,000 limit.
Sending a transfer through the Dashboard
The PayMongo Dashboard is the fastest way to disburse funds without writing any code. You can send to a single recipient or process a batch of up to 1,000 transactions at once.
Single transfer
- Log in to your PayMongo Dashboard.
- Go to the Wallet Dashboard.
- On the upper right, click Send Funds.
- Fill in the recipient details — bank or e-wallet, account name, account number, and amount.
- Click Continue, review the details, then click Submit.
- Enter the OTP sent to your registered email to authorize the transfer.
- Once submitted, the transaction appears in your Wallet transaction history.
Batch transfer
You can send to multiple recipients in one submission — useful for payroll, recurring vendor payouts, or commission disbursements.
- From the Wallet landing page, click Send Funds.
- Enter the details of your first transaction (recipient bank, account name, account number, amount) and click Add.
- Repeat for each additional recipient. You can add up to 1,000 transactions in a single batch.
- Review the list of all added transactions in the Transactions table.
- Click Continue to proceed, or Cancel to clear the entire batch and start over.
- Click Submit and enter the OTP to authorize the batch.
Batch rule — one network per batch: A single batch must use either InstaPay or PESONet, not both. If you have a mix, split them into two separate batches.
Sending a transfer through the API
For developers building automated disbursement workflows, transfers follow a simple pattern:
- Retrieve the list of receiving institutions supported by the rail you want to use — either List All Receiving Institutions for the InstaPay set, or the PESONet-enabled set depending on your Wallet's capabilities.
- Create the wallet transaction using Create a Wallet Transaction. Include the recipient's bank ID, account number, account name, amount, and description.
- Track status either by:
- Supplying a
callback_urlin the create request so PayMongo POSTs the final status to your endpoint, or - Polling Retrieve a Wallet Transaction by ID.
- Supplying a
The same endpoint handles both InstaPay and PESONet — the rail is determined by the receiving institution you select and, where applicable, by the amount.
Test mode provides a simulated environment with no real fund movement so you can validate your integration end-to-end before going live.
Tracking disbursement status
Every transfer moves through one of three terminal or intermediate states:
| Status | Meaning |
|---|---|
pending | The transfer is still being processed. Allow up to 20 minutes for InstaPay and up to 1 banking day for PESONet before treating a transfer as stuck. |
succeeded | The transfer has been credited to the recipient. |
failed | The transfer did not complete. It is generally safe to retry after reviewing the error reason. |
Webhooks and callback URLs
Include a callback_url when creating a wallet transaction and PayMongo will POST the final status payload to your endpoint as soon as the status changes. This is the recommended way to keep your systems in sync without polling.
A typical status payload looks like this:
{
"data": {
"id": "wallet_tr_AYD5d5e5J2NsHL15zy4ord4V",
"type": "wallet_transaction",
"attributes": {
"wallet_id": "wallet_Y1fYZhnbA4JAiQy24ARbXbTE",
"amount": 100,
"batch_transaction_id": null,
"callback_url": "https://example.com/webhooks/paymongo",
"currency": "PHP",
"description": "This is a wallet transaction.",
"fee": 0,
"livemode": true,
"net_amount": 100,
"provider": "paymongo",
"provider_error": null,
"provider_error_code": null,
"purpose": "Payroll disbursement",
"receiver": {
"bank_account_name": "Receiver Testmode",
"bank_account_number": "516646818064",
"bank_code": "PAEYPHM2XXX",
"bank_id": "824",
"bank_name": "PAYMONGO PAYMENTS, INC."
},
"reference_number": "X3veQ6EaqjUuQnsa3noU",
"sender": { "...": "..." },
"status": "succeeded",
"type": "send_payment",
"transfer_id": "tr_hn3hR2g7qYAZ6it23ptk5NqZ",
"created_at": 1753947245,
"updated_at": 1753947245
}
}
}Key fields to watch:
status— one ofsucceeded,pending, orfailed.reference_number— use this when reconciling with the recipient's bank or raising a support ticket.provider_errorandprovider_error_code— populated on failure; use these to map to user-facing messages.transfer_idandbatch_transaction_id— link individual wallet transactions back to the parent transfer and batch.
QR sending and receiving
QR-based transfers let you move money using QR Ph — the national standard for QR codes in the Philippines — without requiring the sender to know the recipient's account number.
Use cases
- Receive funds from other banks directly into your PayMongo Wallet by presenting a dynamic or static QR.
- Send funds to other banks by scanning the recipient's QR and deducting the amount from your PayMongo Wallet.
- Pay merchants by scanning a QR Ph standee or POS-generated code.
- Pay billers by scanning the accepted biller QR code printed on a statement of account.
Flow types
| Type | Description |
|---|---|
| P2P | Person-to-Person — individual account to individual account |
| P2M | Person-to-Merchant — individual account to a merchant |
| P2B | Person-to-Biller — individual account to a biller |
QR flows settle on the underlying EFT rail (typically InstaPay) so they inherit the same speed, limits, and pricing.
Integration notes
- If a scanned QR is missing mandatory fields, the API responds with the list of missing fields or values.
- Test mode simulates the full QR scan-to-settle flow for both sending and receiving.
Error handling
Failed transfers return an error code that you can surface back to your users. Errors fall into two broad groups: PayMongo-level errors (caused by your request or account state) and rail-level errors (returned by InstaPay or PESONet using ISO 20022 status codes).
Common PayMongo transfer errors
| Error code | Cause | What to do |
|---|---|---|
transaction_limit_exceeded | Amount exceeds PHP 50,000 (InstaPay) or PHP 10,000,000 (PESONet) | Lower the amount or split across multiple transfers. |
parameter_above_maximum | A payload value exceeds its allowed maximum | Same as above — reduce the amount or adjust the value. |
parameter_format_invalid | Invalid payload (e.g., malformed account number) | Re-check the payload, especially recipient account number and amount. |
resource_not_found | Account does not exist | Verify the recipient's account details before retrying. |
resource_frozen_state | Recipient account is frozen | Contact [email protected] — the account cannot receive transfers. |
resource_closed_state | Recipient account is closed | Use a different recipient account. |
transfer_to_self_not_allowed | You are sending to your own wallet | Enter a different recipient. |
provider_processing_error | Third-party (InstaPay/PESONet) processing issue | Retry later. If it persists, contact support with the transfer_id. |
too_many_requests | Rate-limited | Back off and retry after a few minutes. |
internal_server_error | Unexpected server error | Retry in a few hours. Escalate to treasury via support with the full payload and transfer_id. |
Rail-level (ISO 20022) errors
InstaPay and PESONet surface granular status codes when a transfer is rejected downstream. The most frequently seen ones:
| Code | Meaning | Typical action |
|---|---|---|
AC01 / AC03 / RC04 | Invalid or non-existent recipient account number | Verify the account number and retry. |
AC04 | Recipient account is closed | Use a different account. |
AC06 | Recipient account is blocked | Use a different account. |
AG01 | Transaction forbidden for sender or receiver | Verify the recipient can receive funds; contact support if it persists. |
AM04 | Insufficient funds on the settlement account | Fund your account and retry. |
AM05 / DU03 | Duplicate transaction detected | Check history before retrying. |
AM14 | Recipient account's receiving limit exceeded | Try a different account or wait for limits to reset. |
DNOR | Recipient bank is not registered on the rail | Use a different bank. |
DT05 | Invalid cut-off time | Retry within banking hours. |
DS24 | Receiving bank did not respond in time | Retry in a few hours. |
FF05 | Bank does not support the selected transfer method (e.g., QR transfer not enabled) | Use a different transfer method. |
FF10 | Processing error on the receiving bank | Retry later. |
TM01 | Cut-off time missed | Retry within banking hours. |
9910 / 9912 | Receiving bank or participant is offline (InstaPay) | Retry later. |
AB01–AB10 | Clearing or settlement aborted / timeout | Retry after a few hours. |
For the complete ISO 20022 code list — including less common errors — see the API reference's Transfer Error Codes table. When surfacing errors to end users, translate the raw code into a friendly action message; the most frequent codes above cover the vast majority of real-world cases.
Retry guidance
pendingis not an error — give InstaPay up to 20 minutes and PESONet up to one banking day before taking action.failedtransfers are generally safe to retry once the underlying cause (invalid account, insufficient funds, rate limit) is resolved.- Never auto-retry without checking for
AM05/DU03(duplicate) responses — your first attempt may have already succeeded.
Cross-border disbursements (coming soon)
Cross-border disbursements will let you send money out of the Philippines to international destinations via fiat and stablecoin rails.
This section is reserved. Scope, supported corridors, fees, timelines, and integration details are pending confirmation from the product team and will be published here ahead of launch.
Planned scope (subject to change):
- Outbound fiat rails to major corridors.
- Outbound stablecoin rails for programmatic global payouts.
- Unified API surface — same Transfers endpoints, with additional destination parameters.
If cross-border disbursement is on your roadmap and you would like to be notified when the capability opens in beta, reach out to your PayMongo account manager.
Related reading
- Wallets — how to fund the PayMongo Wallet that disbursements draw from.
- Ledgers and Workflows — how to automate disbursement logic, including scheduled transfers and splitting disbursements across destinations.
- Webhooks — how to configure reliable event delivery for transfer status updates.
Updated about 4 hours ago