> ## 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.

# 概览

从你的平台生成**托管虚拟卡链接**（“开放式”发送卡片）。你只需调用一个 API 即可铸造一个或多个链接，然后以任意方式将这些链接交付给收件人——通过电子邮件、短信，或直接返回原始 URL 以嵌入到你自己的流程中。收件人打开链接后，将进入由 Fluz 托管的页面，完成身份验证并领取一张从你的账户资金加载的一次性虚拟卡。

<Info>
  **先决条件：** 一个携带 `CREATE_SHARE_LINK` 范围的 Bearer 访问令牌，以及已启用发送卡片功能的账户（`send_virtual_cards_enabled` 活动标记）。不支持基本认证（Basic auth）。联系你的销售代表开通访问权限。参见 [Authentication](/concepts/authentication)。
</Info>

<Note>
  **“托管”/“开放式”是什么意思。** *托管* 链接指向由 Fluz 托管的激活页面。*开放式* 表示生成的虚拟卡是网络卡（Visa/Mastercard 风格），可在许多商户处使用，但须遵循你的项目规则——而不是单品牌的封闭式礼品卡。
</Note>

![托管虚拟卡](https://test.fluz.app/wp-content/uploads/2026/04/ol-mock.png)

## 工作原理

<Steps>
  <Step title="你生成链接">
    使用 `generateVCShareLinks` 指定优惠、卡片限额、数量、资金来源以及投递方式。每个链接代表一张卡片，拥有自身限额，并从你指定的消费账户扣款。
  </Step>

  <Step title="Fluz 为每个链接创建分享请求">
    每个链接对应一个分享请求（`PENDING`）和一个托管 URL。
  </Step>

  <Step title="链接被投递">
    选择 `GENERATE_URL` 时，你将获得返回的 URL 并自行分发。选择 `EMAIL` 或 `PHONE_NUMBER` 时，Fluz 会代你向每位收件人发送一个链接。
  </Step>

  <Step title="收件人激活并领取卡片">
    收件人打开链接，用一次性验证码验证手机号并设置卡片 PIN——无需下载应用、无需密码。卡片限额会在领取时而非生成链接时从你的消费账户占用。随后他们可查看卡片详情、在线消费，并一键将卡添加至 Apple Pay 或 Google Pay。
  </Step>
</Steps>

收件人仅成为该虚拟卡对象的授权用户——他们不会获得对你的账户、余额或任何其他卡片的访问权限。

查看收件人实际体验： [桌面流程](https://test.fluz.app/wp-content/uploads/2026/04/Web-Share-V6.mp4) · [移动流程](https://test.fluz.app/wp-content/uploads/2026/04/Mob-Share-F.mp4)。

![发送卡片流程图](https://files.readme.io/c19029bfeaca196f7eadc2f020ab56f2aad893261f561307bec543e700f0d74b-diagram.svg)

## 可用性与范围

| 能力             | 状态             |
| -------------- | -------------- |
| 一次性加载虚拟卡       | ✅ 支持           |
| 一次性使用 / 可重复加载卡 | ❌ 不支持          |
| 通过 API 生成链接    | ✅ 支持           |
| 通过 CSV 导入生成链接  | ✅ 支持           |
| 托管型**礼品卡**链接   | ❌ 不在范围内（仅限虚拟卡） |

卡片分享链接的对象类型为 `VIRTUAL_CARD`，卡片类型为 `SINGLE_LOAD`。

<Warning>
  **礼品卡：** 尽管更广泛的方案表述为“虚拟卡**与**礼品卡”，目前并没有托管的礼品卡领取流程。礼品卡余额仅会作为托管虚拟卡的\_潜在资金来源\_出现（规划中，尚未启用）。请仅针对虚拟卡进行文档编写与集成开发。
</Warning>

## 操作参考

共有三个公开操作，均受 `CREATE_SHARE_LINK` 范围控制：

| 操作                       | 类型       | 目的             |
| ------------------------ | -------- | -------------- |
| `generateVCShareLinks`   | Mutation | 创建一个或多个托管虚拟卡链接 |
| `getVCShareLinks`        | Query    | 列出/查看先前生成的链接   |
| `deactivateVCShareLinks` | Mutation | 停用（失效）你生成的链接   |

所有发送卡片操作均通过 Fluz GraphQL API 调用：`POST https://<your-fluz-api-host>/api/v1/graphql`，并携带 `Authorization: Bearer <access_token>` 头。令牌必须包含 `CREATE_SHARE_LINK` 范围，且你的账户必须已启用发送卡片功能——否则，每个操作都会返回 *"Missing permissions! Please contact your sales rep to get access to generate VC share links."*。

## generateVCShareLinks

创建 `quantity` 个分享请求，并为每个请求返回一个托管链接。

```graphql theme={null}
mutation GenerateVCShareLinks($input: GenerateVCShareLinksInput!) {
  generateVCShareLinks(input: $input) {
    shareLinks
  }
}
```

### 输入字段

| 字段                    | 类型                 | 必填  | 说明                                                                                       |
| --------------------- | ------------------ | --- | ---------------------------------------------------------------------------------------- |
| `cardLimit`           | `Int!`             | 是   | 每张卡的消费限额（同时也是加载金额），以法币最小单位的整数表示。必须为不小于项目最低限额的整数。                                         |
| `offerId`             | `String!`          | 是   | 卡片绑定的商户优惠的 UUID v4。该优惠必须为激活状态，且其商户必须可分享。                                                 |
| `quantity`            | `Int!`             | 是   | 要生成的链接数量。每个单位会创建一个唯一的托管 URL。                                                             |
| `shareMethod`         | `ShareMethodType!` | 是   | 链接的投递方式：`GENERATE_URL`、`EMAIL` 或 `PHONE_NUMBER`。                                         |
| `userCashBalanceId`   | `UUID`             | 是\* | 用于为卡片提供资金的消费账户。*在架构中标记为可选，但实际上必填——省略将导致校验失败。*                                            |
| `daysUntilExpiration` | `Int`              | 否   | 链接到期的天数。最少 1。若省略，则默认为项目默认值（30 天）。**该日期也将成为卡片的锁定/冻结日期**——参见 [到期与冻结](#expiration--freeze)。 |
| `recipientListEmail`  | `[String]`         | 条件  | 当 `shareMethod = EMAIL` 时必填且不可为空。长度必须等于 `quantity`。其他情况下必须为空。                            |
| `recipientListPhone`  | `[String]`         | 条件  | 当 `shareMethod = PHONE_NUMBER` 时必填且不可为空。长度必须等于 `quantity`。其他情况下必须为空。                     |

<Note>
  **资金来源。** 目前唯一支持的资金来源是**消费账户**（`userCashBalanceId`），且必须属于你（发送方）的账户。其他资金来源（银行账户、银行卡、预付/奖励余额）尚未开放。
</Note>

### 投递方式（`shareMethod`）

| 值              | 行为                       | 收件人列表                                      |
| -------------- | ------------------------ | ------------------------------------------ |
| `GENERATE_URL` | Fluz 在响应中返回托管 URL。你自行分发。 | 两个列表都必须为空/省略。                              |
| `EMAIL`        | Fluz 向每位收件人发送电子邮件链接。     | 需要 `recipientListEmail`；长度必须等于 `quantity`。 |
| `PHONE_NUMBER` | Fluz 向每位收件人发送短信链接。       | 需要 `recipientListPhone`；长度必须等于 `quantity`。 |

### 校验规则

* `cardLimit` 必须为整数且不小于项目最低限额。
* `offerId` 必须是一个有效的 UUID v4，且对应**激活中的**优惠，其**商户可分享**。
* `quantity` 必须为整数。
* 当通过 `EMAIL` 或 `PHONE_NUMBER` 投递时，对应的收件人列表长度**必须等于** `quantity`。不匹配将返回明确错误，且**不会**创建任何记录。
* 只能提供一个资金来源。`userCashBalanceId` 必须为发送方账户拥有的有效 UUID v4。
* 无效的卡片类型或格式错误的输入将返回明确错误，且不会创建记录。

### 示例

<CodeGroup>
  ```json Generate URLs theme={null}
  {
    "input": {
      "cardLimit": 25,
      "offerId": "11111111-2222-3333-4444-555555555555",
      "daysUntilExpiration": 30,
      "quantity": 3,
      "shareMethod": "GENERATE_URL",
      "userCashBalanceId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
    }
  }
  ```

  ```json Email theme={null}
  {
    "input": {
      "cardLimit": 25,
      "offerId": "11111111-2222-3333-4444-555555555555",
      "daysUntilExpiration": 30,
      "quantity": 2,
      "shareMethod": "EMAIL",
      "recipientListEmail": ["recipient1@example.com", "recipient2@example.com"],
      "userCashBalanceId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
    }
  }
  ```

  ```json SMS theme={null}
  {
    "input": {
      "cardLimit": 25,
      "offerId": "11111111-2222-3333-4444-555555555555",
      "daysUntilExpiration": 30,
      "quantity": 2,
      "shareMethod": "PHONE_NUMBER",
      "recipientListPhone": ["+12125550101", "+12125550102"],
      "userCashBalanceId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
    }
  }
  ```
</CodeGroup>

### 响应

```json theme={null}
{
  "data": {
    "generateVCShareLinks": {
      "shareLinks": [
        "https://fluz.app/virtual-prepaid-card/3f8a...c1",
        "https://fluz.app/virtual-prepaid-card/9b2d...77",
        "https://fluz.app/virtual-prepaid-card/0c41...e3"
      ]
    }
  }
}
```

`shareLinks` 是一个托管 URL 数组，与 `quantity` 一一对应，格式为 `https://fluz.app/virtual-prepaid-card/{share_request_id}`。

<Tip>
  响应仅返回 URL。若要获取刚创建链接的**批次 ID**与**展示 ID**（用于列表查询与停用），请使用按状态过滤的 `getVCShareLinks`。
</Tip>

## getVCShareLinks

列出先前生成的分享链接，以便查看状态、收件人、到期时间以及已发放的卡片。

```graphql theme={null}
query GetVCShareLinks($input: GetVCShareLinksInput!) {
  getVCShareLinks(input: $input) {
    senderAppId
    shareRequestBatchId
    shareRequestDisplayId
    shareObjectStatus
    recipientPhone
    recipientEmail
    linkExpirationDate
    virtualCardId
    linkUrl
    shareRequestDetails {
      cardLimit
      offerId
      daysUntilExpiration
      quantity
      shareMethod
      recipientListEmail
      recipientListPhone
      userCashBalanceId
    }
  }
}
```

### 输入字段

| 字段                       | 类型                    | 说明                                         |
| ------------------------ | --------------------- | ------------------------------------------ |
| `shareObjectStatuses`    | `[ShareObjectStatus]` | 按状态过滤：`PENDING`、`ISSUED`、`USED`、`EXPIRED`。 |
| `shareRequestBatchIds`   | `[String]`            | 仅返回这些批次中的链接。                               |
| `shareRequestDisplayIds` | `[String]`            | 仅返回具有这些展示 ID 的链接。                          |

<Tip>
  **推荐流程。** 首次调用时仅按 `shareObjectStatuses` 过滤。响应会提供 `shareRequestBatchId` 与 `shareRequestDisplayId`；随后使用这些值进行精确过滤（以及执行停用）。
</Tip>

### 响应字段（`GeneratedShareLink`）

| 字段                      | 类型                    | 说明                                     |
| ----------------------- | --------------------- | -------------------------------------- |
| `senderAppId`           | `String`              | 生成该链接的应用/开发者应用标识。                      |
| `shareRequestBatchId`   | `String`              | 在一次调用中生成的所有链接共享的批次标识符。                 |
| `shareRequestDisplayId` | `String`              | 便于识别的人类可读单链接标识符。                       |
| `shareObjectStatus`     | `ShareObjectStatus`   | `PENDING`、`ISSUED`、`USED` 或 `EXPIRED`。 |
| `recipientEmail`        | `String`              | 若通过邮件投递，则为收件人邮箱。                       |
| `recipientPhone`        | `String`              | 若通过短信投递，则为收件人手机号。                      |
| `linkExpirationDate`    | `DateTime`            | 链接到期时间 / 卡片冻结时间。                       |
| `virtualCardId`         | `String`              | 领取后发放的虚拟卡 ID。                          |
| `linkUrl`               | `String`              | 链接的托管 URL。                             |
| `shareRequestDetails`   | `ShareRequestDetails` | 原始配置（卡片限额、优惠、数量、投递、资金）。                |

### 示例

<CodeGroup>
  ```json By status theme={null}
  { "input": { "shareObjectStatuses": ["PENDING", "ISSUED"] } }
  ```

  ```json By batch theme={null}
  { "input": { "shareRequestBatchIds": ["ABC123", "XYZ789"] } }
  ```

  ```json By display ID theme={null}
  { "input": { "shareRequestDisplayIds": ["SR-000001", "SR-000002"] } }
  ```
</CodeGroup>

## deactivateVCShareLinks

停用（使失效）你生成的链接——例如某个批次误发，或你需要撤销未被领取的链接。停用后，链接状态将被设为 `EXPIRED`；未领取的链接将无法再被领取。

```graphql theme={null}
mutation DeactivateVCShareLinks($input: DeactivateVCShareLinksInput!) {
  deactivateVCShareLinks(input: $input)
}
```

### 输入字段

| 字段                       | 类型         | 说明                |
| ------------------------ | ---------- | ----------------- |
| `shareRequestBatchIds`   | `[String]` | 停用这些批次中的每个链接。     |
| `shareRequestDisplayIds` | `[String]` | 仅停用具有这些展示 ID 的链接。 |

从 `getVCShareLinks` 获取批次 ID。

```json theme={null}
{ "input": { "shareRequestBatchIds": ["ABC123"] } }
```

返回一个人类可读的确认字符串，例如：`"3 share requests successfully deactivated!"`。

<Warning>
  如果收件人已**领取**某个链接（状态为 `ISSUED`/`USED`），停用该链接并不会回收已发放的卡片。若要停止已发放卡片的消费，请使用相关的卡片生命周期/冻结控制。
</Warning>

## 收件人体验

当收件人打开一个托管链接（`https://fluz.app/virtual-prepaid-card/{share_request_id}`）时：

<Steps>
  <Step title="进入页面并登录">
    收件人将看到带有发送方品牌的激活页面。他们通过 Fluz 身份门户登录（新用户在此完成注册）。
  </Step>

  <Step title="双因素认证">
    首次加载时，现有用户会进入 2FA 页面。完成 2FA 后才能查看或领取卡片。
  </Step>

  <Step title="账单地址（如需）">
    若收件人档案中没有账单地址，将提示其添加。*在线消费需要账单地址。*
  </Step>

  <Step title="设置 PIN（若尚未发放）">
    在卡片发放前，收件人需要设置 PIN。
  </Step>

  <Step title="卡片发放与领取">
    系统会创建一张一次性加载的虚拟卡并分配给收件人，资金来自发送方账户，锁定日期等于链接的到期日期。
  </Step>

  <Step title="使用卡片">
    一旦领取，收件人即可查看卡片详情、交易记录，并（在支持的情况下）将卡片添加至移动钱包。
  </Step>
</Steps>

<Note>
  **已被领取？** 如果同一用户再次打开他们已领取的链接，将看到其卡片详情。若\_不同\_用户打开已被他人领取的链接，则在完成 2FA 后会看到拒绝访问的页面。
</Note>

## 到期与冻结

链接的到期日期具有双重作用：

* **链接到期**——在此日期之后，**未被领取**的链接将无法再被领取。
* **卡片冻结/锁定日期**——对于已**发放**的卡片，这是其锁定日期（当天结束）。届时卡片将被冻结，无法消费。
* **卡片过期** 与冻结日期所在月份的月末对齐（例如，冻结日期为 2026/6/15，则卡片过期为 2026/6/30）。

在生成时通过 `daysUntilExpiration` 设置该窗口。若省略，则使用项目默认（30 天）。此日期会展示给收件人（通常作为“有效期至”日期）。

## 需要告知收件人的项目规则

以下为托管（开放式）虚拟卡的项目级规则。请与你的 Fluz 代表确认**你的**项目的具体取值——其中若干项由合作方协商确定。

| 规则        | 默认值             | 说明                            |
| --------- | --------------- | ----------------------------- |
| 账户日累计消费限额 | **\$250,000/天** | 部分合作方有自定义限额。                  |
| 餐厅交易缓冲    | **25%**         | 所有项目均适用 25% 缓冲（用于容纳餐厅小费/预授权）。 |
| 受限商户/类别   | 项目特定            | 某些商户类别受限。                     |
| 资金来源      | 发送方消费账户         | 卡片在领取时从发送方账户获得资金。             |

**收件人客服支持：** 1-888-360-6660 · [humans@fluz.app](mailto:humans@fluz.app)

<Note>
  完整的合作方参考资料（术语、带截图的收件人流程、资金说明、受限类别、支持信息）详见 **合作方指南 — 托管 URL 虚拟卡**。向你的 Fluz 联系人索取适用于你项目的最新版本。
</Note>

## 状态与错误参考

### 分享对象状态

| 状态        | 含义               |
| --------- | ---------------- |
| `PENDING` | 已生成链接，尚未被领取。     |
| `ISSUED`  | 收件人已领取；虚拟卡已发放。   |
| `USED`    | 已发放卡片已被使用。       |
| `EXPIRED` | 链接已到期或被停用；不可再领取。 |

### 面向收件人的链接错误

| 情况            | 收件人可见内容                           |
| ------------- | --------------------------------- |
| 在领取前已到期       | “Expired before issued”——链接不再可领取。 |
| 发送方提前停用链接     | “Frozen by sender”——链接在到期前已被撤销。   |
| 已发卡后超过锁定日期    | “Expired after issued”——卡片已冻结。    |
| 不同用户打开已被领取的链接 | “Access denied”。                  |

### 常见 API 错误

| 原因                                         | 结果               |
| ------------------------------------------ | ---------------- |
| 缺失/无效的 Bearer 令牌或缺少 `CREATE_SHARE_LINK` 范围 | 请求被拒绝（未授权）。      |
| 账户未开通发送卡片访问（`send_virtual_cards_enabled`）  | 权限错误，提示联系销售代表。   |
| 收件人列表长度 ≠ `quantity`                       | 明确的校验错误；不创建任何记录。 |
| 优惠未激活、商户不可分享或无效的 `offerId`                 | 校验错误；不创建任何记录。    |
| 缺失/无效的 `userCashBalanceId`，或提供了多个资金来源      | 校验错误；不创建任何记录。    |

## 备注与限制

* **返回的 URL 为托管目标地址，而非短链接。** 内部也会使用短链接服务包装，但 API 返回的是规范的托管 URL（`/virtual-prepaid-card/{share_request_id}`）。请按原样分发该 URL。
* 即使架构标记为可选，`userCashBalanceId` 在实际中是必填的。
* **隐藏/内部字段不属于本 API。** 对象类型与卡片类型固定为（`VIRTUAL_CARD` / `SINGLE_LOAD`），其他资金来源字段尚未启用；请勿传递。
* **不支持礼品卡托管链接。** 本 API 仅适用于虚拟卡。

## 后续步骤

<CardGroup cols={2}>
  <Card title="生成分享链接" icon="link" href="/features/generate-share-links">
    专注于 `generateVCShareLinks` 的精要参考，如果你只需要这个。
  </Card>

  <Card title="创建批量订单" icon="layers" href="/features/create-bulk-order">
    一次性发放多张卡，用于程序化分发。
  </Card>
</CardGroup>
