# Transaction flow (Deposits & Withdrawals)

This doc explains how **transaction status fields** are used in HollaEx.

### Concepts and balances

HollaEx effectively treats funds in a few “buckets”:

* **Available balance**: spendable/tradable/withdrawable (depending on your rules).
* **Locked amount**: reserved so the user can’t double-spend while a withdrawal is pending.
* **Final balance deduction**: when the withdrawal is confirmed/settled.

Withdrawals typically move funds like:

**Available → Locked → Deducted (final)**

***

### Deposits: what fields do

#### Deposit `status`

* `status: false` → **does nothing** (no balance change).
* `status: true` → **adds balance** (credits user funds).

#### Other deposit fields

Other fields may exist on the deposit record, but **do not trigger special behavior by default**. They are still useful as:

* metadata for audits,
* integration-specific routing,
* custom flow extensions in a plugin.

***

### Withdrawals: lifecycle and field meanings

A withdrawal record contains flags like:

```json
{
  "type": "withdrawal",
  "status": false,
  "dismissed": false,
  "rejected": false,
  "processing": false,
  "waiting": false,
  "onhold": false
}
```

#### Core behavior at creation time

When a withdrawal is **created**:

* It **deducts from available** immediately
* and **locks the amount** (reserves it).

So the user can’t use the same funds again while the withdrawal is pending.

***

### What each withdrawal field means

#### `status` (finalization switch)

* `status: false` → withdrawal is **not finalized**.
* `status: true` → withdrawal is **finalized** and the system **deducts the balance** (i.e., completes the accounting outcome).

In other words:

* Creation locks funds.
* `status=true` completes the “final deduction” step.

#### `rejected` and `dismissed` (unlock paths when not finalized)

If `status: false` and **either**:

* `rejected: true`, or
* `dismissed: true`

then the system should **unlock** the locked funds (release them back to available), because the withdrawal won’t be finalized.

“Updating `rejected` or `dismissed` to true when `status` is false will unlock the locked balance.”

`dismissed` is generally used when admin dismissed the transaction and `rejected` is used when the system rejects the transaction.

#### `processing` and `waiting` (worker/cron safety flags)

* They **do not change balances**
* They exist to **prevent race conditions** (e.g., cron job double-picking the same withdrawal)
* They can be used however you want as “in-progress” markers.

Typical intention:

* `processing: true` → a worker has claimed it and is actively handling it now.
* `waiting: true` → it’s queued/backing off/awaiting external confirmation (or simply “don’t pick me again yet”).

#### `onhold` (manual pause / admin gate)

* Does not directly change balances by itself.
* Used to prevent automated processing until an admin clears it.
* Once you clean `onhold: false` the transaction would go back to its original course.
* Practically: if `onhold: true`, the cron/plugin should skip it.
* Note that when you set `onhold: false` you should not update other flags in the same request. Setting `onhold` to `true` and `false` should be done independently.

***

### Withdrawal state transitions

#### 1) New withdrawal (eligible for processing)

* Funds: **Available decreases**, **Locked increases**
* Flags commonly look like:
  * `status=false`
  * `processing=false`
  * `waiting=false`
  * `onhold=false`
  * `rejected=false`
  * `dismissed=false`

#### 2) Claimed by cron/plugin

* Funds: unchanged
* Flags:
  * set `processing=true` (or `waiting=true` depending on your approach)

#### 3) Success path (completed)

* Set `status=true`
* Funds: **final deduction happens** (the withdrawal is accounted as completed)

#### 4) Failure path (not completed, funds returned)

* Keep `status=false`
* Set `rejected=true` **or** `dismissed=true`
* Funds: **locked amount is unlocked** back to available

***

### Retry behavior: “Resend withdrawal”

When you click **Resend withdrawal**:

* it **sets all values to `false`**,
* so the withdrawal returns to the “fresh / eligible” state,
* and it will **re-enter the plugin cron processing flow**.

So it effectively:

* clears `processing`, `waiting`, `onhold`, `rejected`, `dismissed`, and keeps `status=false`,
* making it pickable again by the worker.

This is a “reset and retry” mechanism.

***

### Admin console: validation + retry logic

Even without code-level specifics, the admin console typically implements guardrails like:

#### Validation (what should be checked before processing)

Common checks before a worker/admin action finalizes:

* Withdrawal still exists and is consistent (amount, asset, destination).
* Sufficient locked amount exists (i.e., it was reserved).
* Not already finalized (`status !== true`).
* Not blocked by flags (e.g., `onhold === true`, or `processing === true` depending on the action).

#### Retry logic (what “resend” achieves)

* Clears flags that prevent picking (`processing/waiting/onhold`)
* Leaves it in a clean `status=false` state for cron/plugin to attempt again

#### Preventing double processing (race condition control)

The reason `processing`/`waiting` exist is to ensure:

* two cron runs don’t send the same withdrawal twice,
* an admin action doesn’t collide with a worker action.

***

### Practical “rules of thumb”

* **Deposits:** only `status=true` credits balance. `status=false` does nothing.
* **Withdrawals:**
  * Creation: **locks** funds (reduces available, increases locked).
  * `status=true`: **finalizes** and deducts balance.
  * `status=false` + (`rejected=true` or `dismissed=true`): **unlocks** funds.
  * `processing/waiting`: **no balance effects**, just worker flags.
  * `onhold`: **pause flag** (usually skip in cron).
* **Resend withdrawal:** sets everything to `false` → makes it eligible for cron/plugin again.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hollaex.com/plugins/bank-integration/transaction-flow-deposits-and-withdrawals.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
