跳到主要内容

回调通知(Webhooks)

Webhooks 是我们的 API 在相关事件发生时(例如收到 PIX 或支付完成)向您注册的 URL 发送的通知。

Webhook 配置

Webhooks 必须通过 Integrator Portal 进行配置。

查询可用事件

curl -X GET "https://api.corpxapi.com/v1/webhooks/events" \
-H "Authorization: Bearer YOUR_TOKEN"

响应:

{
"eventTypes": [
"pix.in.completed",
"pix.out.completed",
"pix.out.failed",
"qrcode.paid",
"pix.refund.completed",
"pix.refund.failed",
"pix.med.opened",
"pix.med.updated",
"transfer.internal.in",
"transfer.internal.out",
"account.balance_updated",
"account.lock_created",
"account.lock_released",
"accreditation.pf.created",
"accreditation.pj.created",
"edi.batch",
"ted.payment"
]
}

接收流程

  1. 我们平台上发生了一个事件。
  2. 我们向已注册的 URL 发送 POST 请求。
  3. 您的应用需处理该通知并返回 2xx 状态码。

配置灵活性

我们的 webhook 基础设施支持多种投递方式:

  • 合并:您可以在同一个 URL 接收多种事件类型(例如 pix.in.completedpix.out.completed)。
  • 分离:您可以为每种事件类型配置不同的 URL。
  • 冗余:我们可以同时将同一事件发送到多个独立的 URL。

安全性(目标端认证)

创建或更新 webhook 订阅时,您可以选择我们的投递基础设施如何对发往您端点的请求进行认证。认证方式通过 API 或控制面板按订阅进行配置。

可用认证方式

方式authType描述
HMAC 签名HMAC使用 HMAC-SHA256 和您的密钥对每个请求体进行签名。签名通过 X-Signature 请求头发送。推荐使用。
API KeyAPI_KEY在可配置的 HTTP 请求头中发送静态 API key(默认:X-API-Key)。
Basic AuthBASIC在标准 Authorization: Basic ... 请求头中发送 username:password
Bearer TokenBEARERAuthorization: Bearer ... 请求头中发送 token。
无认证NONE不进行认证。不建议在生产环境使用。

您可以在 Integrator Portal 中创建或更新 webhook 订阅时配置认证方式。前往 Webhooks > Edit Subscription,从下拉菜单中选择您偏好的认证方式。系统将根据所选方式要求您提供所需凭据(例如 HMAC 密钥、API key 或用户名/密码)。


HMAC 签名验证

authType 设置为 HMAC 时,每个请求都会包含一个 X-Signature 请求头,其中包含使用您的 secret 作为密钥对原始请求体计算的 Base64 编码 HMAC-SHA256 哈希值。

公式:

expected = base64(HMAC_SHA256(your_secret, raw_request_body))

将计算出的值与 X-Signature 请求头进行比较。如果匹配,则请求是可信的。

警告

请始终使用原始请求体字节进行验证,而非重新解析/重新序列化的版本。重新序列化 JSON 可能会改变字段顺序或空白字符,导致签名无效。

验证示例

Node.js:

const crypto = require("crypto");

function verifySignature(secret, rawBody, signatureHeader) {
const expected = crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("base64");
return expected === signatureHeader;
}

// In your Express handler:
app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => {
const signature = req.headers["x-signature"];
if (!verifySignature(WEBHOOK_SECRET, req.body, signature)) {
return res.status(403).send("Invalid signature");
}
const event = JSON.parse(req.body);
// Process event...
res.sendStatus(200);
});

Python:

import hmac, hashlib, base64

def verify_signature(secret: str, raw_body: bytes, signature_header: str) -> bool:
expected = base64.b64encode(
hmac.new(secret.encode(), raw_body, hashlib.sha256).digest()
).decode()
return hmac.compare_digest(expected, signature_header)

Go:

func verifySignature(secret string, rawBody []byte, signatureHeader string) bool {
mac := hmac.New(sha256.New, []byte(secret))
mac.Write(rawBody)
expected := base64.StdEncoding.EncodeToString(mac.Sum(nil))
return hmac.Equal([]byte(expected), []byte(signatureHeader))
}

API Key 认证

authType 设置为 API_KEY 时,我们会在每个请求的 HTTP 请求头中发送您配置的 API key。默认请求头名称为 X-API-Key,但您可以通过 authConfig.header 进行自定义。

# Creating a subscription with API Key auth:
curl -X POST "https://api.corpxapi.com/v1/webhooks" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-Id: your-tenant-id" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhook",
"authType": "API_KEY",
"authConfig": {
"key": "your-api-key-value",
"header": "X-API-Key"
},
"eventTypes": ["pix.in.completed"]
}'

您的服务器应验证请求头中的值是否与预期的 key 匹配。


Basic Auth

authType 设置为 BASIC 时,我们会在每个请求中发送 Authorization: Basic <base64(username:password)> 请求头。

{
"authType": "BASIC",
"authConfig": {
"username": "your-username",
"password": "your-password"
}
}

Bearer Token

authType 设置为 BEARER 时,我们会在每个请求中发送 Authorization: Bearer <token> 请求头。

{
"authType": "BEARER",
"authConfig": {
"token": "your-bearer-token"
}
}

信息性请求头

除上述认证请求头外,我们的投递基础设施还会在每个请求中添加以下信息性请求头:

请求头描述
x-hookdeck-event-id投递事件 ID(用于调试和支持请求)。
x-hookdeck-request-id原始请求 ID。
x-hookdeck-attempt-count投递尝试次数(首次尝试为 1)。

这些请求头仅供参考,无需验证。

IP 白名单

为提高集成安全性,我们建议您的目标服务器验证传入请求的来源 IP 地址。仅接受来自我们基础设施官方 IP 的通知:

  • 34.138.140.223
  • 34.138.161.100
  • 35.231.250.193
  • 35.196.71.29
  • 34.138.56.192

建议将这些地址添加到您防火墙或 Web 服务器的白名单中。

重试

如果您的应用返回错误(非 2xx 状态码)或发生超时,我们的系统将按照指数退避策略尝试重新发送通知:

  • 尝试次数:最多 6 次。
  • 间隔:逐步递增。

在所有尝试用尽后,该事件将被标记为失败。您可以使用我们 API 中的 Replay 端点请求手动重发。

重发事件(Replay)

如果您需要重发某个事件(由于处理失败或通知丢失),请使用 /v1/webhooks/replay 端点。

请求示例:

curl -X POST "https://api.corpxapi.com/v1/webhooks/replay" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-Id: your-tenant-id" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"eventId": "evt_abc_123",
"tenantId": "your-tenant-id"
}'

API 将返回 202 Accepted 状态码,该事件将被加入队列等待新的投递尝试。

通知格式

所有通知遵循标准信封格式。每个事件的具体内容位于 data 对象中。

标准信封

{
"id": "evt_123456789",
"type": "pix.in.completed",
"occurredAt": "2025-12-29T21:14:33.912Z",
"schemaVersion": "1.0",
"environment": "production",
"accountId": "acc_123456",
"data": { }
}

data 中的通用字段

以下字段出现在表示账本流水的所有事件类型中(PIX IN/OUT、退款、QR 支付、内部转账、手续费)。它们是将 webhook 与其他 API 端点关联起来的推荐方式:

字段说明
transactionId我们 API 使用格式的交易标识符。与 GET /v1/accounts/{accountId}/statement 返回的内容以及发起该交易的端点的同步响应一致。用于在我们的 API 中查询交易。
coreId银行合作方核心账本行的 UUID。与账单的 coreId 字段暴露的值相同;在 webhook 与异步账单同步之间保持稳定。用于与合作方导出数据对账。
endToEnd / endToEndId央行 PIX E2E ID(仅 PIX 事件)。
status交易状态。使用标准化词汇表(见下表)。

前三个字段可以在同一个载荷中共存。如果只有一个出现,则意味着另一个字段对该事件类型不相关(例如:内部转账带有 transactionId + coreId,但没有 endToEnd)。

data.status 可能的值

status 字段在所有事件中使用标准化词汇表:

Status含义事件
SUCCESS操作成功完成;余额已借记/贷记。pix.in.completedpix.out.completedpix.refund.completedqrcode.paidtransfer.internal.intransfer.internal.outfee.chargedfee.refunded
FAILED操作失败。余额变动(或已返还)。查看 data.error 了解详情。pix.out.failedpix.refund.failed
REVERSED之前已完成的 PIX IN 被撤销(例如完整退款)。当延迟对账覆盖已交付的 PIX IN 时出现。pix.in.completed(罕见,对账后)

MED(争议)事件的 status 使用自己的词汇表:

Status含义
OPEN由索赔方开启的争议,等待响应。
PENDING_DECISION已提交响应,等待央行/监管方决定。
ACCEPTED争议被接受 — 资金已返还(全部或部分)。
REJECTED争议被拒绝 — 资金保留在收款方。
CANCELED由索赔方或监管方取消的争议。

事件:pix.med.openedpix.med.updated

status 保证

对于表示账本流水的事件,status 始终存在。如果您收到的 webhook 中缺少此字段(或为空值),则它是纯信息性事件(例如 account.balance_updated)——此时请使用 type 字段本身来确定语义。

日期与时间格式

API 和 webhook 返回的所有日期/时间字段均遵循 ISO 8601 / RFC 3339 标准,使用 UTC 时区并带 Z 后缀。 这适用于信封字段(occurredAt)以及 data 内部的所有字段(receivedAtcompletedAtinitiatedAtchargedAtopenedAt 等)——同时也适用于 REST 端点(/statement/balance/payments 等)返回的 createdAt/updatedAt

示例:

2026-04-29T23:53:55.001Z         ← 毫秒精度
2026-04-29T23:53:49.328720Z ← 微秒精度
2026-04-30T18:04:36Z ← 不带小数秒

我们绝不输出巴西本地时间(BRT)或不带时区标识的"裸"时间戳。如果您收到不带 Z 后缀的日期字段,请视为缺陷并通知我们 —— 一经定位即会规范化。


事件类型与内容(data

1. pix.in.completed

当 PIX 成功入账到账户时发送。

data 结构:

  • endToEnd:中央银行的唯一交易 ID。
  • amount:交易金额。
  • currency:币种(例如 "BRL")。
  • payer:付款方详情(姓名、证件、银行、支行、账户)。
  • payee:收款方详情(姓名、证件、银行、支行、账户)。
  • reconciliationId:银行合作方的对账标识符(如可用)。
  • receivedAt:收款时间戳。

完整示例:

{
"id": "evt_123456789",
"type": "pix.in.completed",
"occurredAt": "2025-12-29T21:14:33.912Z",
"schemaVersion": "1.0",
"environment": "production",
"accountId": "acc_123456",
"data": {
"endToEnd": "E0000000020251229211433912",
"amount": 150.50,
"currency": "BRL",
"reconciliationId": "FAlGf89fN0ol41Wyc5zVQ0k5KD",
"payer": {
"name": "John Smith",
"document": "12345678900",
"bankCode": "001",
"branch": "0001",
"accountNumber": "12345-6"
},
"payee": {
"name": "Test Company",
"document": "12345678000199",
"bankCode": "999",
"branch": "0001",
"accountNumber": "98765-4"
},
"receivedAt": "2025-12-29T21:14:33.900Z"
}
}

2. qrcode.paid

当您生成的 QR Code 被支付时发送。

data 结构:

  • endToEnd:中央银行的唯一交易 ID。
  • type:QR Code 类型(staticdynamic)。
  • identifier:QR Code 的 txid(标识符)。
  • qrcodeId:内部 QR Code ID。
  • amount:支付金额。
  • currency:币种。
  • payer:付款方详情。
  • payee:收款方详情。
  • reconciliationId:银行合作方的对账标识符(如可用)。
  • receivedAt:收款时间戳。

完整示例:

{
"id": "evt_987654321",
"type": "qrcode.paid",
"occurredAt": "2025-12-29T21:15:00.000Z",
"schemaVersion": "1.0",
"environment": "production",
"accountId": "acc_123456",
"data": {
"endToEnd": "E0000000020251229211500000",
"type": "dynamic",
"identifier": "txid-qr-123",
"qrcodeId": "qr_abc123",
"amount": 250.00,
"currency": "BRL",
"reconciliationId": "FAlGf89fN0ol41Wyc5zVQ0k5KD",
"payer": {
"name": "Maria Oliveira",
"document": "98765432100",
"bankCode": "033",
"branch": "0001",
"accountNumber": "54321-0"
},
"payee": {
"name": "Your Company",
"document": "12345678000199",
"bankCode": "999",
"branch": "0001",
"accountNumber": "98765-4"
},
"receivedAt": "2025-12-29T21:14:33.900Z"
}
}

3. pix.out.completed

当出账 PIX 转账成功完成时发送。

data 结构:

  • endToEnd:端到端 ID。
  • key:使用的目标密钥。
  • identifier:交易标识符。
  • amount:转账金额。
  • payer:您的账户详情。
  • payee:目标账户详情。
  • reconciliationId:银行合作方的对账标识符(如可用)。
  • initiatedAt:转账发起时间。
  • completedAt:确认完成时间。

完整示例:

{
"id": "evt_out_123",
"type": "pix.out.completed",
"occurredAt": "2025-12-29T21:14:53.900Z",
"schemaVersion": "1.0",
"environment": "production",
"accountId": "acc_123456",
"data": {
"endToEnd": "E9999999920251229211433900",
"key": {
"type": "CPF",
"key": "12345678900"
},
"identifier": "transfer-001",
"amount": 50.00,
"currency": "BRL",
"reconciliationId": "FAlGf89fN0ol41Wyc5zVQ0k5KD",
"payer": {
"name": "Your Company",
"document": "12345678000199",
"bankCode": "999",
"branch": "0001",
"accountNumber": "98765-4"
},
"payee": {
"name": "John Smith",
"document": "12345678900",
"bankCode": "001",
"branch": "0001",
"accountNumber": "12345-6"
},
"initiatedAt": "2025-12-29T21:14:33.900Z",
"completedAt": "2025-12-29T21:14:53.900Z"
}
}

4. pix.out.failed

当出账 PIX 转账失败时发送。

data 结构:

  • endToEnd:端到端 ID(如可用)。
  • error:错误描述/失败原因。
  • key:目标密钥。
  • identifier:交易标识符。
  • amount:金额。
  • payer:您的账户详情。
  • payee:目标账户详情。
  • reconciliationId:银行合作方的对账标识符(如可用)。
  • initiatedAt:发起时间戳。

完整示例:

{
"id": "evt_out_err_123",
"type": "pix.out.failed",
"occurredAt": "2025-12-29T21:14:35.000Z",
"schemaVersion": "1.0",
"environment": "production",
"accountId": "acc_123456",
"data": {
"endToEnd": "E9999999920251229211433900",
"error": "Insufficient balance in destination account or invalid key",
"key": {
"type": "EMAIL",
"key": "teste@exemplo.com"
},
"identifier": "transfer-002",
"amount": 1000.00,
"currency": "BRL",
"payer": {
"name": "Your Company",
"document": "12345678000199",
"bankCode": "999",
"branch": "0001",
"accountNumber": "98765-4"
},
"payee": {
"name": "Failed Recipient",
"document": "00000000000",
"bankCode": "001",
"branch": "0001",
"accountNumber": "00000-0"
},
"initiatedAt": "2025-12-29T21:14:33.900Z"
}
}

5. payment.sent (已弃用)

已弃用

此事件将在未来版本中移除。请改用带有 methodPAYMENT)字段和 payload 中 payment 对象的 pix.out.completed

当支付指令(PIX Out)被银行合作方确认并与对账单中的交易对账后发送。

data 结构:

  • paymentId:支付指令标识符。
  • endToEnd:中央银行的端到端交易 ID。
  • identifier:集成方创建支付时提供的标识符。
  • amount:支付金额。
  • currency:币种(例如 "BRL")。
  • status:支付状态(COMPLETED)。
  • key:目标 PIX 密钥(类型和值)。
  • payer:付款方详情(姓名、证件、银行、支行、账户)。
  • payee:收款方详情(姓名、证件、银行、支行、账户、PIX key)。
  • initiatedAt:支付指令创建时间戳。
  • completedAt:确认时间戳。

完整示例:

{
"id": "evt_pay_123",
"type": "payment.sent",
"occurredAt": "2026-02-13T15:50:00.000Z",
"schemaVersion": "1.0",
"environment": "production",
"accountId": "acc_123456",
"data": {
"paymentId": "pay_abc123",
"endToEnd": "E3674167520260213154900123456789",
"identifier": "order-12345",
"amount": 150.50,
"currency": "BRL",
"status": "COMPLETED",
"key": {
"type": "CPF",
"key": "12345678900"
},
"payer": {
"name": "Your Company",
"document": "12345678000199",
"bankCode": "999",
"branch": "0001",
"account": "98765-4"
},
"payee": {
"name": "John Smith",
"document": "12345678900",
"bankCode": "001",
"branch": "0001",
"account": "12345-6",
"pixKey": "12345678900"
},
"initiatedAt": "2026-02-13T15:49:30.000Z",
"completedAt": "2026-02-13T15:50:00.000Z"
}
}

6. payment.refunded (已弃用)

已弃用

此事件将在未来版本中移除。请改用带有 method: REFUND_RECEIVEDpix.in.completed

当您发送的支付(PIX Out)被收款方退回时发送。

data 结构:

  • paymentId:原始支付指令标识符。
  • originalEndToEnd:原始支付的端到端 ID。
  • refundEndToEnd:退款的端到端 ID(D 码)。
  • identifier:集成方提供的标识符。
  • originalAmount:原始支付金额。
  • refundAmount:退款金额。
  • currency:币种。
  • status:状态(REFUNDED)。
  • initiatedAt:原始支付时间戳。
  • refundedAt:退款时间戳。

完整示例:

{
"id": "evt_pay_ref_123",
"type": "payment.refunded",
"occurredAt": "2026-02-13T16:00:00.000Z",
"schemaVersion": "1.0",
"environment": "production",
"accountId": "acc_123456",
"data": {
"paymentId": "pay_abc123",
"originalEndToEnd": "E3674167520260213154900123456789",
"refundEndToEnd": "D3674167520260213160000987654321",
"identifier": "order-12345",
"originalAmount": 150.50,
"refundAmount": 150.50,
"currency": "BRL",
"status": "REFUNDED",
"initiatedAt": "2026-02-13T15:49:30.000Z",
"refundedAt": "2026-02-13T16:00:00.000Z"
}
}

7. pix.refund.completed

当 PIX 退款完成时发送。

data 结构:

  • originalEndToEnd:被退款的原始交易 ID。
  • refundEndToEnd:新退款 PIX 的 ID。
  • identifier:退款标识符。
  • amount:退款金额。
  • payer:您的账户详情(发起退款方)。
  • payee:目标账户详情(接收退款方)。
  • reconciliationId:银行合作方的对账标识符(如可用)。
  • initiatedAt:发起时间戳。
  • completedAt:完成时间戳。

完整示例:

{
"id": "evt_ref_123",
"type": "pix.refund.completed",
"occurredAt": "2025-12-29T21:14:53.900Z",
"schemaVersion": "1.0",
"environment": "production",
"accountId": "acc_123456",
"data": {
"originalEndToEnd": "E0000000020251229211433912",
"refundEndToEnd": "D0000000020251229211453900",
"identifier": "refund-999",
"amount": 150.50,
"currency": "BRL",
"payer": {
"name": "Your Company",
"document": "12345678000199",
"bankCode": "999",
"branch": "0001",
"accountNumber": "98765-4"
},
"payee": {
"name": "John Smith",
"document": "12345678900",
"bankCode": "001",
"branch": "0001",
"accountNumber": "12345-6"
},
"initiatedAt": "2025-12-29T21:14:33.900Z",
"completedAt": "2025-12-29T21:14:53.900Z"
}
}

8. pix.refund.failed

当退款请求失败时发送。

data 结构:

  • originalEndToEnd:原始交易 ID。
  • error:失败原因。
  • identifier:标识符。
  • amount:金额。
  • payer:您的账户详情。
  • payee:目标账户详情。
  • initiatedAt:发起时间戳。

完整示例:

{
"id": "evt_ref_err_123",
"type": "pix.refund.failed",
"occurredAt": "2025-12-29T21:14:35.000Z",
"schemaVersion": "1.0",
"environment": "production",
"accountId": "acc_123456",
"data": {
"originalEndToEnd": "E0000000020251229211433912",
"error": "Original transaction has already been refunded",
"identifier": "refund-998",
"amount": 150.50,
"currency": "BRL",
"payer": {
"name": "Your Company",
"document": "12345678000199",
"bankCode": "999",
"branch": "0001",
"accountNumber": "98765-4"
},
"payee": {
"name": "John Smith",
"document": "12345678900",
"bankCode": "001",
"branch": "0001",
"accountNumber": "12345-6"
},
"initiatedAt": "2025-12-29T21:14:33.900Z"
}
}

9. fee.charged

当账户被收取银行费用时发送(例如按笔收取的 PIX 手续费)。

data 结构:

  • amount:收取的费用金额。
  • currency:币种。
  • feeServiceType:触发收费的操作类型(例如 PIX_OUTPIX_IN)。
  • description:费用描述。
  • chargedAt:收费时间戳。

完整示例:

{
"id": "evt_fee_123",
"type": "fee.charged",
"occurredAt": "2026-02-14T20:30:43.000Z",
"schemaVersion": "1.0",
"environment": "production",
"accountId": "acc_123456",
"data": {
"amount": 2.99,
"currency": "BRL",
"feeServiceType": "PIX_OUT",
"description": "Banking Fee",
"chargedAt": "2026-02-14T20:30:43.000Z"
}
}

10. pix.med.opened

当新的 MED(特别退回机制)争议针对某笔交易发起时发送。

data 结构:

  • endToEndId:争议中的交易 ID。
  • identifier:关联标识符。
  • qrcodeId:QR Code ID(如适用)。
  • amount:争议金额。
  • currency:币种。
  • claimant:提出索赔的人员详情(姓名、证件、银行、支行、账户)。
  • openedAt:MED 发起日期。
  • deadlineAt:响应截止日期。

完整示例:

{
"id": "evt_med_123",
"type": "pix.med.opened",
"occurredAt": "2025-12-29T21:14:33.912Z",
"schemaVersion": "1.0",
"environment": "production",
"accountId": "acc_123456",
"data": {
"endToEndId": "E0000000020251229211433912",
"identifier": "tx-med-001",
"qrcodeId": "qr_abc123",
"amount": 150.50,
"currency": "BRL",
"claimant": {
"name": "John Smith",
"document": "12345678900",
"bankCode": "001",
"branch": "0001",
"accountNumber": "12345-6"
},
"openedAt": "2025-12-29T21:14:33.900Z",
"deadlineAt": "2026-01-05T21:14:33.900Z"
}
}

10. pix.med.updated

当 MED(特别退回机制)争议更新(状态变更、新信息、解决方案)时发送。

data 结构:

  • endToEndId:争议中的交易 ID。
  • identifier:关联标识符。
  • qrcodeId:QR Code ID(如适用)。
  • amount:争议金额。
  • currency:币种。
  • status:当前 MED 状态(OPENCLOSEDAGREEDDISAGREED)。
  • result:争议结果(如已解决)。
  • claimant:提出索赔的人员详情。
  • openedAt:MED 发起日期。
  • updatedAt:最后更新日期。

完整示例:

{
"id": "evt_med_456",
"type": "pix.med.updated",
"occurredAt": "2025-12-30T15:20:00.000Z",
"schemaVersion": "1.0",
"environment": "production",
"accountId": "acc_123456",
"data": {
"endToEndId": "E0000000020251229211433912",
"identifier": "tx-med-001",
"qrcodeId": "qr_abc123",
"amount": 150.50,
"currency": "BRL",
"status": "CLOSED",
"result": "AGREED",
"claimant": {
"name": "John Smith",
"document": "12345678900",
"bankCode": "001",
"branch": "0001",
"accountNumber": "12345-6"
},
"openedAt": "2025-12-29T21:14:33.900Z",
"updatedAt": "2025-12-30T15:20:00.000Z"
}
}

最佳实践

  • 幂等性:您的应用应做好多次接收同一 webhook 的准备。使用信封中的 id 避免重复处理。
  • 快速响应:收到 webhook 后立即返回 200 OK 状态码,并异步处理业务逻辑以避免超时。
  • 时间戳验证:检查 occurredAt 是否过旧(建议 5 分钟容差),以防止重放攻击。