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

# 客户阻止列表

> 阻止某位客户，以阻止其未来再次结账、取消其有效订阅，并将其 Customer Portal 设为只读。可从 Settings 或 API 管理阻止列表。

<Info>
  客户阻止列表可阻止已知的不良行为者再次向您购买。被阻止的客户无法付款，其有效订阅会被取消，并且只能在 [Customer Portal](/features/customer-portal) 中查看内容，无法进行任何更改。可从 **Settings → Blocklist** 或通过 Blocklist API 进行管理。
</Info>

<Frame caption="The Blocklist tab under Settings">
  <img src="https://mintcdn.com/dodopayments/c1t35qHSH45TR4GO/images/blocklist/blocklist-settings.png?fit=max&auto=format&n=c1t35qHSH45TR4GO&q=85&s=771eb4a5654fbd22e6a5110cfb1a2e9d" alt="显示被阻止客户总数、包含标识符、阻止者和阻止时间列的被阻止条目表格，以及 Add to Blocklist 按钮的阻止列表设置页面" style={{ maxHeight: '500px', width: 'auto' }} width="2358" height="1554" data-path="images/blocklist/blocklist-settings.png" />
</Frame>

## 阻止客户后会发生什么

| 区域                  | 影响                                                                                                                              |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| **结账**              | 来自被阻止邮箱的所有付款尝试都会被拒绝：包括付款链接、结账会话，以及通过 API 创建的付款或订阅。                                                                              |
| **有效订阅**            | 状态为 `pending`、`active`、`on_hold` 或 `paused` 的订阅会被取消，原因设为 `cancelled_by_merchant`。通常的 `subscription.cancelled` webhook 会为每个订阅触发。 |
| **续订和重试**           | 自动续订和[付款重试](/features/recovery/payment-retries)会跳过被阻止的客户，因此不会产生后续扣款，即使取消仍处于待处理状态。                                               |
| **手动重试**            | 对被阻止客户的付款执行[手动重试](/features/recovery/manual-retry)会被拒绝。                                                                         |
| **Customer Portal** | 客户仍可登录并查看发票、订阅和许可证密钥，但无法取消、暂停或恢复订阅，无法更改方案，也无法更新付款方式。移除已保存的付款方式仍然允许。                                                             |

<Note>
  阻止客户不会退还过去的付款，也不会影响未结争议。如需退款，请从 [Refunds](/features/transactions/refunds) 页面单独发起。
</Note>

## 阻止如何匹配客户

您可以按**客户 ID**或**邮箱**进行阻止。无论使用哪种方式，阻止依据的都是客户邮箱，而不是客户记录：

* **该邮箱对应的每条记录都会受到影响。** 回访邮箱进行结账时可能会创建新的客户记录，因此仅阻止单个客户 ID 可能被绕过，而按邮箱阻止则无法绕过。
* **别名也会受到影响。** 系统会以小写形式比较邮箱，并移除其中的 `+alias`，因此 `buyer+promo@example.com` 和 `Buyer@example.com` 会被视为同一客户。邮箱地址中的点会按原样保留。
* **仅限您的业务。** 阻止仅适用于您的业务。同一邮箱仍可在 Dodo Payments 的其他业务中购买。
* **邮箱必须属于现有客户。** 您无法阻止从未在您这里结账的邮箱，也无法阻止没有邮箱的客户记录。

## 阻止客户

<Tabs>
  <Tab title="From Settings">
    <Steps>
      <Step title="Open the Blocklist">
        前往控制面板中的 **Settings → Blocklist**。
      </Step>

      <Step title="Add to Blocklist">
        点击 **Add to Blocklist**，然后输入客户的邮箱或客户 ID。添加原因，以便团队之后了解添加阻止的原因。
      </Step>

      <Step title="Confirm">
        确认阻止。客户的有效订阅会立即取消，该条目会出现在 **Blocked entries** 表格中。
      </Step>
    </Steps>
  </Tab>

  <Tab title="From the customer's page">
    <Steps>
      <Step title="Open the customer">
        前往 **Sales → Customers**，打开要阻止的客户。
      </Step>

      <Step title="Block the customer">
        点击 **Block Customer**。阻止生效后，页面会在客户姓名旁显示 **Blocked** 徽章。
      </Step>
    </Steps>
  </Tab>
</Tabs>

## 管理被阻止的客户

**Blocklist** 页面会列出所有有效的阻止记录：

* **Total Customers Blocked**：当前被阻止的客户数量。
* **Blocked entries**：每条阻止记录占一行，其中包含您输入的**标识符**（邮箱或客户 ID）、**Blocked By**（添加阻止的团队成员）和 **Blocked On**。
* **Search Identifier** 和 **Filters**：按邮箱或客户 ID 查找记录，或按阻止者和阻止时间进行筛选。
* **Action**：管理记录，包括解除对客户的阻止。

### 被阻止客户的页面

<Frame caption="A blocked customer's details page">
  <img src="https://mintcdn.com/dodopayments/c1t35qHSH45TR4GO/images/blocklist/blocked-customer-details.png?fit=max&auto=format&n=c1t35qHSH45TR4GO&q=85&s=83e1225a8e71c003d2bf660f0eea9c08" alt="被阻止客户的 Customer Information 页面，显示 Blocked 徽章、Unblock Customer 按钮、包含备注和 Added to blocklist 事件的 Activity Log，以及显示客户 ID 的 Reference IDs 面板" style={{ maxHeight: '500px', width: 'auto' }} width="2366" height="1554" data-path="images/blocklist/blocked-customer-details.png" />
</Frame>

从 **Sales → Customers** 或 Blocklist 页面打开被阻止的客户，即可查看：

* 客户姓名旁的 **Blocked** 徽章，以及 **Unblock Customer** 按钮。
* **Activity Log**：客户被添加到阻止列表的时间、原因，以及团队之后添加的任何备注。点击 **Add Note** 记录新的背景信息，例如拒付处理结果。备注之后可以编辑。
* **Reference IDs**：与此阻止记录关联的客户 ID，可直接复制。

## 解除对客户的阻止

在客户页面点击 **Unblock Customer**，或使用 Blocklist 页面上的操作菜单。

* 结账和 Customer Portal 中的更改会立即恢复。
* **已取消的订阅不会重新激活。** 客户必须重新购买。
* 该记录会作为审计记录及其备注保留，但不再显示在有效列表中。
* 之后可以再次阻止同一客户，这会创建一条新记录。

## 客户看到的内容

被阻止的客户永远不会被告知自己已被阻止。

* **在结账时**，付款会以通用拒付信息失败："This payment cannot be processed." API 会返回 HTTP `403` 和错误代码 `PAYMENT_NOT_PERMITTED`，其中不包含任何原因。实际原因只会写入 Dodo Payments 的日志。
* **在 Customer Portal 中**，所有内容都可见，但所有操作都会被禁用。被阻止的写入操作会返回 `PORTAL_ACTION_NOT_PERMITTED`，并显示消息 "This action is not available." Portal 配置文件会携带 `read_only: true`，以便自定义 portal 集成禁用自身的控件。Portal 不会暴露阻止列表记录或其中的备注。

<Warning>
  如果您在自己的产品中呈现结账或 portal 错误，请保持此行为。对于 `PAYMENT_NOT_PERMITTED` 和 `PORTAL_ACTION_NOT_PERMITTED`，显示通用消息。暴露阻止信息会告诉不良行为者尝试使用其他邮箱。
</Warning>

## 使用 API

Blocklist API 允许您从自己的工具中执行阻止操作，例如收到拒付时。它需要您的私有 [API key](/api-reference/introduction)。任何密钥都可以列出记录并读取备注。启用**写入权限**的密钥可以执行阻止、解除阻止和管理备注。控制面板对团队角色采用相同的权限划分：**Viewer** 角色可以读取列表，**Editor** 角色可以进行更改。

| Method   | Endpoint                                          | Purpose                   |
| -------- | ------------------------------------------------- | ------------------------- |
| `GET`    | `/blocklist/customers`                            | 列出被阻止的客户，支持筛选和 `total` 计数 |
| `POST`   | `/blocklist/customers`                            | 按客户 ID 或邮箱阻止客户            |
| `GET`    | `/blocklist/customers/{entry_id}`                 | 获取一条记录及其备注                |
| `DELETE` | `/blocklist/customers/{entry_id}`                 | 解除对客户的阻止                  |
| `POST`   | `/blocklist/customers/{entry_id}/notes`           | 添加备注                      |
| `PATCH`  | `/blocklist/customers/{entry_id}/notes/{note_id}` | 更新备注                      |

### 阻止客户

在请求正文的顶层发送 `customer_id` 或 `email`。`reason` 为可选字段，会显示在记录页面中。

<CodeGroup>
  ```typescript Node.js theme={null}
  import DodoPayments from 'dodopayments';

  const client = new DodoPayments({
    bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  });

  // Block by customer ID
  const entry = await client.blocklist.customers.create({
    customer_id: 'cus_0NmichXWP8JYBB9Dw1Unj',
    reason: 'Chargeback on pay_0NmichXuYoNoapmr',
  });

  // Or block by email
  const byEmail = await client.blocklist.customers.create({
    email: 'buyer@example.com',
    reason: 'Repeated refund abuse',
  });

  console.log(entry.id, entry.cancelled_subscription_ids);
  ```

  ```python Python theme={null}
  import os
  from dodopayments import DodoPayments

  client = DodoPayments(bearer_token=os.environ["DODO_PAYMENTS_API_KEY"])

  # Block by customer ID
  entry = client.blocklist.customers.create(
      customer_id="cus_0NmichXWP8JYBB9Dw1Unj",
      reason="Chargeback on pay_0NmichXuYoNoapmr",
  )

  # Or block by email
  by_email = client.blocklist.customers.create(
      email="buyer@example.com",
      reason="Repeated refund abuse",
  )

  print(entry.id, entry.cancelled_subscription_ids)
  ```

  ```bash cURL theme={null}
  curl -X POST https://live.dodopayments.com/blocklist/customers \
    -H "Authorization: Bearer $DODO_PAYMENTS_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "customer_id": "cus_0NmichXWP8JYBB9Dw1Unj",
      "reason": "Chargeback on pay_0NmichXuYoNoapmr"
    }'
  ```
</CodeGroup>

```json Response theme={null}
{
  "id": "bcu_7Hq2mV9kRt4LxYw3Pz",
  "customer_id": "cus_0NmichXWP8JYBB9Dw1Unj",
  "customer_name": "wow guy",
  "customer_email": "wowguy@example.com",
  "identifier": "cus_0NmichXWP8JYBB9Dw1Unj",
  "reason": "Chargeback on pay_0NmichXuYoNoapmr",
  "source": "api",
  "blocked_by_email": null,
  "created_at": "2026-09-02T12:09:41Z",
  "unblocked_at": null,
  "cancelled_subscription_ids": ["sub_3Fk8pW2nQs6MzXc1"],
  "subscriptions_swept": true
}
```

| Field                        | Description                                                                                     |
| ---------------------------- | ----------------------------------------------------------------------------------------------- |
| `identifier`                 | 您发送的客户 ID 或邮箱。                                                                                  |
| `source`                     | 阻止的来源：`blocklist_page`、`customer_page`、`payment_page`、`dispute_page` 或 `api`。API 密钥始终记录为 `api`。 |
| `blocked_by_email`           | 添加阻止的控制面板用户。对于 API 密钥，则为 `null`。                                                                |
| `cancelled_subscription_ids` | 此调用取消的订阅。                                                                                       |
| `remaining_subscription_ids` | 仍处于有效状态的订阅，原因是取消失败或调用已达到 25 次取消的上限。                                                             |
| `subscriptions_swept`        | 当仍有有效订阅时为 `false`。重复调用，直到其变为 `true`。阻止本身已经生效。                                                   |

<Note>
  阻止已经被阻止的客户会返回 HTTP `409` 和 `CUSTOMER_ALREADY_BLOCKED`，除非仍有订阅等待取消。在这种情况下，该调用会继续执行取消操作。
</Note>

### 检查客户是否已被阻止

[Get Customer Detail](/api-reference/customers/get-customers-1) 会返回两个额外字段：`blocked_at`，即有效阻止的添加时间（如果客户未被阻止，则为 `null`）；以及 `blocklist_entry_id`，即对应的记录。[List Customers](/api-reference/customers/get-customers) 端点会将这两个字段留空。

### 解除对客户的阻止

<CodeGroup>
  ```typescript Node.js theme={null}
  await client.blocklist.customers.delete('bcu_7Hq2mV9kRt4LxYw3Pz');
  ```

  ```python Python theme={null}
  client.blocklist.customers.delete("bcu_7Hq2mV9kRt4LxYw3Pz")
  ```

  ```bash cURL theme={null}
  curl -X DELETE https://live.dodopayments.com/blocklist/customers/bcu_7Hq2mV9kRt4LxYw3Pz \
    -H "Authorization: Bearer $DODO_PAYMENTS_API_KEY"
  ```
</CodeGroup>

端点成功时返回 HTTP `204`。解除阻止会恢复结账和 portal 写入操作，但不会重新激活任何订阅。

## 最佳实践

* **记录原因。** 在阻止记录中填写简短原因，并为之后发生的任何事项添加备注，可让支持团队无需离开控制面板即可了解完整情况。
* **在发生拒付后进行阻止。** 从争议或付款记录中打开客户并在那里阻止，或者通过 `dispute.opened` webhook 和 `POST /blocklist/customers` 自动执行。请参阅[争议](/features/transactions/disputes)。
* **检查 `subscriptions_swept`。** 通过 API 阻止客户时，重复调用，直到响应报告 `true`，确保不会遗留有效订阅。
* **单独退款。** 阻止只会停止未来购买。如果您需要向客户退款，请像往常一样退还付款。
* **定期查看列表。** 对问题已解决的客户解除阻止。解除阻止会立即生效，同时保留历史记录。

## 相关内容

<CardGroup cols={2}>
  <Card title="Customer Management" icon="user-group" href="/features/customers">
    查找客户，打开其详情页面，并管理其订阅。
  </Card>

  <Card title="Customer Portal" icon="id-card" href="/features/customer-portal">
    被阻止的客户在 portal 中可以和不可以执行的操作。
  </Card>

  <Card title="Disputes" icon="circle-exclamation" href="/features/transactions/disputes">
    处理拒付，并判断何时需要阻止客户。
  </Card>

  <Card title="Error Codes" icon="triangle-exclamation" href="/api-reference/error-codes">
    `PAYMENT_NOT_PERMITTED` 和 `PORTAL_ACTION_NOT_PERMITTED` 的含义。
  </Card>
</CardGroup>
