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

# Ramps

> 了解加密货币转换的 on-ramps 和 off-ramps

## 什么是 Ramp？

**Ramp** 是在法币和加密货币之间转换的交易。KillB 支持\*\* on-ramps\*\*（法币 → 加密货币）和\*\* off-ramps\*\*（加密货币 → 法币）。

<Info>
  将 ramps 视为传统银行和加密货币之间的桥梁。它们处理从报价到结算的整个转换过程。
</Info>

## Ramp 类型

<Tabs>
  <Tab title="On-Ramp">
    **法币 → 加密货币**

    将本地货币（COP、MXN、USD）转换为稳定币（USDC、USDT）。

    **流程：**

    1. 用户获取报价（例如，100,000 COP → 23.8 USDC）
    2. 用户使用钱包地址创建 ramp
    3. 用户通过 PSE/SPEI/ACH 支付
    4. KillB 处理转换
    5. USDC/USDT 发送到用户钱包

    **常见用例：**

    * 使用本地货币购买加密货币
    * 为 DeFi 头寸提供资金
    * 跨境汇款
    * 加密货币投资

    ```mermaid theme={null}
    graph LR
        A[用户银行账户] -->|COP/MXN/USD| B[KillB]
        B -->|转换| C[加密货币]
        C -->|USDC/USDT| D[用户钱包]
    ```
  </Tab>

  <Tab title="Off-Ramp">
    **加密货币 → 法币**

    将稳定币（USDC、USDT）转换回本地货币（COP、MXN、USD）。

    **流程：**

    1. 用户获取报价（例如，100 USDC → 420,000 COP）
    2. 用户使用银行账户创建 ramp
    3. 用户将 USDC/USDT 发送到提供的地址
    4. KillB 处理转换
    5. COP/MXN/USD 发送到用户银行

    **常见用例：**

    * 兑现加密货币持有
    * 支付本地费用
    * 加密货币工资支付
    * 业务结算

    ```mermaid theme={null}
    graph LR
        A[用户钱包] -->|USDC/USDT| B[KillB]
        B -->|转换| C[法币]
        C -->|COP/MXN/USD| D[用户银行账户]
    ```
  </Tab>
</Tabs>

## Ramp 生命周期

Ramp 在处理过程中经历多个状态阶段：

```mermaid theme={null}
graph TD
    A[CREATED] --> B[CASH_IN_REQUEST]
    B --> C[CASH_IN_PROCESSING]
    C --> D[CASH_IN_COMPLETED]
    D --> E[CONVERSION_PROCESSING]
    E --> F[CONVERSION_COMPLETED]
    F --> G[CASH_OUT_PROCESSING]
    G --> H[CASH_OUT_COMPLETED]
    H --> I[COMPLETED]
    
    B -.-> J[FAILED]
    C -.-> J
    E -.-> J
    G -.-> J
    
    A -.-> K[CANCELED]
    B -.-> K
```

## Ramp 状态

<AccordionGroup>
  <Accordion title="处理状态" icon="spinner" defaultOpen>
    **CREATED**

    * Ramp 已初始化，等待支付
    * 已向用户提供支付说明

    **CASH\_IN\_REQUEST / CASH\_IN\_REQUESTED**

    * 支付请求已发送给提供商
    * 等待用户支付

    **CASH\_IN\_PROCESSING**

    * 已收到支付，正在验证
    * 确认进行中

    **CASH\_IN\_COMPLETED**

    * 支付已确认
    * 准备转换

    **CONVERSION\_PROCESSING**

    * 正在转换法币 ↔ 加密货币
    * 执行交易

    **CONVERSION\_COMPLETED**

    * 转换完成
    * 准备支付

    **CASH\_OUT\_PROCESSING**

    * 正在向目的地发送资金
    * 交易进行中

    **CASH\_OUT\_COMPLETED**

    * 资金已发送到目的地
    * 等待最终确认
  </Accordion>

  <Accordion title="最终状态" icon="flag-checkered">
    **COMPLETED** ✅

    * 交易完全完成
    * 资金已交付给用户
    * 收据可用

    **FAILED** ❌

    * 交易在某个阶段失败
    * 检查 `details` 字段了解原因
    * 可能有资格重试

    **CANCELED** 🚫

    * 由用户或系统取消
    * 未转移资金
    * 如果适用，已启动退款

    **REJECTED** ⛔

    * 被合规或提供商拒绝
    * 检查 `note` 了解详情
    * 可能需要额外验证

    **ERROR** ⚠️

    * 发生系统错误
    * 使用 ramp ID 联系支持
    * 将进行调查和解决
  </Accordion>
</AccordionGroup>

## 创建 Ramp

### 先决条件

在创建 ramp 之前，您需要：

<Steps>
  <Step title="用户">
    具有适当 KYC 级别的已验证用户
  </Step>

  <Step title="账户">
    作为目的地的活动账户（银行或钱包）
  </Step>

  <Step title="报价">
    有效、未过期的报价
  </Step>
</Steps>

### 基本 Ramp 创建

```bash theme={null}
POST /api/v2/ramps
```

**请求：**

```json theme={null}
{
  "quotationId": "quot-9f8e7d6c-5b4a-3c2d-1e0f",
  "userId": "4d23aa52-1b40-4584-a8ea-58aba6099c5c",
  "accountId": "7c8b9a3d-2f1e-4b5c-9d8e-1a2b3c4d5e6f"
}
```

**响应：**

```json theme={null}
{
  "id": "ramp-1a2b3c4d-5e6f-7g8h-9i0j",
  "status": "CREATED",
  "type": "ON",
  "fromCurrency": "COP",
  "toCurrency": "USDC",
  "fromAmount": 100000,
  "toAmount": 23.81,
  "cashInMethod": "PSE",
  "cashOutMethod": "POLYGON",
  "paymentInfo": [{
    "url": "https://checkout.pse.com.co/payment/123456"
  }],
  "isPreFunded": false,
  "externalId": null,
  "createdAt": "2024-01-15T10:30:00.000Z"
}
```

## 多个目的地账户

您可以将 ramp 拆分到多个目的地账户：

```json theme={null}
{
  "quotationId": "quot-id",
  "userId": "user-id",
  "accounts": [
    {
      "id": "account-1",
      "amount": 50
    },
    {
      "id": "account-2",
      "amount": 50
    }
  ]
}
```

<Tip>
  对于拆分支付、跨钱包多样化或管理多个受益人很有用。
</Tip>

## 支付信息

根据支付方式，返回不同的支付信息：

<Tabs>
  <Tab title="PSE（哥伦比亚）">
    ```json theme={null}
    {
      "paymentInfo": [{
        "url": "https://checkout.pse.com.co/payment/abc123"
      }]
    }
    ```

    * 将用户重定向到 `url`
    * 用户通过 PSE 完成支付
    * Webhook 通知支付完成
  </Tab>

  <Tab title="SPEI（墨西哥）">
    ```json theme={null}
    {
      "paymentInfo": [{
        "network": "SPEI",
        "Bank": "BBVA",
        "Beneficiary": "KillB SA de CV",
        "CLABE": "012345678901234567",
        "concepto": "REF123ABC"
      }]
    }
    ```

    * 用户启动向 CLABE 的 SPEI 转账
    * 必须包含 `concepto` 作为参考
    * KillB 通过参考匹配支付
  </Tab>

  <Tab title="加密货币钱包">
    ```json theme={null}
    {
      "paymentInfo": [{
        "network": "POLYGON",
        "address": "0x123..."
      }]
    }
    ```

    * 用户将加密货币发送到提供的地址
    * KillB 通过区块链检测存款
    * 在网络确认后确认交易
  </Tab>
</Tabs>

## 退款说明

对于 on-ramps，在失败情况下提供退款说明：

```json theme={null}
{
  "quotationId": "quot-id",
  "userId": "user-id",
  "accountId": "account-id",
  "refundInstructions": {
    "clabe": "012345678901234567",
    "beneficiary": "Juan García"
  }
}
```

<Warning>
  退款说明必须与现金入账方法匹配（SPEI 需要 CLABE，加密货币需要钱包地址）。
</Warning>

## 外部 ID

使用 `externalId` 防止重复 ramps 并跟踪交易：

```json theme={null}
{
  "quotationId": "quot-id",
  "userId": "user-id",
  "accountId": "account-id",
  "externalId": "order-12345-from-my-system"
}
```

**优势：**

* 防止重复提交
* 在您的系统中跟踪 ramps
* 重试的幂等性
* 更容易对账

## 监控 Ramps

### 按 ID 获取 Ramp

```bash theme={null}
GET /api/v2/ramps/{rampId}
```

### 查询 Ramps

```bash theme={null}
GET /api/v2/ramps?userId=user-id&status=PROCESSING
```

**过滤选项：**

* `id` - 特定 ramp ID
* `externalId` - 您的系统 ID
* `status` - 按状态过滤
* `limit`、`page` - 分页

### 状态历史

跟踪所有状态更改：

```bash theme={null}
GET /api/v2/ramps/{rampId}/status-history
```

返回所有状态转换的时间顺序列表。

## Ramp 收据

以多种格式获取交易收据：

<Tabs>
  <Tab title="HTML 收据">
    ```bash theme={null}
    GET /api/v2/ramps/{rampId}/receipt
    ```

    返回适合在浏览器或电子邮件中显示的 HTML 收据。
  </Tab>

  <Tab title="JSON 收据">
    ```bash theme={null}
    GET /api/v2/ramps/{rampId}/receipt-json
    ```

    返回包含所有交易详情的结构化 JSON。
  </Tab>

  <Tab title="PDF 收据">
    ```bash theme={null}
    GET /api/v2/ramps/{rampId}/receipt/file
    ```

    返回可下载的 PDF 收据。
  </Tab>
</Tabs>

## 预充值 Ramps

预充值 ramps 即时执行：

```json theme={null}
{
  "quotationId": "quot-id",
  "userId": "user-id",
  "accountId": "account-id"
}
```

当报价使用 `PRE_FUND` 或 `PRE_FUND_*` 方法时：

* 不需要支付确认
* 即时执行
* 立即状态进展
* 更快的完成（分钟而不是小时）

**状态流程：**
`CREATED` → `CONVERSION_PROCESSING` → `CASH_OUT_PROCESSING` → `COMPLETED`

## 处理失败

### 常见失败原因

| 原因                   | 描述      | 解决方案      |
| -------------------- | ------- | --------- |
| `INSUFFICIENT_FUNDS` | 来源余额不足  | 用户需要为账户充值 |
| `INVALID_ACCOUNT`    | 目的地账户无效 | 验证账户详情    |
| `COMPLIANCE_HOLD`    | 需要合规审查  | 等待人工审查    |
| `PROVIDER_ERROR`     | 外部提供商问题 | 重试或联系支持   |
| `EXPIRED_QUOTE`      | 报价已过期   | 创建新报价     |

### 检查失败详情

```json theme={null}
{
  "id": "ramp-id",
  "status": "FAILED",
  "details": "INSUFFICIENT_FUNDS: Not enough balance in pre-fund account",
  "transferProof": null
}
```

<Card title="错误处理指南" icon="triangle-exclamation" href="/zh/resources/error-handling">
  了解处理 ramp 失败的最佳实践
</Card>

## Ramps 的 Webhooks

订阅 ramp 事件以获取实时更新：

**事件类型：** `RAMP`

**操作：**

* `CREATE` - Ramp 已初始化
* `UPDATE` - Ramp 状态已更改（包括所有状态转换）
* `DELETE` - Ramp 已取消（罕见）

**常见状态更新：**

* 已收到支付（`CASH_IN_COMPLETED`）
* 转换完成（`CONVERSION_COMPLETED`）
* Ramp 完全完成（`COMPLETED`）
* Ramp 失败（`FAILED`）
* Ramp 已取消（`CANCELED`）

```json Webhook Payload Example theme={null}
{
  "id": "evt_a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
  "event": "RAMP",
  "action": "UPDATE",
  "data": {
    "id": "be4d353b-00a2-4309-9ef1-594f37dfb1fd",
    "userId": "2bc703f2-1c54-4cbb-a144-993e1d957688",
    "accountId": "f7df00af-5d12-4b33-b5ab-e2b32290ebad",
    "quotationId": "a656a475-0d53-479e-8f30-91582ecf450b",
    "type": "ON",
    "status": "COMPLETED",
    "cashInMethod": "PSE",
    "cashOutMethod": "POLYGON",
    "fromCurrency": "COP",
    "toCurrency": "USDC",
    "fromAmount": 100000,
    "toAmount": 23.81,
    "transferProof": "0x8e2b1f4645ebc8b6f658c860980567a63d283a42735be7401a7950306a2539b0",
    "isPreFunded": false,
    "active": true,
    "accounts": [
      {
        "id": "f7df00af-5d12-4b33-b5ab-e2b32290ebad",
        "amount": 23.81
      }
    ],
    "createdAt": "2025-01-15T23:46:10.226Z",
    "updatedAt": "2025-01-16T00:29:06.813Z"
  },
  "createdAt": "2025-01-16T00:29:06.813Z",
  "updatedAt": "2025-01-16T00:29:06.813Z",
  "attempts": 0
}
```

<Tip>
  您将收到每个状态更改的 webhook 事件。按 `data.status` 过滤以处理特定转换，如 `COMPLETED` 或 `FAILED`。
</Tip>

## Ramp 更新

更新 ramp 信息（有限场景）：

```bash theme={null}
PATCH /api/v2/ramps/{rampId}
```

**可更新：**

* 目的地账户（支付前）
* 账户金额分配

<Warning>
  收到支付后无法修改 ramps。
</Warning>

## 性能考虑

### 交易时间

| 方法               | 典型时间     | 网络依赖   |
| ---------------- | -------- | ------ |
| PSE              | 5-30 分钟  | ✅ 是    |
| SPEI             | 10-60 分钟 | ✅ 是    |
| ACH              | 1-3 个工作日 | ✅ 是    |
| Wire             | 1 个工作日   | ✅ 是    |
| Crypto (Polygon) | 2-5 分钟   | ⛓️ 区块链 |
| Crypto (Solana)  | 1-2 分钟   | ⛓️ 区块链 |
| Pre-Funded       | \< 5 分钟  | ❌ 否    |

<Tip>
  为了获得最佳用户体验，对加密货币交易使用 **Polygon**，对即时执行使用**预充值账户**。
</Tip>

## 最佳实践

<AccordionGroup>
  <Accordion title="始终使用报价" icon="chart-line">
    * 永远不要硬编码汇率
    * 为每个 ramp 创建新报价
    * 遵守报价过期时间（30 秒）
    * 向用户显示确切金额
  </Accordion>

  <Accordion title="实现状态轮询" icon="rotate">
    * 每 10-30 秒轮询一次 ramp 状态
    * 使用 webhooks 作为主要通知
    * 轮询作为备用机制
    * 向用户显示当前状态
  </Accordion>

  <Accordion title="处理边缘情况" icon="triangle-exclamation">
    * 支付时间比预期长
    * 用户在支付期间关闭浏览器
    * 网络连接问题
    * 报价在创建前过期
    * 余额不足场景
  </Accordion>

  <Accordion title="使用外部 ID" icon="fingerprint">
    * 为每个 ramp 提供唯一的 `externalId`
    * 防止重复交易
    * 实现幂等重试
    * 简化对账
  </Accordion>

  <Accordion title="存储交易数据" icon="database">
    * 立即保存 ramp ID
    * 存储所有响应数据
    * 记录状态转换
    * 保留支付证明
    * 归档已完成的 ramps
  </Accordion>
</AccordionGroup>

## 测试 Ramps

### 沙盒测试

在沙盒中，使用 faker 端点：

```javascript theme={null}
// Create ramp
const ramp = await createRamp(quoteId, userId, accountId);

// Simulate payment (sandbox only)
await fetch('/api/v2/faker/cash-in', {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${token}` },
  body: JSON.stringify({ rampId: ramp.id })
});

// Poll for completion
const completed = await waitForStatus(ramp.id, 'COMPLETED');
```

### 生产测试

从小额开始：

1. **使用最小值测试**（$10-$50 等值）
2. **验证完整流程**端到端
3. **检查 webhook 交付**
4. **确认收据生成**
5. **验证会计**
6. **扩展到更大金额**

## 常见问题

<AccordionGroup>
  <Accordion title="创建后可以取消 ramp 吗？">
    只有在尚未收到支付的情况下。一旦现金入账完成，ramp 将处理到完成。
  </Accordion>

  <Accordion title="如果用户不支付怎么办？">
    如果未支付，ramps 在 24 小时后过期并移动到 EXPIRED 状态。您无需采取任何操作。
  </Accordion>

  <Accordion title="区块链确认需要多长时间？">
    * Polygon: 2-5 分钟（128 个区块确认）
    * Solana: 1-2 分钟
    * Ethereum: 10-15 分钟
    * Tron: 1-3 分钟
  </Accordion>

  <Accordion title="可以为多个 ramps 使用相同的报价吗？">
    不可以。每个 ramp 需要自己的报价。报价是单次使用的，并在 30 秒后过期。
  </Accordion>

  <Accordion title="如果处理期间加密货币价格发生变化会怎样？">
    当您使用报价创建 ramp 时，汇率被锁定。用户收到确切的报价金额。
  </Accordion>
</AccordionGroup>

## 高级功能

### 拆分支付

将资金发送到多个账户：

```json theme={null}
{
  "quotationId": "quot-id",
  "userId": "user-id",
  "accounts": [
    { "id": "wallet-1", "amount": 60 },
    { "id": "wallet-2", "amount": 40 }
  ]
}
```

### 交易元数据

在您的 ramp 中存储自定义数据：

```json theme={null}
{
  "quotationId": "quot-id",
  "userId": "user-id",
  "accountId": "account-id",
  "externalId": "order-123",
  "details": {
    "cashIn": {
      "transfiyaAccount": "3001234567"
    }
  }
}
```

## 下一步

<CardGroup cols={2}>
  <Card title="On-Ramp 指南" icon="arrow-up" href="/zh/guides/ramps/on-ramp">
    实现 on-ramps 的完整指南
  </Card>

  <Card title="Off-Ramp 指南" icon="arrow-down" href="/zh/guides/ramps/off-ramp">
    实现 off-ramps 的完整指南
  </Card>

  <Card title="报价" icon="calculator" href="/zh/concepts/quotations">
    了解定价和报价
  </Card>

  <Card title="API 参考" icon="code" href="/api-reference/endpoint/ramps-create">
    查看 Ramps API 文档
  </Card>
</CardGroup>
