Skip to main content

Overview

Payout APIs allow you to withdraw funds from your MartianPay account balance to external cryptocurrency wallets. This feature is designed for secure, verified withdrawals to addresses you control.

When to Use Payout vs Payroll

FeaturePayoutPayroll
Best ForPersonal withdrawals, large transfersBulk salary payments, employee disbursements
Address Verification✅ Required (micro-payment confirmation)⚠️ Optional (higher risk for new addresses)
Typical Use CaseWithdrawing your own fundsPaying multiple employees
Recommended AmountAny amount, especially large transfersUnder $10,000 USD per recipient
Batch ProcessingSingle recipient per payoutMultiple recipients in one batch
Security Level🔒 High (pre-verified addresses)⚠️ Medium (relies on accurate input)

Key Decision Point:

  • Use Payout when withdrawing to your own wallets or for any single transfer exceeding $10,000 USD
  • Use Payroll when paying multiple employees/contractors simultaneously

⚠️ Critical: Crypto Transactions are Irreversible Once a transaction is confirmed on the blockchain, it cannot be reversed or canceled. Always verify destination addresses carefully, especially for large amounts.

Understanding receive_account_id

The receive_account_id is a critical parameter in payout requests that references a pre-verified wallet address.

What is receive_account_id?

receive_account_id is the unique identifier (e.g., ma_pgm4wzxufUY3rDumpg96cP6j) of a wallet address you created and verified through the Wallet Management APIs.

How to Get receive_account_id:

  1. Create a wallet address using the Create Wallet API
  2. Complete the verification process (see below)
  3. Use the returned id field as receive_account_id in your payout requests

Address Verification Process

Before you can use a wallet address for payouts, it must be verified to ensure you control the destination wallet.

Verification Steps:

StepActionDetails
1️⃣Create WalletRegister your wallet address via API
2️⃣Receive Micro-PaymentSystem sends small amount (e.g., 0.003621 USDC)
3️⃣Confirm AmountSubmit last 4 digits (e.g., "3621") via API
4️⃣Verification CompleteAddress status becomes "success"
5️⃣Ready for PayoutsUse the address ID for unlimited withdrawals

💡 Why Verification Matters:

  • Prevents Costly Errors: Confirms you control the wallet before large transfers
  • One-Time Setup: Verified addresses can be reused indefinitely
  • Mandatory for Payouts: All payout destinations must be pre-verified
  • Enhanced Security: Protects against typos and address mistakes

Example:

// After creating and verifying a wallet address
{
"id": "ma_pgm4wzxufUY3rDumpg96cP6j", // ← Use this as receive_account_id
"status": "success",
"address": "8E5C25ZaxxVMs4Vn2rtSqQS2HQc3oF5RxTsC98nhb83C",
"network": "Solana Devnet"
}

For complete wallet management documentation, see How to Manage Wallet.

Payout Workflow

Step-by-Step Process

1. Check Available Balance

Before initiating a payout, verify you have sufficient funds.

Key Points:

  • Use the Balance Query API to check available balance
  • Ensure you have enough in the desired cryptocurrency
  • Consider network fees when planning your payout amount

Preview the payout to understand fees and final amounts before committing.

What You'll Get:

  • Estimated network fees
  • Total amount to be deducted from your balance
  • Expected amount recipient will receive
  • Currency swap details (if applicable)

When Swaps Occur:

  • System prioritizes using the same blockchain
  • If insufficient balance in requested crypto, automatic swap is triggered
  • You must include swap quote_ids when creating the actual payout

3. Create Payout

Submit your payout request with:

  • Source: Which cryptocurrency to withdraw from your balance
  • Destination: Pre-verified receive_account_id
  • Amount: How much to withdraw
  • Quote IDs: Swap quotes if preview showed swap items

4. Approval Process (if required)

Payouts may require approval based on amount:

Amount (USD)Merchant ApprovalAdmin ApprovalProcessing Time
≤ $200❌ Not Required❌ Not RequiredAuto-processed (10-min window)
$200 - $2,000✅ Required❌ Not RequiredAfter merchant approval
> $2,000✅ Required✅ RequiredAfter both approvals

During Approval:

  • Status: pending
  • Approval Status: in_progress
  • Funds are locked in your balance
  • Can be canceled before approval

5. Processing

Once approved (or if no approval needed):

  • AML (Anti-Money Laundering) checks on destination
  • Network fees calculated and deducted
  • Transaction submitted to blockchain

6. Completion

Success:

  • Status changes to paid
  • Funds arrive at destination wallet
  • Transaction hash available for tracking
  • Webhook payout.succeeded sent

Monitoring:

7. Handle Failures

If payout fails:

  1. Check failure_message in payout object
  2. Common issues: AML rejection, network problems, insufficient balance (after swaps)
  3. Resolve the issue
  4. Create a new payout request

Approval Thresholds

Payout approval requirements are based on the USD equivalent value:

Amount (USD)Merchant ApprovalAdmin ApprovalAuto-ProcessCancellation Window
≤ $200❌ Not Required❌ Not Required✅ Yes10 minutes
$200 - $2,000✅ Required❌ Not Required❌ NoUntil approved
> $2,000✅ Required✅ Required❌ NoUntil approved

Notes:

  • Approval thresholds: Calculated based on the USD equivalent at the time of payout creation
  • Small payouts (≤ $200): Auto-processed after a 10-minute quiet period, can be canceled during this window
  • Merchant approval: Required for amounts > $200 (first approval step)
  • Admin approval: Required for high-value payouts (> $2,000) after merchant approval
  • During approval: Payout status is pending with approval_status: "in_progress"
  • After approval: Status changes to approved and processing begins
  • Rejection: Payouts have status rejected with approval_status: "rejected"
  • Cancellation: Can cancel pending payouts before they are approved or during the 10-minute window for small payouts

API Reference

1. Balance Query

The Balance API allows you to check your available balance across different cryptocurrencies in your MartianPay account. This is an essential first step before initiating a payout to ensure you have sufficient funds for the transaction. The API returns details of all available balances including the currency type and amount.

For detailed API reference, see: Balance Query API

Request:

curl --location --request GET 'https://api.martianpay.com/v1/stats/balance' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic {BASE64_ENCODE(api_key + ":")}'

Response:

{
"error_code": "success",
"msg": "success",
"data": {
"currency": "USD",
"available_balance": "94.998719",
"pending_balance": "0",
"locked_balance": "9.800003",
"frozen_balance": "0",
"total_balance": "104.798722",
"balance_details": [
{
"payment_method_type": "crypto",
"currency": "USDC-Algorand-TEST",
"available_balance": "0.832",
"pending_balance": "0",
"locked_balance": "0",
"frozen_balance": "0",
"total_balance": "0.832"
},
{
"payment_method_type": "crypto",
"currency": "USDC-Ethereum-TEST",
"available_balance": "79.680715",
"pending_balance": "0",
"locked_balance": "9.200003",
"frozen_balance": "0",
"total_balance": "88.880718"
},
{
"payment_method_type": "crypto",
"currency": "USDC-Solana-TEST",
"available_balance": "12.330026",
"pending_balance": "0",
"locked_balance": "0.6",
"frozen_balance": "0",
"total_balance": "12.930026"
},
{
"payment_method_type": "crypto",
"currency": "USDT-BSC-TEST",
"available_balance": "2.155978",
"pending_balance": "0",
"locked_balance": "0",
"frozen_balance": "0",
"total_balance": "2.155978"
}
]
}
}

Understanding the Response

How to Check if the Request Was Successful:

FieldValueMeaning
error_code"success"✅ Request succeeded
error_codeOther value❌ Specific error occurred (e.g., "unauthorized", "invalid_request")

Balance Categories Explained:

When querying your account balance, you'll encounter different balance categories:

  • available_balance: Funds that are immediately available for use in transactions (payouts, withdrawals)
  • pending_balance: Temporary balance for unreconciled deposits from payment intents or deposits; once reconciliation is complete, these funds move to available_balance
  • locked_balance: Funds that are locked as soon as a payout request is initiated; these amounts remain locked until the payout process completes or fails (successful payouts deduct from this balance, failed payouts return funds to available_balance)
  • frozen_balance: Funds that are restricted due to compliance or security reasons
  • total_balance: The sum of all balance types in your account

Understanding these balance types helps you manage your funds efficiently and plan for upcoming transactions.

2. Preview Payout

Preview a payout transaction to estimate the total cost and net amount before finalizing the payout.

  • The system prioritizes using the same blockchain for transfers when possible
  • If the balance in the requested cryptocurrency is insufficient, automatic swap will occur

For detailed API reference, see: Preview Payout API

Request:

curl --location --request POST 'https://api.martianpay.com/v1/payouts/preview' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic {BASE64_ENCODE(api_key + ":")}' \
--data-raw '{
"source_coin": "USDC",
"source_amount": "15",
"receive_coin": "USDC",
"receive_account_type": "wallet",
"receive_account_id": "ma_pgm4wzxufUY3rDumpg96cP6j",
"receive_asset_id": "USDC-Solana-TEST"
}'

Response:

{
"error_code": "success",
"msg": "success",
"data": {
"id": "payout_fBz8zpFiGleL5qnhfsZRWRQK",
"object": "payout",
"livemode": false,
"arrival_date": 0,
"automatic": false,
"transactions": [],
"created": -62135596800,
"updated": -62135596800,
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"source_amount": "15",
"source_coin": "USDC",
"exchange_rate": "1.0",
"receive_coin": "USDC",
"receive_asset_id": "USDC-Solana-TEST",
"receive_account_type": "wallet",
"receive_bank_account": null,
"receive_wallet_address": {
"id": "ma_pgm4wzxufUY3rDumpg96cP6j",
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"network": "Solana Devnet",
"address": "8E5C25ZaxxVMs4Vn2rtSqQS2HQc3oF5RxTsC98nhb83C",
"verification_id": "av_iHjrQwOAStpPx0IsMvuXUMMb",
"status": "success",
"alias": "",
"created_at": 1745719033,
"updated_at": 1745719072,
"verification": {
"id": "av_iHjrQwOAStpPx0IsMvuXUMMb",
"status": "success",
"merchant_address_id": "ma_pgm4wzxufUY3rDumpg96cP6j",
"asset_id": "USDC-Solana-TEST",
"verified_at": 1745719072,
"tried_times": 1,
"aml_status": "approved"
}
},
"receive_amount": "14.485483",
"receive_amount_min": "14.474706",
"payment_max_amount": "92.842741",
"payment_network_fee": "0.1",
"payment_service_fee": "0",
"payment_total_fee": "0.1",
"payment_net_amount": "14.385483",
"status": "pending",
"approval_status": "in_progress",
"internal_note": "",
"statement_descriptor": "",
"external_id": "",
"failure_message": "",
"aml_status": "",
"aml_info": null,
"metadata": null,
"withdraw": {
"id": "wd_YKHvhyvkMHH5AZTZHFcUdanG",
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"payout_id": "payout_fBz8zpFiGleL5qnhfsZRWRQK",
"asset_id": "USDC-Solana-TEST",
"decimals": 6,
"amount": "14.385483",
"tx_fee": "0",
"network_fee": "0.1",
"estimated_receive_amount": "14.485483",
"estimated_receive_amount_min": "14.474706",
"status": "pending",
"address": "8E5C25ZaxxVMs4Vn2rtSqQS2HQc3oF5RxTsC98nhb83C",
"created_at": -62135596800,
"updated_at": -62135596800,
"version": 0
},
"swap_items": [
{
"id": "sw_6v1YrP1ROOyKJ5tDWiuaHkYj",
"quote_id": "f231b9f2-8a50-4662-bb6e-ea39bfb90fe3:0",
"created_at": -62135596800,
"updated_at": -62135596800,
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"payout_id": "payout_fBz8zpFiGleL5qnhfsZRWRQK",
"from_asset_id": "USDC-Ethereum-TEST",
"expected_from_amount": "2.669974",
"estimated_from_amount": "2.669974",
"estimated_from_amount_usd": "2.6697",
"actual_from_amount": "0",
"to_asset_id": "USDC-Solana-TEST",
"expected_to_amount": "0",
"estimated_to_amount": "2.155457",
"estimated_to_amount_min": "2.14468",
"estimated_to_amount_usd": "2.155",
"actual_to_amount": "0",
"status": "pending"
}
]
}
}

3. Create Payout

Create a new payout request to transfer funds from your MartianPay account to a specified wallet address. If you have swap items, make sure to include all quote IDs in your request. Otherwise, the system will return an "insufficient balance" error.

For detailed API reference, see: Create Payout API

Request:

curl --location --request POST 'https://api.martianpay.com/v1/payouts' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic {BASE64_ENCODE(api_key + ":")}' \
--data-raw '{
"source_coin": "USDC",
"source_amount": "15",
"receive_coin": "USDC",
"receive_account_type": "wallet",
"receive_account_id": "ma_pgm4wzxufUY3rDumpg96cP6j",
"receive_asset_id": "USDC-Solana-TEST",
"quote_ids": ["f231b9f2-8a50-4662-bb6e-ea39bfb90fe3:0"]
}'

Response:

{
"error_code": "success",
"msg": "success",
"data": {
"id": "payout_7Jqywdh4ssdFHiUu5jWg4mZk",
"object": "payout",
"livemode": false,
"arrival_date": 0,
"automatic": false,
"transactions": [],
"created": 1750052789,
"updated": 1750052789,
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"source_amount": "15",
"source_coin": "USDC",
"exchange_rate": "1.0",
"receive_coin": "USDC",
"receive_asset_id": "USDC-Solana-TEST",
"receive_account_type": "wallet",
"receive_bank_account": null,
"receive_wallet_address": {
"id": "ma_pgm4wzxufUY3rDumpg96cP6j",
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"network": "Solana Devnet",
"address": "8E5C25ZaxxVMs4Vn2rtSqQS2HQc3oF5RxTsC98nhb83C",
"verification_id": "av_iHjrQwOAStpPx0IsMvuXUMMb",
"status": "success",
"alias": "",
"created_at": 1745719033,
"updated_at": 1745719072,
"verification": {
"id": "av_iHjrQwOAStpPx0IsMvuXUMMb",
"status": "success",
"merchant_address_id": "ma_pgm4wzxufUY3rDumpg96cP6j",
"asset_id": "USDC-Solana-TEST",
"verified_at": 1745719072,
"tried_times": 1,
"aml_status": "approved"
}
},
"receive_amount": "14.485483",
"receive_amount_min": "14.474706",
"payment_max_amount": "92.842741",
"payment_network_fee": "0.1",
"payment_service_fee": "0",
"payment_total_fee": "0.1",
"payment_net_amount": "14.385483",
"status": "pending",
"approval_status": "in_progress",
"internal_note": "",
"statement_descriptor": "",
"external_id": "",
"failure_message": "",
"aml_status": "",
"aml_info": null,
"metadata": null,
"withdraw": {
"id": "wd_BmzDM83WuW1icowVvwJasCvl",
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"payout_id": "payout_7Jqywdh4ssdFHiUu5jWg4mZk",
"asset_id": "USDC-Solana-TEST",
"decimals": 6,
"amount": "14.385483",
"tx_fee": "0",
"network_fee": "0.1",
"estimated_receive_amount": "14.485483",
"estimated_receive_amount_min": "14.474706",
"status": "pending",
"address": "8E5C25ZaxxVMs4Vn2rtSqQS2HQc3oF5RxTsC98nhb83C",
"created_at": 1750052789,
"updated_at": 1750052789,
"version": 0
},
"swap_items": [
{
"id": "sw_rFqZeIoIgLEb1j78o2MN7HcZ",
"quote_id": "f231b9f2-8a50-4662-bb6e-ea39bfb90fe3:0",
"created_at": 1750052789,
"updated_at": 1750052789,
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"payout_id": "payout_7Jqywdh4ssdFHiUu5jWg4mZk",
"from_asset_id": "USDC-Ethereum-TEST",
"expected_from_amount": "2.669974",
"estimated_from_amount": "2.669974",
"estimated_from_amount_usd": "2.6697",
"actual_from_amount": "0",
"to_asset_id": "USDC-Solana-TEST",
"expected_to_amount": "0",
"estimated_to_amount": "2.155457",
"estimated_to_amount_min": "2.14468",
"estimated_to_amount_usd": "2.155",
"actual_to_amount": "0",
"status": "pending"
}
]
}
}

Understanding the Response

How to Check if the Request Was Successful:

FieldValueMeaning
error_code"success"✅ Payout request accepted
error_codeOther value❌ Error occurred (e.g., "insufficient_balance", "invalid_wallet")

Key Status Fields:

FieldValueMeaning
status"pending"⏳ Payout created, awaiting approval or processing
status"approved"✅ Approved, ready for blockchain execution
status"in_transit"🔄 Transaction submitted to blockchain
status"paid"Success - Funds delivered to destination
status"failed"Failed - Check failure_message for details
status"rejected"❌ Approval denied - Check approval_status
approval_status"in_progress"⏳ Awaiting merchant/admin approval
approval_status"approved"✅ All required approvals granted
approval_status"rejected"❌ Approval denied

Monitoring Payout Progress:

After creating a payout, monitor its progress through:

  1. Polling: Use Get Payout API to check current status and approval_status
  2. Webhooks: Subscribe to payout webhook events (recommended):
    • payout.created - Payout request submitted
    • payout.updated - Status changed (approval, processing, etc.)
    • payout.succeeded - Funds successfully delivered
    • payout.failed - Payout failed, check failure_message

Next Steps Based on Status:

  • pending + approval_status: "in_progress": Wait for approval or approve via dashboard
  • approved: System will process automatically
  • in_transit: Transaction on blockchain, wait for confirmation
  • paid: ✅ Complete! Check transactions array for blockchain tx_hash
  • failed: Investigate failure_message, resolve issue, create new payout

3. Get Payout Approval Instance

For payout amounts exceeding $200 USD, merchant approval is required. This API is used to query the approval status.

For detailed API reference, see: Get Approval Instance API

Request:

curl --location --request GET 'https://api.martianpay.com/v1/approval/detail?resource_id=payout_7Jqywdh4ssdFHiUu5jWg4mZk' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic {BASE64_ENCODE(api_key + ":")}'

Response:

{
"error_code": "success",
"msg": "success",
"data": {
"id": "approval_instance_xyAmNfPe6aT2msXBoDWEpZh3",
"object": "approval_instance",
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"status": "pending",
"resource_id": "payout_7Jqywdh4ssdFHiUu5jWg4mZk",
"resource_type": "payout",
"created_at": 1750052789,
"updated_at": 1750052789,
"records": [
{
"id": "approval_record_9zNkMLN2EOXKGVA15QmVucHQ",
"action": "start",
"comment": "",
"approver_id": "server-HwTzmQGe2oP9pizy21NsuBEe",
"approver_name": "Jane Smith",
"approver_role": "",
"created_at": 1750052789,
"namespace": "merchant"
}
],
"current_step": {
"id": "approval_step_shneD0P37V3uLEfBJHEy3XtU",
"flow_id": "",
"step_order": 1,
"namespace": "merchant",
"roles": [
"FinanceManager",
"SuperAdmin"
],
"next_on_approve": 2,
"next_on_reject": 0,
"created_at": 1748999979,
"updated_at": 1748999979
}
}
}

4. Approve Payout

Approve a specific payout request.

For detailed API reference, see: Approve Payout API

Request:

curl --location --request POST 'https://api.martianpay.com/v1/approval/approval_instance_xyAmNfPe6aT2msXBoDWEpZh3/approve' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic {BASE64_ENCODE(api_key + ":")}' \
--data-raw '{
"comment": "agree"
}'

Response:

{
"error_code": "success",
"msg": "success"
}

5. Reject Payout

Reject a specific payout request.

For detailed API reference, see: Reject Payout API

Request:

curl --location --request POST 'https://api.martianpay.com/v1/approval/approval_instance_xyAmNfPe6aT2msXBoDWEpZh3/reject' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic {BASE64_ENCODE(api_key + ":")}' \
--data-raw '{
"comment": "reject"
}'

Response:

{
"error_code": "success",
"msg": "success"
}

6. Cancel Payout

Cancel a specific payout request before it has been processed. For small payouts (≤ $200), there is a 10-minute quiet period after creation during which the payout can be canceled before automatic processing begins.

Cancellation Windows:

  • ≤ $200: Can cancel within 10 minutes after creation (during quiet period)
  • $200 - $2,000: Can cancel anytime before merchant approval
  • > $2,000: Can cancel anytime before all approvals are complete

For detailed API reference, see: Cancel Payout API

Request:

curl --location --request POST 'https://api.martianpay.com/v1/payouts/payout_98r7PmaZ3lGdnJQAlQlUG3hZ/cancel' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic {BASE64_ENCODE(api_key + ":")}'

Response:

{
"error_code": "success",
"msg": "success",
"data": {
"id": "payout_98r7PmaZ3lGdnJQAlQlUG3hZ",
"object": "payout",
"livemode": false,
"arrival_date": 0,
"automatic": false,
"transactions": [],
"created": 1750084121,
"updated": 1750084144,
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"source_amount": "11",
"source_coin": "USDC",
"exchange_rate": "1.0",
"receive_coin": "USDC",
"receive_asset_id": "USDC-Solana-TEST",
"receive_account_type": "wallet",
"receive_bank_account": null,
"receive_wallet_address": {
"id": "ma_pgm4wzxufUY3rDumpg96cP6j",
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"network": "Solana Devnet",
"address": "8E5C25ZaxxVMs4Vn2rtSqQS2HQc3oF5RxTsC98nhb83C",
"verification_id": "av_iHjrQwOAStpPx0IsMvuXUMMb",
"status": "success",
"alias": "",
"created_at": 1745719033,
"updated_at": 1745719072,
"verification": {
"id": "av_iHjrQwOAStpPx0IsMvuXUMMb",
"status": "success",
"merchant_address_id": "ma_pgm4wzxufUY3rDumpg96cP6j",
"asset_id": "USDC-Solana-TEST",
"verified_at": 1745719072,
"tried_times": 1,
"aml_status": "approved"
}
},
"receive_amount": "10.9",
"receive_amount_min": "10.9",
"payment_max_amount": "0",
"payment_network_fee": "0.1",
"payment_service_fee": "0",
"payment_total_fee": "0.1",
"payment_net_amount": "10.9",
"status": "canceled",
"approval_status": "in_progress",
"internal_note": "",
"statement_descriptor": "",
"external_id": "",
"failure_message": "",
"aml_status": "",
"aml_info": null,
"metadata": null
}
}

7. Get Payout Approval Instance after approval

Get the approval instance for a specific payout request.

Request:

curl --location --request GET 'https://api.martianpay.com/v1/approval/detail?resource_id=payout_7Jqywdh4ssdFHiUu5jWg4mZk' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic {BASE64_ENCODE(api_key + ":")}'

Response:

{
"error_code": "success",
"msg": "success",
"data": {
"id": "approval_instance_xyAmNfPe6aT2msXBoDWEpZh3",
"object": "approval_instance",
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"status": "pending",
"resource_id": "payout_7Jqywdh4ssdFHiUu5jWg4mZk",
"resource_type": "payout",
"created_at": 1750052789,
"updated_at": 1750053312,
"records": [
{
"id": "approval_record_9zNkMLN2EOXKGVA15QmVucHQ",
"action": "start",
"comment": "",
"approver_id": "server-HwTzmQGe2oP9pizy21NsuBEe",
"approver_name": "Jane Smith",
"approver_role": "",
"created_at": 1750052789,
"namespace": "merchant"
},
{
"id": "approval_record_zhNowCMxsacPpFn7fAwEGkrf",
"action": "approve",
"comment": "agree",
"approver_id": "server-HwTzmQGe2oP9pizy21NsuBEe",
"approver_name": "Jane Smith",
"approver_role": "SuperAdmin",
"created_at": 1750053312,
"namespace": "merchant"
}
],
"current_step": null
}
}

8. Webhook Events for Payouts

MartianPay sends webhook notifications for payout events, allowing you to track the status of your withdrawal requests in real-time.

8.1 Payout Events

Event TypeDescriptionTriggered When
payout.createdPayout request createdA new payout is initially created in the system
payout.updatedPayout status updatedAny details are modified (status, approval, processing updates)
payout.succeededPayout completed successfullyFunds successfully delivered to recipient wallet
payout.failedPayout failedProcessing failed due to insufficient funds, network issues, or invalid address

8.2 Webhook Payload Example

Here's an example of a payout webhook event payload:

{
"id": "evt_056qw9fr9PndljykFUqSIf6t",
"object": "event",
"api_version": "2025-01-22",
"created": 1750052789,
"data": {
"object": {
"id": "payout_7Jqywdh4ssdFHiUu5jWg4mZk",
"object": "payout",
"livemode": false,
"created": 1750052789,
"updated": 1750053125,
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"source_amount": "15",
"source_coin": "USDC",
"receive_coin": "USDC",
"receive_asset_id": "USDC-Solana-TEST",
"receive_account_type": "wallet",
"status": "paid",
"approval_status": "approved",
"external_id": "WITHDRAWAL-2024-001",
"description": "Monthly withdrawal to treasury wallet"
},
"previous_attributes": {
"status": "in_transit",
"updated": 1750053000
}
},
"livemode": false,
"pending_webhooks": 0,
"type": "payout.succeeded"
}

8.3 Webhook Event Flow

Typical Payout Event Sequence:

  1. payout.created - Payout request submitted (status: pending)
  2. payout.updated - Status changes (may occur multiple times: approved, in_transit, etc.)
  3. payout.succeeded - Funds delivered successfully (status: paid)
    • OR payout.failed - Processing failed (status: failed)

Status Transitions:

pending → updated* → paid (SUCCESS)
↘ failed (FAILURE)

* payout.updated fires when status changes (approved, in_transit, etc.)
For rejected payouts: pending → updated (rejected)

8.4 Best Practices

  1. Monitor payout.succeeded events - Confirm successful withdrawals and update your internal accounting records

  2. Alert on payout.failed events - Immediately notify administrators when withdrawals fail so they can take corrective action:

    • Check wallet address validity
    • Verify sufficient balance
    • Retry failed payouts if appropriate
  3. Track approval workflow - Monitor payout.updated events to:

    • Know when payouts are approved or rejected
    • Alert requesters about approval status
    • Measure approval processing times
  4. Handle idempotency - Store the event ID (evt_*) to prevent duplicate processing of the same webhook

  5. Reconcile with external_id - Use the external_id field to match webhook events with your internal withdrawal records

  6. Monitor transaction details - When payout.succeeded is received:

    • Extract the transactions array for blockchain transaction hashes
    • Provide transaction tracking links to requesters
    • Store transaction records for audit purposes

For more details on webhook setup, signature verification, and complete event schemas, see the Webhook Events documentation.

9. Get Payout

Get the details of a specific payout request.

For detailed API reference, see: Get Payout API

Request:

curl --location --request GET 'https://api.martianpay.com/v1/payouts/payout_7Jqywdh4ssdFHiUu5jWg4mZk' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic {BASE64_ENCODE(api_key + ":")}'

Response:

{
"error_code": "success",
"msg": "success",
"data": {
"id": "payout_7Jqywdh4ssdFHiUu5jWg4mZk",
"object": "payout",
"livemode": false,
"arrival_date": 0,
"automatic": false,
"transactions": [],
"created": 1750052789,
"updated": 1750052789,
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"source_amount": "15",
"source_coin": "USDC",
"exchange_rate": "1.0",
"receive_coin": "USDC",
"receive_asset_id": "USDC-Solana-TEST",
"receive_account_type": "wallet",
"receive_bank_account": null,
"receive_wallet_address": {
"id": "ma_pgm4wzxufUY3rDumpg96cP6j",
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"network": "Solana Devnet",
"address": "8E5C25ZaxxVMs4Vn2rtSqQS2HQc3oF5RxTsC98nhb83C",
"verification_id": "av_iHjrQwOAStpPx0IsMvuXUMMb",
"status": "success",
"alias": "",
"created_at": 1745719033,
"updated_at": 1745719072,
"verification": {
"id": "av_iHjrQwOAStpPx0IsMvuXUMMb",
"status": "success",
"merchant_address_id": "ma_pgm4wzxufUY3rDumpg96cP6j",
"asset_id": "USDC-Solana-TEST",
"verified_at": 1745719072,
"tried_times": 1,
"aml_status": "approved"
}
},
"receive_amount": "14.485483",
"receive_amount_min": "14.474706",
"payment_max_amount": "0",
"payment_network_fee": "0.1",
"payment_service_fee": "0",
"payment_total_fee": "0.1",
"payment_net_amount": "14.385483",
"status": "pending",
"approval_status": "in_progress",
"internal_note": "",
"statement_descriptor": "",
"external_id": "",
"failure_message": "",
"aml_status": "",
"aml_info": null,
"metadata": null,
"withdraw": {
"id": "wd_BmzDM83WuW1icowVvwJasCvl",
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"payout_id": "payout_7Jqywdh4ssdFHiUu5jWg4mZk",
"asset_id": "USDC-Solana-TEST",
"decimals": 6,
"amount": "14.385483",
"tx_fee": "0",
"network_fee": "0.1",
"estimated_receive_amount": "14.485483",
"estimated_receive_amount_min": "14.474706",
"status": "pending",
"address": "8E5C25ZaxxVMs4Vn2rtSqQS2HQc3oF5RxTsC98nhb83C",
"created_at": 1750052789,
"updated_at": 1750052789,
"version": 0
},
"swap_items": [
{
"id": "sw_rFqZeIoIgLEb1j78o2MN7HcZ",
"quote_id": "f231b9f2-8a50-4662-bb6e-ea39bfb90fe3:0",
"created_at": 1750052789,
"updated_at": 1750052789,
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"payout_id": "payout_7Jqywdh4ssdFHiUu5jWg4mZk",
"from_asset_id": "USDC-Ethereum-TEST",
"expected_from_amount": "2.669974",
"estimated_from_amount": "2.669974",
"estimated_from_amount_usd": "3",
"actual_from_amount": "0",
"to_asset_id": "USDC-Solana-TEST",
"expected_to_amount": "0",
"estimated_to_amount": "2.155457",
"estimated_to_amount_min": "2.14468",
"estimated_to_amount_usd": "2",
"actual_to_amount": "0",
"status": "pending"
}
]
}
}

10. List Payouts

Retrieve a list of all payouts in your account. This allows you to view and manage your existing payouts.

For detailed API reference, see: List Payouts API

Request:

curl --location --request GET 'https://api.martianpay.com/v1/payouts?page=0&page_size=5' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic {BASE64_ENCODE(api_key + ":")}'

Response:

{
"error_code": "success",
"msg": "success",
"data": {
"payouts": [
{
"id": "payout_7Jqywdh4ssdFHiUu5jWg4mZk",
"object": "payout",
"livemode": false,
"arrival_date": 0,
"automatic": false,
"transactions": [],
"created": 1750052789,
"updated": 1750079369,
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"source_amount": "15",
"source_coin": "USDC",
"exchange_rate": "1.0",
"receive_coin": "USDC",
"receive_asset_id": "USDC-Solana-TEST",
"receive_account_type": "wallet",
"receive_bank_account": null,
"receive_wallet_address": {
"id": "ma_pgm4wzxufUY3rDumpg96cP6j",
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"network": "Solana Devnet",
"address": "8E5C25ZaxxVMs4Vn2rtSqQS2HQc3oF5RxTsC98nhb83C",
"verification_id": "av_iHjrQwOAStpPx0IsMvuXUMMb",
"status": "success",
"alias": "",
"created_at": 1745719033,
"updated_at": 1745719072,
"verification": {
"id": "av_iHjrQwOAStpPx0IsMvuXUMMb",
"status": "success",
"merchant_address_id": "ma_pgm4wzxufUY3rDumpg96cP6j",
"asset_id": "USDC-Solana-TEST",
"verified_at": 1745719072,
"tried_times": 1,
"aml_status": "approved"
}
},
"receive_amount": "14.485483",
"receive_amount_min": "14.474706",
"payment_max_amount": "0",
"payment_network_fee": "0.1",
"payment_service_fee": "0",
"payment_total_fee": "0.1",
"payment_net_amount": "14.385483",
"status": "rejected",
"approval_status": "rejected",
"internal_note": "",
"statement_descriptor": "",
"external_id": "",
"failure_message": "",
"aml_status": "",
"aml_info": null,
"metadata": null
},
{
"id": "payout_AsxtAGpSUs3KTMdikncFeKw6",
"object": "payout",
"livemode": false,
"arrival_date": 0,
"automatic": false,
"transactions": [],
"created": 1749741191,
"updated": 1749741239,
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"source_amount": "15",
"source_coin": "USDC",
"exchange_rate": "1.0",
"receive_coin": "USDC",
"receive_asset_id": "USDC-Solana-TEST",
"receive_account_type": "wallet",
"receive_bank_account": null,
"receive_wallet_address": {
"id": "ma_pgm4wzxufUY3rDumpg96cP6j",
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"network": "Solana Devnet",
"address": "8E5C25ZaxxVMs4Vn2rtSqQS2HQc3oF5RxTsC98nhb83C",
"verification_id": "av_iHjrQwOAStpPx0IsMvuXUMMb",
"status": "success",
"alias": "",
"created_at": 1745719033,
"updated_at": 1745719072,
"verification": {
"id": "av_iHjrQwOAStpPx0IsMvuXUMMb",
"status": "success",
"merchant_address_id": "ma_pgm4wzxufUY3rDumpg96cP6j",
"asset_id": "USDC-Solana-TEST",
"verified_at": 1745719072,
"tried_times": 1,
"aml_status": "approved"
}
},
"receive_amount": "39.387912",
"receive_amount_min": "39.252623",
"payment_max_amount": "0",
"payment_network_fee": "0.1",
"payment_service_fee": "0",
"payment_total_fee": "0.1",
"payment_net_amount": "39.287912",
"status": "rejected",
"approval_status": "rejected",
"internal_note": "",
"statement_descriptor": "",
"external_id": "",
"failure_message": "",
"aml_status": "",
"aml_info": null,
"metadata": null
},
{
"id": "payout_EUEHhyTjbc8SDaNQm2z3DRzl",
"object": "payout",
"livemode": false,
"arrival_date": 0,
"automatic": false,
"transactions": [],
"created": 1749741030,
"updated": 1749741089,
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"source_amount": "30",
"source_coin": "USDC",
"exchange_rate": "1.0",
"receive_coin": "USDC",
"receive_asset_id": "USDC-Ethereum-TEST",
"receive_account_type": "wallet",
"receive_bank_account": null,
"receive_wallet_address": {
"id": "ma_HDbjWWxLdS764gK37jbMpvsF",
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"network": "Ethereum Sepolia",
"address": "0x36279Ac046498bF0cb742622cCe22F3cE3c2AfD9",
"verification_id": "av_4OCclVdmIOI5474We4GnS2Qp",
"status": "success",
"alias": "",
"created_at": 1749729086,
"updated_at": 1749729282,
"verification": {
"id": "av_4OCclVdmIOI5474We4GnS2Qp",
"status": "success",
"merchant_address_id": "ma_HDbjWWxLdS764gK37jbMpvsF",
"asset_id": "USDC-Ethereum-TEST",
"verified_at": 1749729282,
"tried_times": 1,
"aml_status": "approved"
}
},
"receive_amount": "29.99",
"receive_amount_min": "29.99",
"payment_max_amount": "0",
"payment_network_fee": "0.01",
"payment_service_fee": "0",
"payment_total_fee": "0.01",
"payment_net_amount": "29.99",
"status": "rejected",
"approval_status": "rejected",
"internal_note": "",
"statement_descriptor": "",
"external_id": "",
"failure_message": "",
"aml_status": "",
"aml_info": null,
"metadata": null
},
{
"id": "payout_TzQxLrKhKqR6akpzVWDVrjJy",
"object": "payout",
"livemode": false,
"arrival_date": 0,
"automatic": false,
"transactions": [],
"created": 1749739845,
"updated": 1749739942,
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"source_amount": "15",
"source_coin": "USDC",
"exchange_rate": "1.0",
"receive_coin": "USDC",
"receive_asset_id": "USDC-Solana-TEST",
"receive_account_type": "wallet",
"receive_bank_account": null,
"receive_wallet_address": {
"id": "ma_pgm4wzxufUY3rDumpg96cP6j",
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"network": "Solana Devnet",
"address": "8E5C25ZaxxVMs4Vn2rtSqQS2HQc3oF5RxTsC98nhb83C",
"verification_id": "av_iHjrQwOAStpPx0IsMvuXUMMb",
"status": "success",
"alias": "",
"created_at": 1745719033,
"updated_at": 1745719072,
"verification": {
"id": "av_iHjrQwOAStpPx0IsMvuXUMMb",
"status": "success",
"merchant_address_id": "ma_pgm4wzxufUY3rDumpg96cP6j",
"asset_id": "USDC-Solana-TEST",
"verified_at": 1745719072,
"tried_times": 1,
"aml_status": "approved"
}
},
"receive_amount": "14.455869",
"receive_amount_min": "14.44524",
"payment_max_amount": "0",
"payment_network_fee": "0.1",
"payment_service_fee": "0",
"payment_total_fee": "0.1",
"payment_net_amount": "14.355869",
"status": "failed",
"approval_status": null,
"internal_note": "",
"statement_descriptor": "",
"external_id": "",
"failure_message": "",
"aml_status": "",
"aml_info": null,
"metadata": null
},
{
"id": "payout_S22s5IKJA8OrOKSe3k3gxV4o",
"object": "payout",
"livemode": false,
"arrival_date": 0,
"automatic": false,
"transactions": [],
"created": 1749736491,
"updated": 1749739326,
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"source_amount": "15",
"source_coin": "USDC",
"exchange_rate": "1.0",
"receive_coin": "USDC",
"receive_asset_id": "USDC-Solana-TEST",
"receive_account_type": "wallet",
"receive_bank_account": null,
"receive_wallet_address": {
"id": "ma_pgm4wzxufUY3rDumpg96cP6j",
"merchant_id": "accu_M7PTgveSgMtTtPHbjFgEtAlD",
"network": "Solana Devnet",
"address": "8E5C25ZaxxVMs4Vn2rtSqQS2HQc3oF5RxTsC98nhb83C",
"verification_id": "av_iHjrQwOAStpPx0IsMvuXUMMb",
"status": "success",
"alias": "",
"created_at": 1745719033,
"updated_at": 1745719072,
"verification": {
"id": "av_iHjrQwOAStpPx0IsMvuXUMMb",
"status": "success",
"merchant_address_id": "ma_pgm4wzxufUY3rDumpg96cP6j",
"asset_id": "USDC-Solana-TEST",
"verified_at": 1745719072,
"tried_times": 1,
"aml_status": "approved"
}
},
"receive_amount": "14.460672",
"receive_amount_min": "14.450019",
"payment_max_amount": "0",
"payment_network_fee": "0.1",
"payment_service_fee": "0",
"payment_total_fee": "0.1",
"payment_net_amount": "14.360672",
"status": "failed",
"approval_status": null,
"internal_note": "",
"statement_descriptor": "",
"external_id": "",
"failure_message": "",
"aml_status": "",
"aml_info": null,
"metadata": null
}
],
"total": 78,
"page": 0,
"page_size": 5
}
}