EVM mass payouts
ERC-20 mass payouts on Polygon and more.
EVM mass payouts distribute ERC-20 tokens (USDC, USDT) to many recipients via an on-chain escrow contract. The merchant deposits tokens into the contract; Payzum's operator wallet pays gas to trigger each distribution batch.
EVM mass payouts use the same CSV format and quote concepts as UTXO payouts. See Mass payouts overview for the CSV format, quote field reference, and idempotency details.
How EVM payouts differ from UTXO
Unlike UTXO (where Payzum holds a derived signing key), EVM uses an on-chain escrow contract. Funds never leave the merchant's control until distributeBatch is called:
- Merchant deposits tokens into the
PayzumMassPayoutcontract via an ERC-20approve+deposit. - Payzum's operator wallet calls
distributeBatchfor each batch, paying only gas. - Recipients receive tokens directly from the contract.
The quote fee covers Payzum's service fee (basis points on the token amount) plus an estimated gas cost in the same token denomination.
Supported chains and tokens
Polygon is the first supported chain. Additional EVM chains are rolling out. Call GET /v1/currencies for the current live set — do not hardcode chain or contract addresses.
On the dashboard wizard, select Testnet to use Polygon Amoy for integration testing before going live on mainnet.
CSV format
Use the standard CSV format (header row with address, amount, optional label) plus the token field in the request body to specify the ERC-20 token.
address,amount,label
0xAbCd1234abcd1234AbCd1234abcd1234AbCd1234,10.00,user-001
0x5678EfGh5678EfGh5678EfGh5678EfGh5678EfGh,25.50,user-002Amounts are decimal strings in whole token units (e.g. 10.00 for 10 USDC).
Endpoints
All merchant endpoints require the X-Api-Key header.
| Method | Path | Description |
|--------|------|-------------|
| POST | /v1/evm-mass-payout | Create order (multipart form with chain, mode, token, csv) |
| GET | /v1/evm-mass-payout | List orders (paginated) |
| GET | /v1/evm-mass-payout/:id | Fetch order with batch detail |
| GET | /v1/evm-mass-payout/:id/recipients | Paginated recipient rows |
| GET | /v1/evm-mass-payout/:id/deposit-instructions | Where and how to deposit tokens into the contract |
| POST | /v1/evm-mass-payout/:id/confirm | Confirm quote; advance to pending_deposit |
| POST | /v1/evm-mass-payout/:id/cancel | Cancel order |
| POST | /v1/evm-mass-payout/:id/refund | Request a refund for a cancelled, expired, or partial-failed order |
| POST | /v1/evm-mass-payout/:id/refresh-quote | Refresh the gas/fee estimate |
Create order — request fields
POST /v1/evm-mass-payout accepts multipart/form-data.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| chain | string | yes | EVM chain identifier (e.g. polygon). Call GET /v1/currencies for the live set. |
| mode | string | yes | mainnet | testnet |
| token | string | yes | Token identifier (e.g. usdc, usdt) |
| csv | file | yes | CSV file with header row; columns address, amount, optional label |
Deposit instructions
After confirming the order, call GET /v1/evm-mass-payout/:id/deposit-instructions to get the contract address and the exact token amount to approve and deposit. The dashboard wizard handles this step with a Web3 wallet (MetaMask or similar).
Order lifecycle
pending_quote → pending_deposit → deposit_confirmed → executing
→ completed | partial_failed | expired | cancelled | refunded
The EVM lifecycle adds the deposit_confirmed state between pending_deposit and executing. The deposit-watcher detects the on-chain Deposited event and advances the order after the required confirmation count.
cURL example — create order
curl -X POST "$PAYZUM_BASE/v1/evm-mass-payout" \
-H "X-Api-Key: $PAYZUM_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-F "chain=polygon" \
-F "mode=testnet" \
-F "token=usdc" \
-F "csv=@payouts.csv"The response includes the order object with the quote and deposit instructions reference. Call confirm, then follow the deposit-instructions endpoint to fund the contract.
Refunds
If an order is cancelled, expires, or ends in partial_failed, call POST /v1/evm-mass-payout/:id/refund to trigger the operator's emergencyRefund on the contract. Funds are returned to the original depositor address on-chain.