> ## Documentation Index
> Fetch the complete documentation index at: https://developers.uqpay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Transfer Between Accounts

> Move funds between a master Global Account and its sub-accounts by using the Transfer APIs.

Use internal transfers to move available Global Account balance between a master account and one of its sub-accounts. This is typically used to fund a sub-account before payout, sweep funds from a sub-account back to the master account, or rebalance balances across your account structure.

Internal transfers are different from payouts and deposits:

| Use case                                               | What to use                                                                                                                                                                                                                                                                                         |
| ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Move funds between your master account and sub-account | [Create Transfer](/global-account/v1.6/api-reference/create-transfer)                                                                                                                                                                                                                               |
| Send funds to an external bank account or beneficiary  | [Create Payout](/global-account/v1.6/api-reference/create-payout)                                                                                                                                                                                                                                   |
| Receive funds into a virtual account                   | Ask the payer to send a bank transfer to your virtual account. Use the [Deposit guide](/global-account/v1.6/guide/deposit), [List Deposits](/global-account/v1.6/api-reference/list-deposits), and [Retrieve Deposit](/global-account/v1.6/api-reference/retrieve-deposit) to track received funds. |

## Supported transfer directions

The transfer must involve the account represented by the authenticated API token. Direct sub-account to sub-account transfers are not supported. To move funds from one sub-account to another, transfer from the source sub-account to the master account first, then from the master account to the target sub-account.

| Direction                     | `source_account_id` | `target_account_id` | Typical use case                                  |
| ----------------------------- | ------------------- | ------------------- | ------------------------------------------------- |
| Master account to sub-account | Master account ID   | Sub-account ID      | Fund a sub-account before it initiates payouts.   |
| Sub-account to master account | Sub-account ID      | Master account ID   | Sweep collected funds back to the master account. |

The source and target must be different accounts. Both accounts must be active, and the transfer product must be enabled for both sides.

## Prerequisites

Before creating a transfer, confirm the following:

* The authenticated account is either the source account or the target account.
* The source and target accounts belong to the same master-sub-account relationship.
* Both accounts are active. If an individual account is involved, it must also be verified.
* The transfer product is enabled for both accounts and for the transfer direction.
* The source account has enough available balance for the transfer amount and any applicable fee.
* You have the account IDs for both sides. For sub-accounts, use the `account_id` from Account Center connected account APIs, not the short display ID.
* You generate a unique `x-idempotency-key` for each create request.

## Step 1: Check the source balance

Use [Retrieve Balance](/global-account/v1.6/api-reference/retrieve-balance) or [List Balances](/global-account/v1.6/api-reference/list-balances) to confirm the source account has enough available balance.

```bash theme={null}
curl --location 'https://api-sandbox.uqpaytech.com/api/v1/balances/USD' \
  --header 'Accept: application/json' \
  --header 'x-auth-token: {{token}}'
```

If the available balance is lower than the transfer amount plus fees, create transfer will fail. For zero-decimal currencies such as `IDR` and `JPY`, the transfer amount must be an integer.

## Step 2: Create the transfer

Call [Create Transfer](/global-account/v1.6/api-reference/create-transfer) with the source account, target account, currency, amount, and transfer reason.

```bash theme={null}
curl --location 'https://api-sandbox.uqpaytech.com/api/v1/transfer' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --header 'x-auth-token: {{token}}' \
  --header 'x-idempotency-key: 6a931dcb-ec6f-4f0c-90d7-ff7ebdfdf9b4' \
  --data '{
    "source_account_id": "2cc4f12a-9d1f-4e86-a98a-2f3a67d7e5a1",
    "target_account_id": "6d0af26e-475e-4fd4-a2e7-39f0ea38cbbb",
    "currency": "USD",
    "amount": "1000.00",
    "reason": "Fund sub-account before supplier payout"
  }'
```

A successful response returns the transfer identifiers:

```json theme={null}
{
  "transfer_id": "e08146de-4267-4e76-b35b-f7b34b656a53",
  "short_reference_id": "TQ8K9M2X4"
}
```

Store both identifiers. Use `transfer_id` for API retrieval and `short_reference_id` for operations, finance, or customer support workflows.

## Idempotency

Create Transfer requires `x-idempotency-key`. Use a UUID generated by your system and reuse the same key only when retrying the exact same request after a timeout or network failure.

If the same idempotency key is retried with the same request body, UQPAY returns the original transfer identifiers. If the same key is reused with a different request body, the request is rejected.

Recommended retry behavior:

* Retry on network timeouts, connection resets, or uncertain client-side failures.
* Reuse the same `x-idempotency-key` for retries of the same transfer.
* Do not create a new idempotency key unless you intend to create a separate transfer.
* After receiving a response, use [Retrieve Transfer](/global-account/v1.6/api-reference/retrieve-transfer) to confirm the final status.

## Step 3: Retrieve the transfer

Use [Retrieve Transfer](/global-account/v1.6/api-reference/retrieve-transfer) to get the latest status and transfer details.

```bash theme={null}
curl --location 'https://api-sandbox.uqpaytech.com/api/v1/transfer/e08146de-4267-4e76-b35b-f7b34b656a53' \
  --header 'Accept: application/json' \
  --header 'x-auth-token: {{token}}'
```

The response includes the source and destination account names, transfer amount, reason, status, and timestamps.

Common transfer statuses:

| Status      | Meaning                                                                                                                    |
| ----------- | -------------------------------------------------------------------------------------------------------------------------- |
| `completed` | The transfer has completed successfully.                                                                                   |
| `failed`    | The transfer failed. Check the request details, account status, product configuration, and source balance before retrying. |

## Step 4: List transfers for reconciliation

Use [List Transfers](/global-account/v1.6/api-reference/list-transfers) to reconcile internal movement over a period.

```bash theme={null}
curl --location 'https://api-sandbox.uqpaytech.com/api/v1/transfer?page_size=10&page_number=1&currency=USD&transfer_status=completed' \
  --header 'Accept: application/json' \
  --header 'x-auth-token: {{token}}'
```

You can filter by:

* `page_size` and `page_number`
* `start_time` and `end_time`
* `transfer_status`
* `currency`

Use the returned `transfer_id`, `short_reference_id`, `source_account_name`, `destination_account_name`, `transfer_amount`, and `complete_time` fields to match internal ledger entries.

## Common validation failures

| Failure                                         | How to resolve                                                                                                |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| Source and target are the same account          | Use different values for `source_account_id` and `target_account_id`.                                         |
| Transfer is not between master and sub-account  | Route the movement through the master account. Direct sub-account to sub-account transfers are not supported. |
| Account is not active or not verified           | Complete verification or activate the account before creating the transfer.                                   |
| Transfer product is not enabled                 | Contact UQPAY support to enable the transfer product for both accounts and the required direction.            |
| Insufficient balance                            | Check the source account balance and account for any applicable transfer fee.                                 |
| Amount is invalid                               | Use a positive amount with no more than two decimals. For `IDR` and `JPY`, use an integer amount.             |
| Idempotency key reused with a different payload | Generate a new key for a new transfer, or retry with the original request body.                               |

## Related API reference

* [Create Transfer](/global-account/v1.6/api-reference/create-transfer)
* [Retrieve Transfer](/global-account/v1.6/api-reference/retrieve-transfer)
* [List Transfers](/global-account/v1.6/api-reference/list-transfers)
* [List Balances](/global-account/v1.6/api-reference/list-balances)
* [Retrieve Balance](/global-account/v1.6/api-reference/retrieve-balance)
