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

# 发送资金

> 使用 sendMoney 将用户现金余额中的资金发送到电子邮箱、手机号、Fluz 账户或领取链接，并可取消无人领取的汇款。

使用 [`sendMoney`](https://docs.fluz.app/api-reference/mutations/send-money) 从用户的 Fluz 现金余额发送资金。你可以将资金发送到电子邮箱或手机号、Fluz 账户 ID，也可以不指定收款人，这时你会得到一个领取链接，由你自行转交。收款人无需是你应用的用户，也无需已有 Fluz 账户。

一笔汇款有两种结果。`SENT` 表示资金已进入收款人的余额，这是最终结果。`PENDING_CLAIM` 表示 Fluz 保管这笔资金，直到收款人在 Fluz 页面上领取。如果到期前无人领取，或你取消了汇款，资金会退回发送方。你指定收款人的方式决定了出现哪种结果。

> [!NOTE]
>
> **开始之前**
>
> * 调用时请使用具有 `MAKE_PAYOUT_TRANSFER_SEND` 权限范围的 Bearer 用户访问令牌。不接受使用 API 密钥的 Basic Auth。
> * 令牌所属用户必须是该账户的所有者或管理员。
> * Fluz 按账户开通发送资金功能。请联系你的客户经理，为每个需要发送资金的账户开通。
> * 账户必须已通过身份验证：个人账户为 KYC，企业账户为 KYB。
> * 如果用户将你的应用限制为只能使用某些消费账户，请从其中一个账户发送。

> [!NOTE]
>
> **与 `createTransfer` 不同。**
>
> [`createTransfer`](https://docs.fluz.app/features/transfer-to-another-fluz-wallet) 在你的应用账户与已授权你的应用的账户之间移动资金，也可以在两个这样的账户之间移动资金。`sendMoney` 可以向任何能够接收付款的 Fluz 账户付款，也可以通过电子邮箱或手机号联系到对方。对于新收款人，它会保管这笔资金直到对方领取，并由 Fluz 向对方发送领取链接。

## 汇款如何送达

| 发送到 | 结果 |
| :- | :- |
| `recipientId` | 资金立即转入该账户（`SENT`）。如果该账户无法接收付款，汇款会被拒绝，不会转为待领取。 |
| `recipientEmail` 或 `recipientPhone`，且有 Fluz 用户已验证该联系方式 | 资金立即转入该用户的个人账户（`SENT`）。 |
| `recipientEmail` 或 `recipientPhone` 与任何 Fluz 用户都不匹配，或匹配的用户尚未验证该联系方式 | Fluz 保管资金（`PENDING_CLAIM`），并通过你提供的联系方式向收款人发送领取链接。 |
| `linkOnly: true` | Fluz 保管资金（`PENDING_CLAIM`）并返回 `claimLink`。Fluz 不会联系任何人，由你转交该链接。 |

Fluz 会匹配用户 Fluz 资料中的电子邮箱和手机号。如果其中任何一个匹配到多个用户，汇款会被拒绝，你需要改用其他标识。

你可以为同一个人同时传入 `recipientEmail` 和 `recipientPhone`。如果两者匹配到同一个用户，以手机号为准：只有该用户已验证手机号，资金才会立即转入其账户。如果两者匹配到两个不同的用户，Fluz 不会择一，而是保管资金。如果只有其中一个匹配到用户，则由该联系方式单独决定：只要用户已验证它，即使另一个联系方式没有匹配到任何人，资金也会立即转入该用户的账户。

`recipientId` 不能与电子邮箱或手机号同时使用，`linkOnly` 不能与任何收款人同时使用。不能向发送方自己的账户汇款。

如果汇款本应立即到账却无法到账，例如收款人的账户无法接收付款，或金额超出限额，汇款会失败并返回错误。Fluz 不会改为保管这笔资金。

## 发送资金

同一个变更涵盖所有类型的汇款，只有输入不同。

```graphql Mutation theme={null}
mutation SendMoney($input: SendMoneyInput!) {
  sendMoney(input: $input) {
    result
    transferId
    destinationAccountId
    shareRequestId
    claimLink
    claimStatus
  }
}
```

### 发送到电子邮箱或手机号

```json Variables theme={null}
{
  "input": {
    "idempotencyKey": "6f2b8c1e-4d3a-4f7b-9a21-3c5e8d9f0a12",
    "amount": 25,
    "sourceCashBalanceId": "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed",
    "recipientEmail": "alex@example.com",
    "memo": "Dinner on Friday"
  }
}
```

```json Response (held) theme={null}
{
  "data": {
    "sendMoney": {
      "result": "PENDING_CLAIM",
      "transferId": "c56a4180-65aa-42ec-a945-5fd21dec0538",
      "destinationAccountId": null,
      "shareRequestId": "0b8f2a5e-7c41-4d9e-8f3a-2e6b9c1d4a70",
      "claimLink": "https://fluz-links.short.gy/Xy7Kq2",
      "claimStatus": "PENDING"
    }
  }
}
```

```json Response (sent) theme={null}
{
  "data": {
    "sendMoney": {
      "result": "SENT",
      "transferId": "c56a4180-65aa-42ec-a945-5fd21dec0538",
      "destinationAccountId": "a2c02ec6-357b-41cf-9229-4da34e727019",
      "shareRequestId": null,
      "claimLink": null,
      "claimStatus": null
    }
  }
}
```

`claimLink` 是指向领取页面的短链接。请原样使用返回的链接，不要自行拼接或解析。

要发送到手机号，请传入 E.164 格式的 `recipientPhone`（例如 `+14155551234`），而不是 `recipientEmail`。

### 发送到 Fluz 账户

传入收款人的账户 ID。汇款要么立即到账，要么被拒绝。

```json Variables theme={null}
{
  "input": {
    "idempotencyKey": "3d1f9a7c-2b5e-4c8d-a6f0-7e9b1c2d3a45",
    "amount": 40.5,
    "sourceCashBalanceId": "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed",
    "recipientId": "a2c02ec6-357b-41cf-9229-4da34e727019"
  }
}
```

### 以领取链接发送

设置 `linkOnly`，并自行转交 `claimLink`，例如放在你自己的应用或消息中。

```json Variables theme={null}
{
  "input": {
    "idempotencyKey": "9a4e2c7b-1f3d-4b6a-8c5e-0d2f4a6b8c1e",
    "amount": 15,
    "sourceCashBalanceId": "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed",
    "linkOnly": true
  }
}
```

> [!WARNING]
>
> **请像对待密码一样对待领取链接。**
>
> 任何持有仅链接汇款的 `claimLink` 的人，通过身份验证后都可以领取这笔资金。它的 `shareRequestId` 同样敏感，因为凭它也能打开领取页面。请勿将两者写入日志和分析系统。

## 输入字段

[`SendMoneyInput`](https://docs.fluz.app/api-reference/types/send-money-input)

| 字段 | 类型 | 必填 | 说明 |
| :- | :- | :- | :- |
| `idempotencyKey` | `UUID!` | 是 | 你为每笔新汇款生成的 UUID。参见[幂等性](#幂等性)。 |
| `amount` | `Float!` | 是 | 大于 0，最大 1,000,000，最多两位小数。 |
| `sourceCashBalanceId` | `UUID!` | 是 | 付款的消费账户的 `userCashBalanceId`，可从 [`getUserCashBalances`](https://docs.fluz.app/features/get-spend-accounts) 获取（需要 `LIST_PAYMENT` 权限范围）。它必须是令牌所属账户下处于激活状态的消费账户。 |
| `recipientEmail` | `String` | 任选其一 | 收款人的电子邮箱。 |
| `recipientPhone` | `String` | 任选其一 | 收款人的手机号，E.164 格式。 |
| `recipientId` | `UUID` | 任选其一 | 收款人的 Fluz 账户 ID。 |
| `linkOnly` | `Boolean` | 任选其一 | 设为 `true` 可获得不指定收款人的领取链接。 |
| `memo` | `String` | 否 | 给收款人的备注，最多 255 个字符。不能以 `=`、`+`、`-`、`@`、制表符或回车符开头，即使前面有空白字符也不行。 |
| `daysUntilExpiration` | `Int` | 否 | 待领取的汇款可被领取的天数，取值 1 到 365。默认为 30。 |

指定汇款对象时，可以使用 `recipientEmail`、`recipientPhone` 或两者同时使用，也可以使用 `recipientId` 或 `linkOnly`。

对于待领取的汇款，备注会显示在领取页面上，任何打开链接的人都能看到，即使汇款已被领取或退回也是如此。请不要在备注中写入个人信息。

## 响应字段

[`SendMoneyResponse`](https://docs.fluz.app/api-reference/types/send-money-response)

| 字段 | 类型 | 说明 |
| :- | :- | :- |
| `result` | `MoneySendResult!` | `SENT` 或 `PENDING_CLAIM`。 |
| `transferId` | `UUID` | 实际移动资金的转账，或在汇款等待领取期间保管这笔资金的转账。 |
| `destinationAccountId` | `UUID` | 收到资金的账户。仅当 `result` 为 `SENT` 时才有值。 |
| `shareRequestId` | `UUID` | 标识一笔待领取的汇款。将其传给 `cancelMoneySend`。仅当 `result` 为 `PENDING_CLAIM` 时才有值。它和 `claimLink` 一样能打开领取页面，请勿将其写入日志和分析系统。 |
| `claimLink` | `String` | 收款人用来领取资金的链接。仅在 `claimStatus` 为 `PENDING` 时返回。 |
| `claimStatus` | `MoneySendClaimStatus` | 待领取汇款的当前状态。参见[追踪待领取的汇款](#追踪待领取的汇款)。 |

## 收款人需要做什么

领取在 Fluz 页面上完成，而不是通过 API。

**1. 打开链接**

Fluz 会把领取链接发送到你汇款所用的电子邮箱或手机号。对于仅链接汇款，由你转交链接。

**2. 登录或创建 Fluz 账户**

资金会转入收款人领取时所登录的账户，个人账户或企业账户均可。

**3. 验证身份**

账户必须通过身份验证：个人账户需通过 KYC，企业账户需通过 KYB，并且账户能够接收付款。

**4. 证明联系方式**

对于发送到手机号的汇款，收款人 Fluz 账户上的手机号必须与之匹配且已验证。对于发送到电子邮箱的汇款，Fluz 会向该邮箱发送一个 6 位验证码。如果你同时填写了两者，已验证且匹配的手机号就足够了；如果收款人账户上的手机号匹配但尚未验证，需要先完成验证；否则，收款人需要输入邮箱验证码。仅链接汇款只需要链接。

任何打开链接的人在登录之前，就能在领取页面上看到金额、发送方的姓名和备注。

有人领取时，Fluz 会再次检查发送方的账户。如果该账户不再通过 KYC 或 KYB，或已被 Fluz 限制，领取会被拒绝，资金仍由 Fluz 保管，直到你取消这笔汇款或它到期。为账户关闭发送资金功能，并不会阻止该账户已有的待领取汇款被领取，因此对于想要阻止的汇款，请将其取消。

## 追踪待领取的汇款

要查看待领取汇款的当前状态，请使用相同的 `idempotencyKey` 和相同的输入再次调用 `sendMoney`。响应会重复原始结果和各个 ID，并附上当前的 `claimStatus`，仅在 `claimStatus` 为 `PENDING` 时包含 `claimLink`，且不会移动任何资金。

| `claimStatus` | 含义 |
| :- | :- |
| `PENDING` | 等待收款人领取。你可以取消。 |
| `CLAIMING` | 保留值。领取会让汇款直接从 `PENDING` 变为 `CLAIMED`。 |
| `CLAIMED` | 收款人已领取，资金已进入其余额。 |
| `RETURNED` | 已过期或已被取消，资金已退回发送方。 |

重复调用会执行与新汇款相同的权限范围、角色和消费账户检查，因此如果该用户不再是所有者或管理员，或你的应用不能再使用该消费账户，调用会被拒绝。

## 取消待领取的汇款

[`cancelMoneySend`](https://docs.fluz.app/api-reference/mutations/cancel-money-send) 可在汇款的 `claimStatus` 为 `PENDING` 时将其取消，并把资金退回其来源的现金余额。状态为 `SENT` 的汇款无法取消。

```graphql Mutation theme={null}
mutation CancelMoneySend($shareRequestId: UUID!, $idempotencyKey: UUID!) {
  cancelMoneySend(shareRequestId: $shareRequestId, idempotencyKey: $idempotencyKey) {
    cancelled
    transferId
  }
}
```

```json Variables theme={null}
{
  "shareRequestId": "0b8f2a5e-7c41-4d9e-8f3a-2e6b9c1d4a70",
  "idempotencyKey": "4c7e1a9b-6d2f-4e8a-b3c5-1f9d7a2e6b40"
}
```

```json Response theme={null}
{
  "data": {
    "cancelMoneySend": {
      "cancelled": true,
      "transferId": "c56a4180-65aa-42ec-a945-5fd21dec0538"
    }
  }
}
```

取消汇款需要相同的权限范围，且令牌所属用户必须是发送账户的所有者或管理员。你可以取消该账户发出的任何待领取汇款，包括由其他用户或应用发起的汇款。被拒绝的取消请求会以错误形式返回，因此 `cancelled` 始终为 `true`。同一用户在 24 小时内对同一笔汇款使用相同的 `idempotencyKey` 重复一次已成功的取消，会返回相同的响应。被拒绝的取消不会被保存，因此重复请求会重新执行。

## 到期

待领取的汇款可以领取到发送日之后第 `daysUntilExpiration` 天的东部时间当天结束。响应中不包含该日期，因此请在发送时自行记录。

此后领取会被拒绝，Fluz 会在次日早上将资金退回发送方的现金余额，由每天东部时间 9:00 运行的任务执行。在资金退回之前，`claimStatus` 仍显示为 `PENDING`，你仍然可以取消这笔汇款。

## 幂等性

`sendMoney` 和 `cancelMoneySend` 都接受 `idempotencyKey`，这是一个由你生成的 UUID。不区分大小写。

* 使用相同的幂等键和相同的输入重复调用，会返回原来的汇款，不会移动任何资金，并显示汇款的当前状态。
* 幂等键会一直与其对应的汇款绑定。Fluz 在 24 小时内从缓存中响应重复请求，之后则根据汇款本身响应，因此同一个幂等键绝不会发送两次。每笔新汇款请使用新的幂等键。
* 如果重复调用更改了金额、现金余额或收款人，或对一个已用于指定收款人的幂等键设置了 `linkOnly`，会被拒绝并返回 `ARG-0001`。不要复用其他操作的幂等键：用于 `createTransfer` 的幂等键会创建一笔新的汇款，用于对外打款的幂等键只有在该打款的幂等键为小写时才会被拒绝。
* `memo` 和 `daysUntilExpiration` 不参与比对。只更改这两项的重复调用，会原样返回原来的汇款。
* `sendMoney` 的幂等键归账户所有，而不是归你的应用所有。该账户下的另一个应用或用户使用相同的幂等键和输入，会返回原来的汇款。
* 如果汇款在任何资金移动之前就失败了，例如因为余额不足，该幂等键仍可使用。排除原因后，可以用相同的幂等键重试。

`G-0409` 表示 Fluz 仍在处理该幂等键，或其结果已丢失。汇款可能已经成功，因此请使用相同的幂等键和相同的输入重试，直到得到结果。处理中的请求最多会占用其幂等键 10 分钟。

## 限额

汇款会计入账户的转账限额：每日、每周、每月和每年的总额，以及单笔汇款的最小和最大金额。待领取的汇款从发送时起一直计入，直到资金退回。收款人的接收限额在资金到账时生效：立即到账的汇款在发送时生效，待领取的汇款在领取时生效。你账户的具体限额，请向你的客户经理咨询。

## 错误

错误会出现在 GraphQL 的 `errors` 数组中，此时 `sendMoney` 或 `cancelMoneySend` 为 `null`。请根据 `extensions.code` 区分处理。`ARG-` 和 `G-0003` 的消息会说明具体原因，其他消息可能会变化。

| 代码 | 出现场景 |
| :- | :- |
| `AUTH-0002` | 请求使用了 Basic Auth。请改用 Bearer 用户访问令牌。 |
| `AUTH-0031` | 令牌缺少 `MAKE_PAYOUT_TRANSFER_SEND`，或你的应用无法使用该现金余额。 |
| `AUTH-0008` | 令牌所属用户不是该账户的所有者或管理员。 |
| `G-0003` | `Account is not enabled for money sends`：Fluz 尚未为该账户开通发送资金功能。 |
| `G-0003` | `Sender is not authorized to send a payment.`：该账户尚未通过 KYC 或 KYB。 |
| `G-0003` | `Recipient is not able to receive payments`：你通过 `recipientId` 发送的目标账户无法接收付款，或这笔汇款会超出其接收限额，消息中不会说明原因。 |
| `ARG-0001`、`ARG-0002` | 输入无效，消息会指出具体问题。包括向发送方自己的账户汇款、联系方式匹配到多个用户，以及同一个幂等键被用于不同的输入。 |
| `PT-0007` | 现金余额不足以支付该金额。 |
| `PT-0008` | 个人账户的部分余额仍在等待入账，暂时无法发送。 |
| `US-0042` | `sourceCashBalanceId` 不是该账户名下的消费账户。完全不存在的 ID 可能会返回 `ARG-0001`。 |
| `CASH-0002` | 收款人没有可以接收这笔汇款的现金余额。 |
| `FLUZ-0113` | 发送方的账户目前无法发送资金。 |
| `FLUZ-0131`、`FLUZ-0140`、`FLUZ-0132`、`FLUZ-0141` | 这笔汇款会超出每日、每周、每月或每年的限额。 |
| `FLUZ-0142`、`FLUZ-0143` | 金额低于单笔最小金额，或高于单笔最大金额。 |
| `G-0409` | 该幂等键仍在处理中，或其结果已丢失。请使用相同的幂等键和输入重试。 |
| `G-0010` | 向电子邮件地址或电话号码汇款时，Fluz 的某项服务在设置收款人时出错。资金未发生变动。请使用相同的幂等键和输入重试；如果仍然失败，请联系你的客户经理。 |
| `G-0004` | 发生了意外错误，或消费账户未处于激活状态。请使用相同的幂等键和输入重试，如果仍然失败，请检查该消费账户。 |

立即到账的汇款还会经过 Fluz 的欺诈筛查，筛查可能以其他错误码拒绝该汇款。对于发送到 `recipientEmail` 或 `recipientPhone` 的汇款，`FLUZ-` 限额错误码也可能表示收款人的接收限额。

缺失、无效或已撤销的令牌会在操作执行前被拒绝，返回 HTTP 401；已过期的令牌返回 HTTP 498。这两种响应都不包含 GraphQL `errors` 数组。

对于 `cancelMoneySend`：

| 代码 | 消息 | 出现场景 |
| :- | :- | :- |
| `ARG-0001` | `Money send not found` | 该 ID 不是一笔汇款。 |
| `G-0003` | `You are not the sender of this money send` | 该汇款来自另一个账户。 |
| `G-0003` | `Money send is not cancellable (status USED)` | 收款人已领取。 |
| `G-0003` | `Money send is not cancellable (status EXPIRED)` | 已被取消或已退回。 |
| `G-0003` | `Money send escrow was settled concurrently` | 保管的资金已经结算，但该汇款仍显示为 `PENDING`。请提供 `shareRequestId` 联系你的客户经理。 |

## 参考资料

* [`sendMoney`](https://docs.fluz.app/api-reference/mutations/send-money) 和 [`SendMoneyInput`](https://docs.fluz.app/api-reference/types/send-money-input)
* [`SendMoneyResponse`](https://docs.fluz.app/api-reference/types/send-money-response)、[`MoneySendResult`](https://docs.fluz.app/api-reference/types/money-send-result) 和 [`MoneySendClaimStatus`](https://docs.fluz.app/api-reference/types/money-send-claim-status)
* [`cancelMoneySend`](https://docs.fluz.app/api-reference/mutations/cancel-money-send) 和 [`CancelMoneySendResponse`](https://docs.fluz.app/api-reference/types/cancel-money-send-response)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.