Traxvo

Payouts

Send payouts to your users with hardware wallet signing

Payouts

Send USDT/USDC to your users using your connected hardware wallet. Non-custodial - you control the private key.

How It Works

1. Connect hardware wallet (Ledger/Trezor)
2. Create payout request via API
3. Sign transaction on hardware device
4. Submit signed transaction to broadcast

Connect Payout Wallet

Connect your hardware wallet address for each chain.

POST /v1/payout/wallet

Request

{
  "chain": "TRON",
  "address": "TYourHardwareWalletAddress...",
  "label": "My Ledger"
}

Response

{
  "status": "success",
  "wallet": {
    "id": "wallet_123",
    "chain": "TRON",
    "address": "TYourHardwareWalletAddress...",
    "label": "My Ledger",
    "is_active": true,
    "created_at": "2024-01-15T10:00:00.000Z"
  }
}

Create Payout

Create a payout request and receive an unsigned transaction.

POST /v1/payout/create

Request

{
  "chain": "TRON",
  "token": "USDT",
  "to_address": "TUserWalletAddress...",
  "amount": 100,
  "metadata": {
    "user_id": "user_123",
    "withdrawal_id": "wd_456"
  },
  "callback_url": "https://your-site.com/payout-webhook"
}

Response

{
  "status": "success",
  "payout": {
    "id": "payout_abc123",
    "chain": "TRON",
    "token": "USDT",
    "from_address": "TYourHardwareWallet...",
    "to_address": "TUserWalletAddress...",
    "amount": 100,
    "unsigned_tx": "{...}",
    "expires_at": "2024-01-15T10:10:00.000Z",
    "created_at": "2024-01-15T10:00:00.000Z"
  }
}

Sign Transaction

Sign the unsigned_tx using your hardware wallet:

Ledger (JavaScript)

import TransportWebUSB from "@ledgerhq/hw-transport-webusb";
import Trx from "@ledgerhq/hw-app-trx";
 
async function signWithLedger(unsignedTx) {
  const transport = await TransportWebUSB.create();
  const trx = new Trx(transport);
 
  const tx = JSON.parse(unsignedTx);
  const signedTx = await trx.signTransaction(
    "44'/195'/0'/0/0", // derivation path
    tx.raw_data_hex
  );
 
  return signedTx;
}

Trezor (JavaScript)

import TrezorConnect from "@trezor/connect-web";
 
async function signWithTrezor(unsignedTx) {
  const tx = JSON.parse(unsignedTx);
 
  const result = await TrezorConnect.tronSignTransaction({
    path: "m/44'/195'/0'/0/0",
    transaction: tx
  });
 
  return result.payload.serializedTx;
}

Broadcast Transaction

Submit the signed transaction for broadcasting.

POST /v1/payout/:id/broadcast

Request

{
  "signed_tx": "{...signed transaction...}"
}

Response

{
  "status": "success",
  "payout": {
    "id": "payout_abc123",
    "tx_hash": "abc123def456...",
    "status": "confirming"
  }
}

Check Payout Status

GET /v1/payout/:id

Response

{
  "status": "success",
  "payout": {
    "id": "payout_abc123",
    "chain": "TRON",
    "token": "USDT",
    "from_address": "TYourHardwareWallet...",
    "to_address": "TUserWalletAddress...",
    "amount": 100,
    "fee": 0,
    "net_amount": 100,
    "status": "completed",
    "tx_hash": "abc123def456...",
    "confirmations": 19,
    "created_at": "2024-01-15T10:00:00.000Z"
  }
}

List Payouts

GET /v1/payout

Query Parameters

ParameterTypeDefaultDescription
limitnumber50Results per page (max 100)
offsetnumber0Pagination offset
statusstring-Filter by status

Payout Status Values

StatusDescription
pendingWaiting for signature
signedSigned, ready to broadcast
broadcastingBeing broadcast
confirmingWaiting for confirmations
completedConfirmed on chain
expiredUnsigned tx expired (10 min)
failedFailed to broadcast/confirm
cancelledCancelled by merchant

Cancel Payout

Cancel a pending (unsigned) payout.

POST /v1/payout/:id/cancel

Fee Structure

FeeNone
GasPaid by you

Payouts have no Traxvo fees. You only pay the network gas fee for broadcasting the transaction.

Webhooks

Payout webhooks are sent to callback_url:

{
  "event": "payout.completed",
  "payout_id": "payout_abc123",
  "tx_hash": "abc123def456...",
  "amount": 100,
  "net_amount": 100,
  "to_address": "TUserWalletAddress...",
  "metadata": {
    "user_id": "user_123"
  },
  "timestamp": "2024-01-15T10:05:00.000Z"
}

Webhook Events

EventDescription
payout.pendingPayout created, awaiting signature
payout.signedTransaction signed, ready to broadcast
payout.confirmingTransaction broadcast, awaiting confirmations
payout.completedPayout confirmed on chain
payout.failedPayout failed
payout.cancelledPayout cancelled

Bulk Payouts

Currently, each payout is processed as an individual transaction. Each payout requires:

  1. Create payout request
  2. Sign on hardware wallet
  3. Broadcast transaction

Why no batch payouts?

Standard TRC20/BEP20 transfers only support one recipient per transaction. Batching multiple payouts into a single transaction would require:

  • Custom smart contracts deployed on each chain
  • More complex transaction signing
  • Higher gas costs for contract execution

For high-volume payouts, we recommend:

  • Queue payouts: Collect pending payouts and process them sequentially
  • Use dashboard: The Traxvo dashboard allows signing multiple payouts efficiently
  • Automate with API: Build automation to create and sign payouts programmatically

Security

Non-Custodial Design

Traxvo never has access to your private keys:

  • Private keys remain on your hardware wallet
  • We only provide unsigned transactions
  • You sign and broadcast through your own device

Hardware Wallet Benefits

FeatureBenefit
Offline signingPrivate keys never touch the internet
Physical confirmationEach transaction requires button press
Tamper-resistantHardware designed to protect keys
Multi-currencySame device for TRON and BSC

Best Practices

  1. Use dedicated payout wallet - Keep payout funds separate from main holdings
  2. Monitor balances - Ensure payout wallet has sufficient funds
  3. Verify addresses - Double-check recipient addresses on device screen
  4. Set up webhooks - Get real-time notifications for all payout events

On this page