# payout

* Make sure the address is formatted correctly and matches the network.
* The amount must be a string and should be in the standard currency unit. I.e. ETH (not WEI) and TRX (not SUN)
* Token is optional, use only if sending token. E.g. USDT&#x20;

## <mark style="color:blue;">Example</mark>

Sending 100 USDT on Tron to `TTVkK6hGoAFhALG9NTkUDHjcFFXKmWcScU` for `user123`

{% tabs %}
{% tab title="TypeScript" %}

```typescript
const { l2Hash } = await akashicPay.payout(
  "user123",
  "TTVkK6hGoAFhALG9NTkUDHjcFFXKmWcScU",
  "100",
  NetworkSymbol.Tron,
  TokenSymbol.USDT
);
```

{% endtab %}

{% tab title="PHP" %}

```php
$result = $akashicPay->payout(
  "user123",
  "TTVkK6hGoAFhALG9NTkUDHjcFFXKmWcScU",
  "100",
  NetworkSymbol::TRON,
  TokenSymbol::USDT
);
```

{% endtab %}

{% tab title="Java" %}

```java
APPayoutResult result = akashicPay.payout(
  "user123",
  "TTVkK6hGoAFhALG9NTkUDHjcFFXKmWcScU",
  100.0,
  APNetworkSymbol.TRX,
  APTokenSymbol.USDT
);
```

{% endtab %}

{% tab title="C#" %}
{% code overflow="wrap" %}

```csharp
var trxPayoutResult = await sdk.PayoutAsync(
  "user123",
  "TTVkK6hGoAFhALG9NTkUDHjcFFXKmWcScU",
  100.0,
  TronShastaNetworkSymbol.Value,
  ApTokenSymbol.Usdt
);
```

{% endcode %}
{% endtab %}

{% tab title="Go" %}
{% code overflow="wrap" %}

```go
l2Hash, err := ap.Payout("user123", "TTVkK6hGoAFhALG9NTkUDHjcFFXKmWcScU", "100", akashicpay.Tron, akashicpay.USDT)

```

{% endcode %}
{% endtab %}
{% endtabs %}

## <mark style="color:blue;">**Return Example**</mark>

Returns the [L2](https://docs.akashicpay.com/introduction/terminology#layer-2) transaction hash if the transaction is successful. Otherwise, returns an error-code.

Note: `l2Txnhash` (the "L2-hash") should always be used as the unique identifier of a transaction. This is a unique transaction-hash for any transaction on [AkashicChain](https://docs.akashicpay.com/introduction/terminology#akashicchain). It is present for Confirmed deposits and Pending/Confirmed payouts. This is particularly important for the case of [Layer 2](https://docs.akashicpay.com/introduction/terminology#layer-2) transactions, which will not have a Layer 1 hash (`txHash`)

{% tabs %}
{% tab title="TypeScript" %}

```typescript
// Success
{
  l2Hash: 'ASe5659e1700b9004ef06a622e49b6d367d3a76d3fed5e7872aaf684b51b824a89'
}

// Failure
{
  error: AkashicErrorCode.SavingsExceeded // 'FUNDS_EXCEEDED'
}
```

{% endtab %}

{% tab title="PHP" %}

```php
["l2Hash" => 'ASe5659e1700b9004ef06a622e49b6d367d3a76d3fed5e7872aaf684b51b824a89']
```

{% endtab %}

{% tab title="Java" %}

```java
{
  l2Hash: "ASe5659e1700b9004ef06a622e49b6d367d3a76d3fed5e7872aaf684b51b824a89"
}
```

{% endtab %}

{% tab title="C#" %}

```csharp
{
  l2Hash: "ASe5659e1700b9004ef06a622e49b6d367d3a76d3fed5e7872aaf684b51b824a89"
}
```

{% endtab %}

{% tab title="Go" %}

```go
// L2 Hash (string)
"ASe5659e1700b9004ef06a622e49b6d367d3a76d3fed5e7872aaf684b51b824a89"
```

{% endtab %}
{% endtabs %}

## <mark style="color:blue;">Errors</mark>

The function will return a field name\* `error` with an error-code upon any expected failure. Note that an error may still be thrown on any unexpected failure (e.g. network issues causes the transaction-submission to time out). For a full list of all errors, see [Errors](https://docs.akashicpay.com/sdk/errors).

\* In the `Go` case, an error object is returned as per standard Go practice.

Expect errors returned by the function are:

<table><thead><tr><th>Error</th><th>Explanation</th><th data-hidden></th></tr></thead><tbody><tr><td><pre><code>L2ADDRESS_NOT_FOUND
</code></pre></td><td>If trying to send to an Layer 2 transaction and the recipient does not exist on AkashicChain. If only doing <a href="../../../introduction/terminology#layer-1">Layer 1</a> transactions, ignore this.</td><td></td></tr><tr><td><pre><code>FUNDS_EXCEEDED
</code></pre></td><td>You do not posses enough funds of the chosen currency to complete the transaction. Re-check your balances.</td><td></td></tr><tr><td><pre><code><strong>UNKNOWN_ERROR
</strong></code></pre></td><td>Usually means you've done something wrong. E.g. trying to send without having created or onboarded your account to AkashicPay. Could also indicate unexpected problems with AkashicPay while trying to orchestrate the transaction. Should be rare. Check your details, retry quickly, and contact Customer Support if no solution is found. </td><td></td></tr></tbody></table>

If an `UNKNOWN_ERROR` is thrown, it could indicate an [AkashicChain](https://docs.akashicpay.com/introduction/terminology#akashicchain) error. Check the `details` of the thrown error for more information. If you have done everything correctly, these errors are usually transient and a retry after a small delay should succeed.

#### Callback

If a callback URL is registered for `payout` on [Akashicpay.com](https://docs.akashicpay.com/introduction/terminology#akashicpay.com), you will receive an HTTP call to that URL with the body like the following:

Note: If the response to the callback has a status code >= 400, the callback is retried up to 10 times with increasing delays up to around 15mins since the first attempt.

**NB:** While we aim for stability and consistency at Akashic, we cannot guarantee that the below object remains unchanged. For example, new features might necessitate additional fields in the callback. We will however aim to not remove existing fields. For convenience, we recommend filtering and handling the callback as per your needs while being open to the possibility of future additions.

```json

  {
  "fromAddress": "TTVkK6hGoAFhALG9NTkUDHjcFFXKmWcScU", // sending wallet/account of transaction
  "toAddress": "TQH8ygbS8BAnzSQ9uxR9vXHJYMQVRvbgPg", // receiving wallet/account of transaction
  "layer": "L1Transaction", // 'L1Transaction' or 'L2Transaction'
  "initiatedAt": "2024-08-19T10:02:54.000Z", // ISO8601 format
  "confirmedAt": "2024-08-19T10:04:02.000Z", // Only present if status is 'Confirmed' or 'Failed'
  "amount": "1.000000",  // Amount sent
  "coinSymbol": "TRX", // NetworkSymbol, e.g. 'ETH' or 'TRX'
  "status": "Confirmed", // TransactionStatus. 'Pending', 'Confirmed', or 'Failed'
  "txHash": "28a9880ad2ef3b7be1c40763128ec9630ab74e4749a3c81037c3501e4209bfcc", // Network's hash if L1. Not present for L2
  "feesEstimate": "6.114654", // Gas fee estimated by Akashic. Not present for L2
  "feesPaid": "5.822220, // Gas Fee paid on network. Not present for L2
  "l2TxnHash": "ASe7eb1cb8193787040fcffa02a224a6ced7415ff2205343c0ab661e898e8d6eef", // Akashic Transaction Hash. For both L1 and L2 
  "senderInfo": {
    "identity": "ASbb8efead2d5ff2f618a85895bac8e8ac1bae236d4d730bf113400b7e6f108ca5", // Akashic Address of sender
  },
  "senderIdentity": "ASbb...", // DEPRECATED. Same as above. Please use senderInfo.identity instead
  "tokenSymbol": "USDT", // TokenSymbol. Present only if token-transaction
  "internalFee": {
    "withdraw": "0.100000"
  }, // Akashic Fee { deposit?: string, withdraw?: string}
   "identifier": "user123", // User-identifier
   "feeIsDelegated": false, // Whether L1 gas fees were paid using token instead of native coin
   "directResolution": false // true if the transaction was never registered in the "Pending" state
}

```

*A note on withdrawal fees*

There are a few different components in play regarding fees when doing a withdrawal. These are:&#x20;

* Akashic Fee (`internalFee.withdraw` in callback), always in the same currency as the transaction. I.e. ETH for an ETH transfer, USDT for a USDT transfer, USDC for a USDC transfer, etc. **Normally 0 unless "fee delegation" happens, see below.**&#x20;
* [Gas Fee](https://docs.akashicpay.com/introduction/terminology#fees-gas) (`feesPaid` in callback), always in [native coin](https://docs.akashicpay.com/introduction/terminology#coins) (e.g. ETH for a ERC20 USDT or USDC transfer, TRX for a TRC20 USDT transfer, BNB for a BEP20 USDT or USDC transfer etc.). Charged by the [L1 networks ](https://docs.akashicpay.com/introduction/terminology#layer-1)(Ethereum, Tron, BNB Smart Chain (BSC), Solana etc.)
* "Fee Delegation". The Akashic system lets you pay for the aforementioned native fee in tokens instead of native coin to simplify matters. If this is done, `feeIsDelegated` will be `true` in the callback. All withdrawals done using the SDK should be "delegated" while withdrawals initating from [AkashicLink](https://docs.akashicpay.com/introduction/terminology#akashiclink) will not by default. The extra token-amount needed to "delegate" the fee is in `internalFee.withdraw`&#x20;

Using this, to calculate the total amount spent by a user we can do (assuming callback data of the form shown above is in `txCallback`):

<pre class="language-typescript"><code class="lang-typescript"><strong>// Token transaction (USDT)
</strong><strong>if (txCallback.tokenSymbol) {
</strong><strong>    userTokenSpent = txCallback.amount + txCallback.internalFee.withdraw;
</strong><strong>    // If fee is not delegated, gas fees are paid in native coin
</strong><strong>    if (!feeIsDelegated) {
</strong><strong>        userNativeCoinSpent = txCallback.feesPaid;
</strong><strong>    }
</strong><strong>} else {
</strong>// Coin transaction (ETH, TRX)
<strong>    userNativeCoinSpent = txCallback.amount + txCallback.internalFee.withdraw 
</strong><strong>        + txCallback.feesPaid;
</strong><strong>}
</strong><strong>
</strong></code></pre>

Note that the above is pseudocode. You would probably need to take extra care of handling potential undefined/null values like `internalFee` as well as parse the numbers safely and correctly, following normal practices in your chosen programming language.
