> ## 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 来创建一个或多个链接，然后通过电子邮件、短信，或你自己的分发流程将这些链接发送给收件人。收件人打开链接后，会进入由 Fluz 托管的激活页面，完成验证，并领取一张由你的账户出资的一次性充值虚拟卡。

<Info>
  **先决条件：** 一个带有 `CREATE_SHARE_LINK` 范围的 Bearer 访问令牌，以及已启用托管虚拟卡发送功能的账户。若你的账户未启用，该 API 将返回权限错误并指引你联系你的 Fluz 代表。
</Info>

<Note>
  **“托管”/“开放环”含义。** 托管链接会指向由 Fluz 托管的激活页面。开放环表示收件人领取的是网络虚拟卡，可依据你的项目规则在合格商户处使用。
</Note>

<Tip>
  需要完整功能说明——收件人流程、项目规则，以及完整的状态/错误参考？参见 [发送卡概览](/features/send-cards)。本页是针对三个分享链接操作的聚焦 API 参考。
</Tip>

## 工作原理

1. 你的平台调用 `generateVCShareLinks`，传入优惠、卡限额、数量、资金来源和交付方式。
2. Fluz 为每个请求的链接创建一个分享请求和一个托管 URL。
3. 交付方式取决于 `shareMethod`：
   * `GENERATE_URL`：Fluz 在 API 响应中返回托管 URL，由你自行分发。
   * `EMAIL`：Fluz 向每位收件人发送其链接邮件。
   * `PHONE_NUMBER`：Fluz 向每位收件人发送其链接短信。
4. 收件人打开托管链接，登录、完成验证并领取该卡。
5. Fluz 向收件人签发一次性充值虚拟卡，资金来自发送方账户。

## 认证

所有发送卡分享链接操作都使用 Fluz GraphQL API。

```http theme={null}
POST https://<your-fluz-api-host>/api/v1/graphql
Authorization: Bearer <access_token>
Content-Type: application/json
```

你的访问令牌必须包含 `CREATE_SHARE_LINK` 范围。

```json theme={null}
{
  "scopes": ["CREATE_SHARE_LINK"]
}
```

你的账户也必须启用托管虚拟卡发送功能。若未启用，API 将返回权限错误并指引你联系你的 Fluz 代表。

## 操作

| Operation                | Type     | Purpose         |
| ------------------------ | -------- | --------------- |
| `generateVCShareLinks`   | Mutation | 创建一个或多个托管虚拟卡链接。 |
| `getVCShareLinks`        | Query    | 列出并查看先前生成的链接。   |
| `deactivateVCShareLinks` | Mutation | 停用已生成的链接。       |

## generateVCShareLinks

创建 `quantity` 个托管分享链接。

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

### 输入字段

| Field                 | Type               | Required    | Description                                                            |
| :-------------------- | :----------------- | :---------- | :--------------------------------------------------------------------- |
| `cardLimit`           | `Int!`             | Yes         | 每张卡的消费限额和充值金额。必须为整数且符合项目最低限额。                                          |
| `offerId`             | `String!`          | Yes         | 虚拟卡优惠的 UUID v4。该优惠必须为激活状态且其商户可分享。                                      |
| `quantity`            | `Int!`             | Yes         | 要生成的链接数量。Fluz 为每个单位创建一个唯一托管 URL。                                       |
| `shareMethod`         | `ShareMethodType!` | Yes         | 交付方式：`GENERATE_URL`、`EMAIL` 或 `PHONE_NUMBER`。                          |
| `userCashBalanceId`   | `UUID`             | Yes         | 用于为卡提供资金的消费账户。尽管 GraphQL 架构可能显示为可选，此字段在实际中是必填的。                        |
| `daysUntilExpiration` | `Int`              | No          | 链接的有效天数。最少为 1。若省略，使用项目默认值。生成的到期日也会成为发卡后的卡片锁定/冻结日期。                     |
| `recipientListEmail`  | `[String]`         | Conditional | 当 `shareMethod` 为 `EMAIL` 时必填。长度必须等于 `quantity`。其他交付方式下必须省略或为空。        |
| `recipientListPhone`  | `[String]`         | Conditional | 当 `shareMethod` 为 `PHONE_NUMBER` 时必填。长度必须等于 `quantity`。其他交付方式下必须省略或为空。 |

### 交付方式

| `shareMethod`  | Behavior         | Recipient list rule                               |
| :------------- | :--------------- | :------------------------------------------------ |
| `GENERATE_URL` | 返回托管 URL 供你自行分发。 | 不要发送 `recipientListEmail` 或 `recipientListPhone`。 |
| `EMAIL`        | 向每位收件人发送一封电子邮件。  | 发送 `recipientListEmail`；长度必须等于 `quantity`。        |
| `PHONE_NUMBER` | 向每位收件人发送一条短信。    | 发送 `recipientListPhone`；长度必须等于 `quantity`。        |

### 校验规则

* `cardLimit` 必须为整数且符合项目最低限额。
* `offerId` 必须是处于激活且可分享优惠的有效 UUID v4。
* `quantity` 必须为整数。
* 使用 `EMAIL` 或 `PHONE_NUMBER` 时，收件人列表长度必须等于 `quantity`。
* `userCashBalanceId` 必须为发送方账户所拥有的有效消费账户。
* 不要包含多个资金来源。
* 无效或格式错误的请求将校验失败，且不会创建任何分享链接。

### 示例：生成 URL 以供你自行分发

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

```json 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 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 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"
  }
}
```

### 响应

```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。

```text theme={null}
https://fluz.app/virtual-prepaid-card/{share_request_id}
```

API 返回托管目标 URL。若 Fluz 还在内部创建了短链接包装，该短链接不会由此 API 返回。

## getVCShareLinks

使用 `getVCShareLinks` 列出已生成的链接，获取批次和展示 ID，查看交付目标并检查状态。

```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
    }
  }
}
```

### 输入字段

| Field                    | Type                  | Description                                  |
| :----------------------- | :-------------------- | :------------------------------------------- |
| `shareObjectStatuses`    | `[ShareObjectStatus]` | 按状态筛选：`PENDING`、`ISSUED`、`USED` 或 `EXPIRED`。 |
| `shareRequestBatchIds`   | `[String]`            | 仅返回这些批次中的链接。                                 |
| `shareRequestDisplayIds` | `[String]`            | 仅返回具有这些展示 ID 的链接。                            |

首次查询时，可按 `shareObjectStatuses` 筛选。响应包含 `shareRequestBatchId` 和 `shareRequestDisplayId`，你可用于后续查询或停用操作。

### 示例

```json theme={null}
{
  "input": {
    "shareObjectStatuses": ["PENDING", "ISSUED"]
  }
}
```

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

```json theme={null}
{
  "input": {
    "shareRequestDisplayIds": ["SR-000001", "SR-000002"]
  }
}
```

### 响应字段

| Field                   | Type                  | Description            |
| :---------------------- | :-------------------- | :--------------------- |
| `senderAppId`           | `String`              | 生成该链接的应用程序。            |
| `shareRequestBatchId`   | `String`              | 与同一生成请求中创建的链接共享的批次 ID。 |
| `shareRequestDisplayId` | `String`              | 单个分享请求的人性化展示 ID。       |
| `shareObjectStatus`     | `ShareObjectStatus`   | 分享请求的当前状态。             |
| `recipientEmail`        | `String`              | 通过电子邮件交付时的收件人邮箱。       |
| `recipientPhone`        | `String`              | 通过短信交付时的收件人手机号。        |
| `linkExpirationDate`    | `DateTime`            | 链接到期日及卡片锁定/冻结日期。       |
| `virtualCardId`         | `String`              | 链接被领取后签发的虚拟卡 ID。       |
| `linkUrl`               | `String`              | 分享请求的托管 URL。           |
| `shareRequestDetails`   | `ShareRequestDetails` | 原始生成设置。                |

## deactivateVCShareLinks

使用 `deactivateVCShareLinks` 使已生成的链接过期，例如当批次误发或需要撤销未被领取的链接时。

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

### 输入字段

| Field                    | Type       | Description       |
| :----------------------- | :--------- | :---------------- |
| `shareRequestBatchIds`   | `[String]` | 停用这些批次中的所有链接。     |
| `shareRequestDisplayIds` | `[String]` | 仅停用具有这些展示 ID 的链接。 |

### 示例

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

### 响应

返回一个确认字符串，例如：

```text theme={null}
3 share requests successfully deactivated!
```

停用链接可防止未被领取的链接被继续领取。若卡片已被签发，请使用相应的卡片生命周期控制来管理该卡。

## 收件人激活体验

当收件人打开托管链接时，会进入由 Fluz 托管的激活页面。

1. 收件人打开托管虚拟卡链接。
2. 收件人通过 Fluz 认证流程登录或创建账户。
3. 现有用户在查看或领取卡片前需完成双重验证（2FA）。
4. 若收件人尚未保存账单地址，会提示其添加。线上消费需要账单地址。
5. 若该卡尚未签发，收件人需设置 PIN。
6. Fluz 向收件人签发虚拟卡。
7. 签发后，收件人即可查看卡片详情与活动。

如果同一用户打开其已领取的链接，他们可以查看卡片详情。若不同用户打开已被他人领取的链接，则在完成认证后会显示拒绝访问状态。

## 到期与卡片冻结

`daysUntilExpiration` 决定托管链接的有效期。

生成的到期日用于两种相关行为：

* 领取前：到期日之后，链接不再可被领取。
* 领取后：到期日成为卡片的锁定/冻结日期。该日期之后，已签发的卡将被冻结且不可再消费。

如果省略 `daysUntilExpiration`，将使用项目默认值。

## 项目规则

项目规则可能因合作伙伴而异。请与你的 Fluz 代表确认你项目的最终取值。

| Rule                            | Default / behavior                                          |
| :------------------------------ | :---------------------------------------------------------- |
| Funding source                  | 发送方的消费账户。                                                   |
| Daily account spend limit       | 每日 \$250,000，除非你的项目有自定义上限。                                  |
| Restaurant transaction buffer   | 餐厅交易适用 25% 缓冲。                                              |
| Restricted merchants/categories | 可能适用项目特定限制。                                                 |
| Recipient support               | 1-888-360-6660 或 [humans@fluz.app](mailto:humans@fluz.app)。 |

## 状态参考

| Status    | Meaning          |
| :-------- | :--------------- |
| `PENDING` | 链接已生成且尚未被领取。     |
| `ISSUED`  | 收件人已领取链接并已签发虚拟卡。 |
| `USED`    | 已签发的卡已被使用。       |
| `EXPIRED` | 链接已过期或已被停用。      |

## 常见错误

| Cause                      | Result         |
| :------------------------- | :------------- |
| 缺少或无效的 Bearer 令牌           | 请求被拒绝。         |
| 缺少 `CREATE_SHARE_LINK` 范围  | 请求被拒绝。         |
| 账户未启用托管卡发送                 | 权限错误。          |
| 收件人列表长度不等于 `quantity`      | 校验错误；不会创建任何链接。 |
| 不活跃或不可分享的优惠                | 校验错误；不会创建任何链接。 |
| 缺少或无效的 `userCashBalanceId` | 校验错误；不会创建任何链接。 |
| 提供了多个资金来源                  | 校验错误；不会创建任何链接。 |

## 备注与限制

* 此 API 仅适用于托管虚拟卡。不支持托管礼品卡链接。
* API 返回托管目标 URL，而非短链接。
* `userCashBalanceId` 在实践中是必填项。
* 本阶段对象类型和卡类型是固定的，不应在公共 API 请求中提供。

<Warning>
  **发送前须知：**

  * 若收件人在领取卡片时你的资金来源余额不足，发卡将失败。请确保余额充足。
  * `recipientListPhone` 中的电话号码必须为无空格的字符串，并且必须在开头包含国家代码——例如 `+18883606660`，其中 `+1` 为国家代码。
</Warning>

## 后续步骤

<CardGroup cols={2}>
  <Card title="发送卡概览" icon="send" href="/features/send-cards">
    完整功能说明——收件人流程、项目规则与完整错误参考。
  </Card>

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