Payouts
Payouts
Three read-only endpoints cover the payout domain:
- List Payouts — page through your payout history.
- Get Payout — fetch the full detail of a single payout by its
payout_order_id. - Get Balance — read the available on-chain balance of your receiving wallet.
Payouts cover two scenarios, distinguished by scene:
payout— paying a third party (e.g. a supplier or a revenue-share recipient).withdraw— moving settled funds to your own wallet.
All requests must be authenticated with your
API Key. The gateway resolves your merchant identity from the API Key, so you do
not send merchant_id in the query — it is ignored if present.
Base URL
https://pay-openapi.morph.network/pro/merchant/payout/v1
Endpoint paths in this page are relative to that base URL.
Response envelope
Every response is wrapped in a common envelope:
{
"error_code": 0,
"msg": "success",
"data": {},
"trace": "..."
}
Business success or failure is determined by error_code (error_code == 0
means success), not by the HTTP status code alone. See the
Error Codes reference for the full list.
List Payouts
GET /payouts
Returns payout history in reverse-chronological order by default, with
cursor-based pagination. Omit scene to return both payout and withdraw
records.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
scene | string | No | payout (pay a third party) or withdraw (withdraw to yourself); omit to return both. |
status | string | No | Filter by payout status. One of pending, success, failed. |
chain | string | No | Filter by chain identifier. Max 32 characters. |
reference_id | string | No | Filter by your business reference id. Max 64 characters. |
start | string | No | Range start, Unix milliseconds or RFC3339. Max 32 characters. |
end | string | No | Range end, Unix milliseconds or RFC3339. Max 32 characters. |
sort_by | string | No | Sort field. Currently only created_at is supported. |
order | string | No | Sort direction. One of asc, desc (default). |
cursor | string | No | Pagination cursor; omit for the first page. Max 512 characters. |
limit | integer | No | Page size. 1–100, default 20 when omitted. |
Any value outside the ranges/enums above is rejected with error_code: 90000
before the request reaches order-service — you will not get a partial or
best-effort match.
Request example
GET /pro/merchant/payout/v1/payouts?scene=withdraw&limit=20
Success response
{
"error_code": 0,
"msg": "success",
"data": {
"list": [
{
"payout_order_id": "po_01HXXX",
"scene": "withdraw",
"reference_id": "merchant-ref-001",
"status": "success",
"chain": "morph",
"created_at": 1782777600000
}
],
"cursor": "eyJ..."
},
"trace": "..."
}
To fetch the next page, pass the returned cursor on the next request. An empty
or missing cursor means there are no more results.
The fields shown above are the stable query-side fields. Each list[] entry may
carry additional payout detail fields (amount, recipient, token, etc.); treat
the payout record itself as the source of truth for those.
Get Payout
GET /payouts/detail
Returns the full detail of a single payout, including the on-chain
transaction and the per-recipient breakdown — fields not present on the
List Payouts list[] entry.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
payout_order_id | string | Yes | The payout id returned by List Payouts or when the payout was created. |
Omitting payout_order_id is rejected with error_code: 90000.
Request example
GET /pro/merchant/payout/v1/payouts/detail?payout_order_id=po_01HXXX
Success response
{
"error_code": 0,
"msg": "success",
"data": {
"payout_order_id": "po_01HXXX",
"scene": "payout",
"status": "success",
"phase": "completed",
"chain": "morph",
"source_address": "0x65c17d0410e1a7c038ce7f44964174e8611b3631",
"reference_id": "merchant-ref-001",
"recipient_count": 2,
"gas_token_symbol": "USDT",
"gas_token_address": "0xe7cd86e13ac4309349f30b3435a9d337750fc82d",
"gas_token_decimals": 6,
"quoted_gas_fee": "0.006214",
"max_gas_fee": "0.007457",
"final_gas_fee": "0.005750",
"transfer_summary": [
{ "symbol": "USDT", "address": "0xe7cd86e13ac4309349f30b3435a9d337750fc82d", "decimals": 6, "amount": "20.00", "recipient_count": 2 }
],
"transaction": {
"payout_txn_id": "pytx_01HXXX",
"chain": "morph",
"status": "success",
"phase": "completed",
"from_address": "0x65c17d0410e1a7c038ce7f44964174e8611b3631",
"tx_hash": "0x...",
"confirmed_at": 1782777610000
},
"items": [
{ "index": 0, "recipient_address": "0x742d35cc6634c0532925a3b844bc454e4438f44e", "token_symbol": "USDT", "token_address": "0xe7cd86e13ac4309349f30b3435a9d337750fc82d", "token_decimals": 6, "amount": "10.00" },
{ "index": 1, "recipient_address": "0xc10bc8317072e6c83b2cd95521202c5f76517ed2", "token_symbol": "USDT", "token_address": "0xe7cd86e13ac4309349f30b3435a9d337750fc82d", "token_decimals": 6, "amount": "10.00" }
],
"created_at": 1782777600000,
"updated_at": 1782777610000,
"completed_at": 1782777610000
},
"trace": "..."
}
The fields shown above reflect a completed payout example. A failed
payout instead carries failure_code / failure_message; an in-flight one may
omit transaction / completed_at until it settles. Treat the payout record
itself as the source of truth — do not assume every field is always present.
Get Balance
GET /balance
No query parameters. Returns the real-time on-chain balance (with fiat valuation) of your receiving wallet, per active chain and token. Results are cached for about 10 seconds.
Success response
{
"error_code": 0,
"msg": "success",
"data": {
"address": "0x742d35cc6634c0532925a3b844bc454e4438f44e",
"list": [
{
"chain_code": "morph",
"chain_name": "Morph",
"chain_id": 2818,
"token_code": "usdt",
"token_name": "USDT",
"token_contract": "0xe7cd86e13ac4309349f30b3435a9d337750fc82d",
"token_decimals": 6,
"balance": "1234.56",
"price": "1.00",
"change_24h": 0.02
}
]
},
"trace": "..."
}
Response fields
| Field | Type | Description |
|---|---|---|
address | string | The receiving wallet address the balance belongs to. |
list[].chain_code / chain_name / chain_id | string / string / int64 | Chain information. |
list[].token_code / token_name / token_contract / token_decimals | string / string / string / int32 | Token information. |
list[].balance | string | On-chain balance of this token in the wallet. |
list[].price | string | Real-time fiat unit price of the token. |
list[].change_24h | number | 24-hour price change. |
This endpoint only inspects your TEE-managed receiving wallets. Wallet selection follows these rules:
- Among your TEE wallets, if one is marked as default, its balance is returned.
- If none is marked as default, the earliest created TEE wallet is used (the one with the smallest internal ID, not necessarily the first shown in any list).
- Funds held on other (non-selected) receiving wallets are not included.
If you have no TEE-managed receiving wallets (for example, you only use
self-custody signing wallets), no wallet is matched and the response returns an
empty result (address: "", list: []) rather than an error.
Errors
| error_code | Meaning | Description |
|---|---|---|
0 | Success | — |
90000 | Invalid parameters | A query parameter is out of its allowed enum/range (e.g. scene, status, order, or limit outside 1–100). |
90001 | Unauthorized | Authentication failed or merchant identity is missing. |
80000 – 80099 | System error | The service is temporarily unavailable or hit an internal error; treat as a retryable system error. |
See the Error Codes reference for details.