> For the complete documentation index, see [llms.txt](https://docs-sdk.crypto-chief.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs-sdk.crypto-chief.com/processing/java/guides/payouts.md).

# Send a payout

Send single crypto payouts in Java — estimate, execute idempotently, and wait for confirmation.

A payout sends crypto from your project balance to any address. The flow is **estimate** (optional) → **execute** → **wait for confirmation** (optional).

## Estimate

Preview the network fee and the net amount the recipient receives before sending:

```java
import com.cryptochief.processing.Chain;
import com.cryptochief.processing.models.EstimatePayoutRequest;

var est = client.payouts().estimate(
    EstimatePayoutRequest.of(Chain.ETH_MAINNET, "USDT", "25.0", "0xRecipient..."));
// est.amountToReceive(), est.feeInfo().estimatedFiat(), est.sources()
```

{% hint style="warning" %}
**On TRON the fee fields are not the whole cost.** `feeInfo()` here, and `fee_info.total_fee_paid_fiat` on the payout webhook, cover **on-chain gas only**. Energy rented for the transfer — which is the platform default, `gas_source=rented` — is billed to your API credits instead, in every fee mode, so you will see a credits charge that no fee field accounts for. It is one cost billed once; reconcile it from the credits ledger. See [Auto-sweep settings](/processing/java/guides/auto-sweep-settings.md#billing).
{% endhint %}

## Execute

```java
import com.cryptochief.processing.models.ExecutePayoutRequest;

var payout = client.payouts().execute(new ExecutePayoutRequest(
    "order-42",        // idempotency key — safe to retry
    "u-7",
    Chain.ETH_MAINNET,
    "USDT",
    "25.0",
    "0xRecipient...",
    "https://your.app/webhooks/payout",
    null, false, false, null, null, null));
```

{% hint style="info" %}
`orderId` is an **idempotency key**: re-submitting the same `order_id` returns the same payout instead of creating a second one. That is what makes the SDK's automatic retries safe.
{% endhint %}

## Wait for confirmation

```java
import com.cryptochief.processing.PollOptions;
import com.cryptochief.processing.poll.Polling;
import java.time.Duration;

var finalPayout = Polling.waitForPayout(client, payout.uuid(),
    new PollOptions(Duration.ofSeconds(5), Duration.ofMinutes(5)));
if (finalPayout.succeeded()) {
    System.out.println("paid: tx=" + finalPayout.txid());
}
```

Or react to the `payout.*` [webhook](/processing/java/guides/webhooks.md) instead of polling.

## Pay out in a different asset (swap)

{% hint style="warning" %}
**Not available yet.** The payout request carries an `auto_convert` field and this SDK exposes it, but the platform refuses any payout that sets it, answering `AUTO_CONVERT_NOT_IMPLEMENTED`. `auto_convert_policy` is reserved alongside it. Convert the asset yourself and pay out what the master wallet already holds.
{% endhint %}

## Handle errors

```java
import com.cryptochief.processing.exceptions.ApiException;
import com.cryptochief.processing.exceptions.ErrorCode;

try {
    client.payouts().execute(req);
} catch (ApiException e) {
    switch (e.code()) {
        case ErrorCode.INSUFFICIENT_FUNDS -> { /* top up and retry */ }
        case ErrorCode.ASSET_NOT_ENABLED -> { /* coin/network not enabled */ }
        case ErrorCode.DEBT_LIMIT_EXCEEDED -> { /* postpaid cap hit */ }
        default -> throw e;
    }
}
```

See [Errors & retries](/processing/java/concepts/errors.md).

{% content-ref url="/pages/5UbuUpe65sK6O1k0Hw9s" %}
[Mass payouts](/processing/java/guides/mass-payouts.md)
{% endcontent-ref %}
