diff --git a/docs.json b/docs.json
index 1a46808e..a3c5d8b4 100644
--- a/docs.json
+++ b/docs.json
@@ -46,13 +46,17 @@
"pages": [
"v2/guides/webhooks-callbacks/introduction",
"v2/guides/webhooks-callbacks/set-up-endpoint",
- "v2/guides/webhooks-callbacks/webhook-event-type"
+ "v2/guides/webhooks-callbacks/webhook-event-type",
+ "v2/guides/webhooks-callbacks/transaction-events",
+ "v2/guides/webhooks-callbacks/mpc-tss-request-events",
+ "v2/guides/webhooks-callbacks/webhook-operations"
]
},
{
"group": "Transactions",
"pages": [
"v2/guides/transactions/sources-and-destinations",
+ "v2/guides/transactions/transaction-fields",
"v2/guides/transactions/transfer-routing",
"v2/guides/transactions/estimate-fees",
"v2/guides/transactions/solana-token-account-rent",
@@ -858,13 +862,17 @@
"pages": [
"v2_cn/guides/webhooks-callbacks/introduction",
"v2_cn/guides/webhooks-callbacks/set-up-endpoint",
- "v2_cn/guides/webhooks-callbacks/webhook-event-type"
+ "v2_cn/guides/webhooks-callbacks/webhook-event-type",
+ "v2_cn/guides/webhooks-callbacks/transaction-events",
+ "v2_cn/guides/webhooks-callbacks/mpc-tss-request-events",
+ "v2_cn/guides/webhooks-callbacks/webhook-operations"
]
},
{
"group": "交易",
"pages": [
"v2_cn/guides/transactions/sources-and-destinations",
+ "v2_cn/guides/transactions/transaction-fields",
"v2_cn/guides/transactions/transfer-routing",
"v2_cn/guides/transactions/estimate-fees",
"v2_cn/guides/transactions/solana-token-account-rent",
@@ -1598,4 +1606,4 @@
"destination": "https://www.cobo.com/payments/cn/guides/overview"
}
]
-}
\ No newline at end of file
+}
diff --git a/v2/guides/transactions/status.mdx b/v2/guides/transactions/status.mdx
index 97757df1..42984125 100644
--- a/v2/guides/transactions/status.mdx
+++ b/v2/guides/transactions/status.mdx
@@ -288,6 +288,16 @@ After a transaction is approved, it enters the `PendingSignature` status and mus
A transaction in the `Confirming` status with the sub-status `PendingBlockConfirmations` is waiting for the required number of block confirmations on its chain. This is a normal part of processing and does not mean the transaction is stuck. The required number of confirmations and the expected confirmation time vary by chain.
+## When to credit a deposit
+
+Treat `Confirming` and its `wallets.transaction.updated` events as progress only. A blockchain deposit in `Confirming` is not yet safe to credit. Its `confirmed_num` must reach `confirming_threshold` before the transaction can complete confirmation processing.
+
+The successful internal outcome is surfaced publicly as the `Completed` status and the [`wallets.transaction.succeeded`](/v2/guides/webhooks-callbacks/transaction-events#walletstransactionsucceeded) event. Credit a deposit after receiving that event, or after verifying `Completed` with [Get transaction information](/v2/api-references/transactions/get-transaction-information) or [List all transactions](/v2/api-references/transactions/list-all-transactions). Make reconciliation idempotent according to the [endpoint handling guidance](/v2/guides/webhooks-callbacks/set-up-endpoint#important-notes).
+
+
+This crediting guidance applies only to blockchain deposits. It does not apply to `MessageSign` or other transaction types that do not move funds.
+
+
## Available actions
You can perform the following actions based on the transaction status:
@@ -302,4 +312,4 @@ You can perform the following actions based on the transaction status:
For details on how a replaced transaction's status changes, see [RBF (Replace-By-Fee) transaction lifecycle](/v2/guides/transactions/rbf-transaction-lifecycle).
-For more details, refer to [Manage transactions](/v2/guides/transactions/manage-transactions).
\ No newline at end of file
+For more details, refer to [Manage transactions](/v2/guides/transactions/manage-transactions).
diff --git a/v2/guides/transactions/transaction-fields.mdx b/v2/guides/transactions/transaction-fields.mdx
new file mode 100644
index 00000000..59d47ec7
--- /dev/null
+++ b/v2/guides/transactions/transaction-fields.mdx
@@ -0,0 +1,38 @@
+---
+title: "Transaction field reference"
+lang: "en"
+description: "Reconcile transactions by understanding identifiers, direction fields, replacement links, and Cobo-defined categories."
+---
+
+import WaasSkillReminder from '/snippets/waas_skill_reminder.mdx';
+
+
+
+## Overview
+
+Use this reference to distinguish transaction fields that look similar but serve different reconciliation purposes. See [Transaction event payload](/v2/guides/webhooks-callbacks/transaction-events) for the complete payload contract, [Transaction sources and destinations](/v2/guides/transactions/sources-and-destinations) for direction shapes, [RBF transaction lifecycle](/v2/guides/transactions/rbf-transaction-lifecycle) for replacement behavior, and [Manage transactions](/v2/guides/transactions/manage-transactions#cobo-defined-categories) for the full `cobo_category` table.
+
+## Field dictionary
+
+| Field | Meaning and conditionality | Preferred reconciliation use |
+| --- | --- | --- |
+| `chain_id` | Identifies the blockchain network. It is present for on-chain transactions and differs from the asset identifiers below. | Use it with `token_id` when routing chain-specific processing. |
+| `token_id` | Identifies an on-chain token in Cobo's catalog. Native assets and contract tokens have different values, and the same economic asset on different chains has different `token_id` values. | Use it for token-specific balances, decimals, and chain transfers. |
+| `asset_id` | Identifies an asset in an Exchange Wallet, where the balance is not represented by an on-chain `token_id`. | Use it for exchange-account reconciliation; do not treat it as a network identifier. |
+| `request_id` | Your idempotency and correlation identifier for a client-initiated request. It is `null` when no client request created the transaction, such as for a deposit. | Match a webhook or API result to the local request that initiated an outbound transaction. |
+| `source` | Describes the origin selected by `source_type`. For a deposit it normally represents the external sender; for a withdrawal it represents the sending wallet. | Determine direction and the account or address from which value moved. |
+| `destination` | Describes the target selected by `destination_type`. For a deposit it identifies the receiving wallet address; for a withdrawal it identifies the external target. | Determine direction and the account, address, contract, or signing input receiving the operation. |
+| `replaced_by_transaction_hash` | Appears in `replacement` only on the original transaction after replacement and points to the new transaction's hash. | Follow the original record to the effective RBF transaction. |
+| `cobo_category` | Contains Cobo-defined operational classifications when applicable. High-signal values include `AutoSweep`, `ComplianceRefund`, `ComplianceIsolate`, `ScreenAppRefund`, and `ScreenAppIsolate`. | Branch on the explicit category instead of inferring system activity from addresses. |
+
+## Example mappings
+
+| Asset | `chain_id` | `token_id` | `asset_id` |
+| --- | --- | --- | --- |
+| Ethereum native asset | `ETH` | `ETH` | `ETH` |
+| USDT on Ethereum | `ETH` | `ETH_USDT` | `USDT` |
+| TRON native asset | `TRON` | `TRON` | `TRON` |
+| USDT on TRON | `TRON` | `TRON_USDT` | `USDT` |
+| Bitcoin | `BTC` | `BTC` | `BTC` |
+
+The `asset_id` column shows the corresponding Exchange Wallet asset identifier. An Exchange Wallet transaction returns `asset_id` instead of the on-chain `chain_id` and `token_id` pair.
diff --git a/v2/guides/webhooks-callbacks/mpc-tss-request-events.mdx b/v2/guides/webhooks-callbacks/mpc-tss-request-events.mdx
new file mode 100644
index 00000000..fe8ee41c
--- /dev/null
+++ b/v2/guides/webhooks-callbacks/mpc-tss-request-events.mdx
@@ -0,0 +1,71 @@
+---
+title: "MPC TSS request event payload"
+lang: "en"
+description: "Understand the shared TSSRequest payload for Portal key-generation and resharing webhook events."
+---
+
+import WaasSkillReminder from '/snippets/waas_skill_reminder.mdx';
+
+
+
+## Overview
+
+The `wallets.mpc.tss_request.*` event family reports MPC key-generation and resharing requests initiated in Cobo Portal. The four events use the same `TSSRequest` payload. See [Webhook event types](/v2/guides/webhooks-callbacks/webhook-event-type) for the catalog.
+
+## TSSRequest payload fields
+
+| Field | Type | Conditional | Description |
+| --- | --- | --- | --- |
+| `tss_request_id` | string | No | Unique identifier of the TSS request. |
+| `source_key_share_holder_group` | object, nullable | Yes | Existing source group for a resharing request. It is absent for initial key generation. |
+| `source_key_share_holder_group.key_share_holder_group_id` | string | When the parent is present | Identifier of the source key share holder group. |
+| `source_key_share_holder_group.tss_node_ids` | array of strings | When the parent is present | TSS Node identifiers participating from the source group. |
+| `target_key_share_holder_group_id` | string | No | Group that the request creates or updates. |
+| `type` | string | No | Request type, such as `KeyGen` or `KeyGenFromKeyGroup`. |
+| `status` | string | No | Current state of the request. |
+| `description` | string, nullable | Yes | Description supplied with the request; it is `null` when none was provided. |
+| `created_timestamp` | integer | No | Request creation time as a Unix timestamp in milliseconds. |
+
+
+## `wallets.mpc.tss_request.created`
+
+Emitted when the request record is created in its initial state.
+
+### Initial key generation example
+
+```json
+{"tss_request_id":"20260721114129000132315000003970","source_key_share_holder_group":null,"target_key_share_holder_group_id":"11111111-1111-4111-8111-111111111111","type":"KeyGen","status":"PendingKeyHolderConfirmation","description":"Create the first Main Group","created_timestamp":1784563200000}
+```
+
+
+## `wallets.mpc.tss_request.updated`
+
+Emitted when the request moves to a different intermediate state while key holders and MPC processing complete their work.
+
+### Resharing update example
+
+```json
+{"tss_request_id":"20260721114129000132315000003971","source_key_share_holder_group":{"key_share_holder_group_id":"22222222-2222-4222-8222-222222222222","tss_node_ids":["cobo5yb7BNEBwwp5XXedbhnzQfvQtp132W4dH4Jz4x4eDp4KA"]},"target_key_share_holder_group_id":"33333333-3333-4333-8333-333333333333","type":"KeyGenFromKeyGroup","status":"MPCProcessing","description":null,"created_timestamp":1784563300000}
+```
+
+
+## `wallets.mpc.tss_request.succeeded`
+
+Emitted when the request reaches the terminal `Success` state.
+
+### Successful resharing example
+
+```json
+{"tss_request_id":"20260721114129000132315000003972","source_key_share_holder_group":{"key_share_holder_group_id":"22222222-2222-4222-8222-222222222222","tss_node_ids":["cobo5yb7BNEBwwp5XXedbhnzQfvQtp132W4dH4Jz4x4eDp4KA"]},"target_key_share_holder_group_id":"33333333-3333-4333-8333-333333333333","type":"KeyGenFromKeyGroup","status":"Success","description":null,"created_timestamp":1784563300000}
+```
+
+
+## `wallets.mpc.tss_request.failed`
+
+Emitted when the request reaches `KeyHolderConfirmationFailed` or `KeyGeneratingFailed`.
+
+### Failed key generation example
+
+```json
+{"tss_request_id":"20260721114129000132315000003973","source_key_share_holder_group":null,"target_key_share_holder_group_id":"11111111-1111-4111-8111-111111111111","type":"KeyGen","status":"KeyGeneratingFailed","description":"Create the first Main Group","created_timestamp":1784563200000}
+```
diff --git a/v2/guides/webhooks-callbacks/set-up-endpoint.mdx b/v2/guides/webhooks-callbacks/set-up-endpoint.mdx
index 4153a322..0ef8621c 100644
--- a/v2/guides/webhooks-callbacks/set-up-endpoint.mdx
+++ b/v2/guides/webhooks-callbacks/set-up-endpoint.mdx
@@ -19,6 +19,18 @@ First, choose a server environment, such as a cloud service like AWS, Google Clo
After you create the endpoint, you need to implement the logic on the server to handle the webhook events or callback messages, including parsing the API request, verifying the signature, responding to the request and adding other handling logic if necessary.
+### Callback message payload
+
+A callback message's `data` field uses the same `Transaction` shape as a transaction webhook event. See [Transaction event payload](/v2/guides/webhooks-callbacks/transaction-events) for the complete field table. The values reflect what is known when your endpoint must return `ok` or `deny`; do not treat the callback as the transaction's final state.
+
+| Field | Population at callback time |
+| --- | --- |
+| `cobo_id` | Can be `null` when Cobo has not yet assigned the tracking identifier. |
+| `asset_id` | Populated for an Exchange Wallet asset when that value is available; otherwise `null`. On-chain wallet transactions use `token_id` instead. |
+| `result` | `null` until a `MessageSign` result is available, and remains `null` for transaction types that do not produce a signing result. |
+
+Other optional fields depend on transaction type and value availability. Use the [Transaction event payload](/v2/guides/webhooks-callbacks/transaction-events) for the full contract and [Transaction field reference](/v2/guides/transactions/transaction-fields) for reconciliation semantics. Retrieve the transaction through the API or process later transaction events when you need its subsequent state.
+
### Verify the signature
To prevent unauthorized access, when you receive a webhook event or a callback message, you need to validate the authenticity of the API request by verifying the signature.
@@ -80,11 +92,12 @@ The verification steps are as follows:
Properly responding to webhook events and callback messages is crucial for ensuring that webhooks and callbacks are processed as expected. This section describes the expected response from both webhook and callback endpoints.
-#### Webhook events
+
+#### Webhook delivery policy
When your webhook endpoint receives a webhook event, it should respond with a status code of `200` or `201` to indicate that the event has been successfully received and processed. Once this response is sent, the WaaS service will stop retrying to send the event and the event status will become `Delivered` on Cobo Portal.
-The default timeout for each webhook event is 2 seconds. If the webhook endpoint does not respond or responds with a status code other than `200` or `201`, the WaaS service will continue to retry sending the event. If the number of retry attempts reaches 10 , the WaaS service will stop sending the event and the event status will become `Failed`· You can resend the event by clicking **Retry** on **Cobo Portal** > **Developer** > **WaaS 2.0** > **Webhook Events**.
+The default timeout for each webhook event is 2 seconds. If the webhook endpoint does not respond or responds with a status code other than `200` or `201`, the WaaS service will continue to retry sending the event. If the number of retry attempts reaches 10, the WaaS service will stop sending the event and the event status will become `Failed`. You can resend the event by clicking **Retry** on **Cobo Portal** > **Developer** > **WaaS 2.0** > **Webhook Events**.
Cobo does not guarantee that events will be delivered in the order they are generated. For example, creating a transfer will generate the following events:
@@ -94,11 +107,14 @@ Cobo does not guarantee that events will be delivered in the order they are gene
Your endpoint should not assume that events will arrive in this sequence and must handle delivery appropriately.
-#### Callback messages
+
+#### Callback delivery policy
-When your callback endpoint receives a callback message, it should respond with a status code of `200` or `201` and a response body of `ok` or `deny` to indicate transaction approval or rejection. Once this response is sent, the WaaS service will stop retrying to send the message and the callback message status will become `Delivered`on Cobo Portal.
+When your callback endpoint receives a callback message, it should respond with a status code of `200` or `201` and a response body of `ok` or `deny` to indicate transaction approval or rejection. Once this response is sent, the WaaS service will stop retrying to send the message and the callback message status will become `Delivered` on Cobo Portal.
-If the callback endpoint does not respond, responds with a status code other than `200` or `201`, or the response body does not contain `ok` or `deny`, the WaaS service will continue to retry sending the message. If the number of retry attempts reaches 30, the WaaS service will stop sending the message and the callback message status will become `Failed`. You can resend the message by using the [Retry callback message](/v2/api-references/developers/retry-callback-message) operation.
+If the callback endpoint does not respond, responds with a status code other than `200` or `201`, or the response body does not contain `ok` or `deny`, the WaaS service will continue to retry sending the message. If the number of retry attempts reaches 30, the WaaS service will stop sending the message and the callback message status will become `Failed`. You can resend the message by using the [Retry callback message](/v2/api-references/developers/retry-callback-message) operation.
+
+Webhook event and callback message records expose their delivery `status` and retry information. For webhooks, inspect the endpoint-scoped attempts with [List webhook event logs](/v2/api-references/developers--webhooks/list-webhook-event-logs). You can also inspect the response status and body for each webhook or callback attempt through the Portal path below. For a full recovery workflow, see [Recover missed or failed events](/v2/guides/webhooks-callbacks/webhook-operations#recover-missed-or-failed-events) in Webhook and callback operations.
### Common delivery failures
@@ -126,6 +142,10 @@ To see examples of how to implement the handling logic, refer to the following f
## Advanced usage
+### Multiple endpoints
+
+When you operate multiple webhook endpoints, or a webhook endpoint together with a callback endpoint, inspect each endpoint's event or message record and endpoint-scoped delivery logs separately. Do not assume that different endpoints share one delivery state. Make every endpoint handler idempotent according to [Important notes](#important-notes).
+
### Wallet-level webhook routing
In certain business scenarios, you may need to apply different Webhook handling logic for different wallets. For example:
@@ -188,4 +208,4 @@ async def handle_webhook(
- When receiving the webhook events, your endpoint should first return the correct status code promptly and then handle any subsequent processing asynchronously to prevent timeouts.
- Due to the retry mechanism of webhook events, webhook endpoints may sometimes receive the same event multiple times. To protect against duplicate event processing, please log the event IDs, transaction hashes, or transaction IDs you've already processed and refrain from processing those that are already logged.
-
\ No newline at end of file
+
diff --git a/v2/guides/webhooks-callbacks/transaction-events.mdx b/v2/guides/webhooks-callbacks/transaction-events.mdx
new file mode 100644
index 00000000..d20f6ce3
--- /dev/null
+++ b/v2/guides/webhooks-callbacks/transaction-events.mdx
@@ -0,0 +1,154 @@
+---
+title: "Transaction event payload"
+lang: "en"
+description: "Understand the shared Transaction payload contract for the four wallets.transaction.* webhook events."
+---
+
+import WaasSkillReminder from '/snippets/waas_skill_reminder.mdx';
+
+
+
+## Overview
+
+`wallets.transaction.created`, `wallets.transaction.updated`, `wallets.transaction.succeeded`, and `wallets.transaction.failed` all deliver the same `Transaction` payload shape. This page documents that contract once; each event section describes the trigger and lifecycle meaning that differs.
+
+See [Webhook event types](/v2/guides/webhooks-callbacks/webhook-event-type) for the event catalog and [Transaction field reference](/v2/guides/transactions/transaction-fields) for reconciliation guidance for fields such as `chain_id`, `token_id`, and `asset_id`.
+
+## Transaction payload fields
+
+| Field | Type | Conditional | Description |
+| --- | --- | --- | --- |
+| `transaction_id` | string | No | Cobo's unique transaction record identifier. |
+| `cobo_id` | string, nullable | Yes | Cobo's tracking identifier. It can be `null` before it is assigned. |
+| `request_id` | string, nullable | Yes | Your identifier for the request that created the transaction. It is `null` when no client request exists, such as for a deposit. |
+| `wallet_id` | string | No | Destination wallet for a deposit and source wallet for an outbound transaction. |
+| `type` | string | No | Transaction type, such as `Deposit`, `Withdrawal`, `ContractCall`, or `MessageSign`. |
+| `status` | string | No | Public lifecycle status. See [Transaction statuses and sub-statuses](/v2/guides/transactions/status). |
+| `sub_status` | string, nullable | Yes | More specific processing state within `status`, when available. |
+| `failed_reason` | string, nullable | Yes | Failure detail for a transaction that did not complete. |
+| `chain_id` | string, nullable | Yes | Blockchain identifier for an on-chain transaction. |
+| `token_id` | string, nullable | Yes | Cobo token catalog identifier for an on-chain asset. |
+| `asset_id` | string, nullable | Yes | Exchange Wallet asset identifier; it is used instead of `token_id` for that wallet type. |
+| `source` | object | No | Transaction origin. `source_type` selects the shape; other fields can include `wallet_id`, `address`, `addresses`, or `included_utxos`. |
+| `destination` | object | No | Transaction target. `destination_type` selects the shape; other fields can include `wallet_id`, `address`, `amount`, `account_output`, `utxo_outputs`, or contract and message-signing inputs. |
+| `result` | object, nullable | Yes | Completed `MessageSign` result. A signature result contains `result_type` and `signature`; other transaction types return `null`. |
+| `fee` | object, nullable | Yes | Network fee details once known. Fields vary by `fee_type` and can include `token_id`, `fee_used`, `estimated_fee_used`, and maximum-fee values. |
+| `initiator` | string, nullable | Yes | Display identifier of the initiator when available. |
+| `initiator_type` | string, nullable | Yes | Channel through which the transaction was initiated when available. |
+| `confirmed_num` | integer, nullable | Yes | On-chain confirmations received so far. |
+| `confirming_threshold` | integer, nullable | Yes | Confirmations required before the transaction can be confirmed. |
+| `transaction_hash` | string, nullable | Yes | On-chain transaction hash after broadcast. |
+| `block_info` | object, nullable | Yes | Block containing the transaction. It is `null` before the transaction is included in a block. |
+| `block_info.block_number` | integer | When the parent is present | Height of the block containing the transaction. |
+| `block_info.block_timestamp` | integer | When the parent is present | Block creation time as a Unix timestamp in milliseconds. |
+| `block_info.block_hash` | string | When the parent is present | Hash of the block containing the transaction. |
+| `raw_tx_info` | object, nullable | Yes | Constructed transaction details. It is `null` before raw transaction data is available. |
+| `raw_tx_info.raw_tx` | string, nullable | When available | Serialized signed transaction data. |
+| `raw_tx_info.unsigned_raw_tx` | string, nullable | When available | Serialized transaction data before signing. |
+| `raw_tx_info.used_nonce` | integer, nullable | Account-model chains only | Nonce consumed by the transaction. It is `null` for chains that do not use account nonces. |
+| `raw_tx_info.selected_utxos` | array of objects, nullable | UTXO chains only | Inputs selected for a UTXO transaction. |
+| `raw_tx_info.selected_utxos[].tx_hash` | string | When `selected_utxos` is present | Hash of the transaction that created the selected output. |
+| `raw_tx_info.selected_utxos[].vout_n` | integer | When `selected_utxos` is present | Output index within the transaction identified by `tx_hash`. |
+| `raw_tx_info.selected_utxos[].token_id` | string | When `selected_utxos` is present | Token identifier of the selected output. |
+| `raw_tx_info.selected_utxos[].address` | string | When `selected_utxos` is present | Address that owns the selected output. |
+| `raw_tx_info.selected_utxos[].value` | string | When `selected_utxos` is present | Value of the selected output in token units. |
+| `raw_tx_info.utxo_changes` | array of objects, nullable | UTXO chains only | Change outputs created by a UTXO transaction. |
+| `raw_tx_info.utxo_changes[].address` | string | When `utxo_changes` is present | Address receiving the change output. |
+| `raw_tx_info.utxo_changes[].value` | string | When `utxo_changes` is present | Value of the change output in token units. |
+| `raw_tx_info.utxo_changes[].token_id` | string | When `utxo_changes` is present | Token identifier of the change output. |
+| `replacement` | object, nullable | Yes | RBF relationship. It is `null` when the transaction has not replaced another transaction and has not been replaced. |
+| `replacement.replaced_by_type` | string, nullable | Original transaction only | Replacement action applied to this transaction: `Drop`, `Resend`, or `SpeedUp`. |
+| `replacement.replaced_by_transaction_id` | string, nullable | Original transaction only | Cobo transaction ID of the transaction that replaced this transaction. |
+| `replacement.replaced_by_transaction_hash` | string, nullable | Original transaction only | On-chain hash of the transaction that replaced this transaction, once available. |
+| `replacement.replaced_type` | string, nullable | Replacement transaction only | Replacement action through which this transaction replaced another transaction: `Drop`, `Resend`, or `SpeedUp`. |
+| `replacement.replaced_transaction_id` | string, nullable | Replacement transaction only | Cobo transaction ID of the transaction that this transaction replaced. |
+| `replacement.replaced_transaction_hash` | string, nullable | Replacement transaction only | On-chain hash of the transaction that this transaction replaced, once available. |
+| `category` | array of strings, nullable | Yes | Your custom transaction categories. |
+| `cobo_category` | array of strings, nullable | Yes | Cobo-defined operational categories, such as `AutoSweep`. |
+| `description` | string, nullable | Yes | Client-provided transaction description. |
+| `is_loop` | boolean | No | Whether the transfer uses Cobo Loop instead of an on-chain transaction. |
+| `extra` | array of strings, nullable | Yes | Additional structured business data encoded as strings when applicable. |
+| `fueling_info` | object, nullable | Yes | Fee Station transaction relationship. It is `null` when Fee Station is not involved. |
+| `fueling_info.request_id` | string | When the parent is present | Request identifier of the Fee Station transaction. |
+| `fueling_info.transaction_id` | string | When the parent is present | Cobo transaction ID of the Fee Station transaction. |
+| `fueling_info.main_transaction_id` | string, nullable | Fee transaction records only | Cobo transaction ID of the parent transaction whose fee this record funds. It is omitted for the main transaction. |
+| `timeline` | array of objects, nullable | Yes | Ordered lifecycle states for the transaction. |
+| `timeline[].status` | string | When `timeline` is present | Lifecycle state represented by the entry. It uses the same Transaction status enum as the top-level `status` field. |
+| `timeline[].finished` | boolean | When `timeline` is present | Whether processing for this lifecycle state has finished. |
+| `timeline[].finished_timestamp` | integer, nullable | When `timeline` is present | Time the lifecycle state finished, as a Unix timestamp in milliseconds. It is `null` while `finished` is `false`. |
+| `created_timestamp` | integer | No | Transaction creation time as a Unix timestamp in milliseconds. |
+| `updated_timestamp` | integer | No | Most recent transaction update time as a Unix timestamp in milliseconds. |
+
+See [Transaction sources and destinations](/v2/guides/transactions/sources-and-destinations) for every supported `source` and `destination` shape, [Estimate transaction fees](/v2/guides/transactions/estimate-fees) for fee variants, and [RBF transaction lifecycle](/v2/guides/transactions/rbf-transaction-lifecycle) for replacement fields.
+
+## Direction: deposits and withdrawals
+
+For a `Deposit`, `wallet_id` identifies the destination wallet, `source` describes the external origin, and `destination` describes the deposit address. For a `Withdrawal`, `wallet_id` and `source` identify the sending wallet, while `destination` identifies the receiving address or account output. Use the `type`, `source.source_type`, and `destination.destination_type` discriminators together rather than inferring direction from addresses.
+
+
+## `wallets.transaction.created`
+
+This event is emitted when Cobo first records a transaction. For a deposit, this follows detection on the blockchain. For an outbound transaction, this follows creation of the transaction record from the request. It does not indicate success.
+
+### TRON token deposit example
+
+```json
+{"transaction_id":"55555555-5555-4555-8555-555555555555","cobo_id":null,"request_id":null,"wallet_id":"22222222-2222-4222-8222-222222222222","type":"Deposit","status":"PendingScreening","sub_status":"PendingCoboKYTCheck","failed_reason":null,"chain_id":"TRON","token_id":"TRON_USDT","asset_id":null,"source":{"source_type":"DepositFromAddress","address":"TSource11111111111111111111111111111"},"destination":{"destination_type":"DepositToAddress","address":"TDestination111111111111111111111111"},"result":null,"fee":null,"initiator":null,"initiator_type":"Blockchain","confirmed_num":0,"confirming_threshold":19,"transaction_hash":"5555555555555555555555555555555555555555555555555555555555555555","block_info":null,"raw_tx_info":null,"replacement":null,"category":[],"cobo_category":[],"description":null,"is_loop":false,"extra":null,"fueling_info":null,"timeline":[{"status":"PendingScreening","finished":false,"finished_timestamp":null}],"created_timestamp":1784563000000,"updated_timestamp":1784563000000}
+```
+
+### EVM native-asset withdrawal example
+
+```json
+{"transaction_id":"66666666-6666-4666-8666-666666666666","cobo_id":null,"request_id":"withdrawal-20260721-000","wallet_id":"44444444-4444-4444-8444-444444444444","type":"Withdrawal","status":"Submitted","sub_status":null,"failed_reason":null,"chain_id":"ETH","token_id":"ETH","asset_id":null,"source":{"source_type":"Org-Controlled","wallet_id":"44444444-4444-4444-8444-444444444444","address":"0x3333333333333333333333333333333333333333"},"destination":{"destination_type":"Address","address":"0x4444444444444444444444444444444444444444","amount":"0.10000000"},"result":null,"fee":null,"initiator":"operator@example.com","initiator_type":"API","confirmed_num":0,"confirming_threshold":12,"transaction_hash":null,"block_info":null,"raw_tx_info":null,"replacement":null,"category":[],"cobo_category":[],"description":"Treasury withdrawal","is_loop":false,"extra":null,"fueling_info":null,"timeline":[{"status":"Submitted","finished":false,"finished_timestamp":null}],"created_timestamp":1784563100000,"updated_timestamp":1784563100000}
+```
+
+
+## `wallets.transaction.updated`
+
+This event is emitted when transaction data changes, including status or confirmation progress. A transition to a terminal outcome also produces an `updated` event, in addition to the corresponding `succeeded` or `failed` event. Subscribe to `updated` to observe all lifecycle changes; use the terminal events when your workflow needs an explicit outcome signal.
+
+### EVM token deposit example
+
+```json
+{"transaction_id":"11111111-1111-4111-8111-111111111111","cobo_id":"202607210001","request_id":null,"wallet_id":"22222222-2222-4222-8222-222222222222","type":"Deposit","status":"Confirming","sub_status":"PendingBlockConfirmations","failed_reason":null,"chain_id":"ETH","token_id":"ETH_USDT","asset_id":null,"source":{"source_type":"DepositFromAddress","address":"0x1111111111111111111111111111111111111111"},"destination":{"destination_type":"DepositToAddress","address":"0x2222222222222222222222222222222222222222"},"result":null,"fee":null,"initiator":null,"initiator_type":"Blockchain","confirmed_num":4,"confirming_threshold":12,"transaction_hash":"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","block_info":{"block_number":24001234,"block_timestamp":1784563200000,"block_hash":"0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"},"raw_tx_info":null,"replacement":null,"category":[],"cobo_category":[],"description":null,"is_loop":false,"extra":null,"fueling_info":null,"timeline":[{"status":"Confirming","finished":false,"finished_timestamp":null}],"created_timestamp":1784563180000,"updated_timestamp":1784563200000}
+```
+
+### UTXO native-asset withdrawal example
+
+```json
+{"transaction_id":"33333333-3333-4333-8333-333333333333","cobo_id":"202607210002","request_id":"withdrawal-20260721-001","wallet_id":"44444444-4444-4444-8444-444444444444","type":"Withdrawal","status":"Broadcasting","sub_status":"Broadcasting","failed_reason":null,"chain_id":"BTC","token_id":"BTC","asset_id":null,"source":{"source_type":"Org-Controlled","wallet_id":"44444444-4444-4444-8444-444444444444","address":"bc1qsource000000000000000000000000000000000"},"destination":{"destination_type":"Address","address":"bc1qdestination0000000000000000000000000000","amount":"0.01000000"},"result":null,"fee":{"fee_type":"UTXO","token_id":"BTC","fee_used":"0.00001000"},"initiator":"operator@example.com","initiator_type":"API","confirmed_num":0,"confirming_threshold":6,"transaction_hash":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc","block_info":null,"raw_tx_info":{"used_nonce":null,"raw_tx":"0200000001...","unsigned_raw_tx":"0200000001...","selected_utxos":[{"tx_hash":"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd","vout_n":0}],"utxo_changes":[{"address":"bc1qchange000000000000000000000000000000000","value":"0.00499000","token_id":"BTC"}]},"replacement":null,"category":[],"cobo_category":[],"description":"Treasury withdrawal","is_loop":false,"extra":null,"fueling_info":null,"timeline":[{"status":"Broadcasting","finished":false,"finished_timestamp":null}],"created_timestamp":1784563300000,"updated_timestamp":1784563320000}
+```
+
+
+## `wallets.transaction.succeeded`
+
+This event is emitted when the transaction reaches the successful terminal state. For deposit reconciliation, see [When to credit a deposit](/v2/guides/transactions/status#when-to-credit-a-deposit).
+
+### UTXO native-asset deposit example
+
+```json
+{"transaction_id":"77777777-7777-4777-8777-777777777777","cobo_id":"202607210003","request_id":null,"wallet_id":"22222222-2222-4222-8222-222222222222","type":"Deposit","status":"Completed","sub_status":null,"failed_reason":null,"chain_id":"BTC","token_id":"BTC","asset_id":null,"source":{"source_type":"DepositFromAddress","address":"bc1qsource111111111111111111111111111111111"},"destination":{"destination_type":"DepositToAddress","address":"bc1qdestination1111111111111111111111111111"},"result":null,"fee":null,"initiator":null,"initiator_type":"Blockchain","confirmed_num":6,"confirming_threshold":6,"transaction_hash":"7777777777777777777777777777777777777777777777777777777777777777","block_info":{"block_number":900001,"block_timestamp":1784563400000,"block_hash":"8888888888888888888888888888888888888888888888888888888888888888"},"raw_tx_info":null,"replacement":null,"category":[],"cobo_category":[],"description":null,"is_loop":false,"extra":null,"fueling_info":null,"timeline":[{"status":"Confirming","finished":true,"finished_timestamp":1784563400000},{"status":"Completed","finished":false,"finished_timestamp":null}],"created_timestamp":1784563340000,"updated_timestamp":1784563400000}
+```
+
+### TRON token withdrawal example
+
+```json
+{"transaction_id":"88888888-8888-4888-8888-888888888888","cobo_id":"202607210004","request_id":"withdrawal-20260721-002","wallet_id":"44444444-4444-4444-8444-444444444444","type":"Withdrawal","status":"Completed","sub_status":null,"failed_reason":null,"chain_id":"TRON","token_id":"TRON_USDT","asset_id":null,"source":{"source_type":"Org-Controlled","wallet_id":"44444444-4444-4444-8444-444444444444","address":"TSource22222222222222222222222222222"},"destination":{"destination_type":"Address","address":"TDestination222222222222222222222222","amount":"25.000000"},"result":null,"fee":{"fee_type":"Fixed","token_id":"TRON","fee_used":"2.000000"},"initiator":"operator@example.com","initiator_type":"API","confirmed_num":19,"confirming_threshold":19,"transaction_hash":"9999999999999999999999999999999999999999999999999999999999999999","block_info":{"block_number":76001234,"block_timestamp":1784563500000,"block_hash":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},"raw_tx_info":{"used_nonce":null,"raw_tx":"0a02...","unsigned_raw_tx":"0a02...","selected_utxos":null,"utxo_changes":null},"replacement":null,"category":[],"cobo_category":[],"description":"Treasury withdrawal","is_loop":false,"extra":null,"fueling_info":null,"timeline":[{"status":"Broadcasting","finished":true,"finished_timestamp":1784563460000},{"status":"Completed","finished":false,"finished_timestamp":null}],"created_timestamp":1784563440000,"updated_timestamp":1784563500000}
+```
+
+
+## `wallets.transaction.failed`
+
+This event is emitted when the transaction reaches `Failed`, `Rejected`, or `Canceled`. These terminal outcomes also appear through `wallets.transaction.updated`.
+
+### Rejected EVM native-asset deposit example
+
+```json
+{"transaction_id":"99999999-9999-4999-8999-999999999999","cobo_id":"202607210005","request_id":null,"wallet_id":"22222222-2222-4222-8222-222222222222","type":"Deposit","status":"Rejected","sub_status":"RejectedByCoboKYT","failed_reason":"The deposit did not pass transaction screening.","chain_id":"ETH","token_id":"ETH","asset_id":null,"source":{"source_type":"DepositFromAddress","address":"0x5555555555555555555555555555555555555555"},"destination":{"destination_type":"DepositToAddress","address":"0x2222222222222222222222222222222222222222"},"result":null,"fee":null,"initiator":null,"initiator_type":"Blockchain","confirmed_num":0,"confirming_threshold":12,"transaction_hash":"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee","block_info":null,"raw_tx_info":null,"replacement":null,"category":[],"cobo_category":[],"description":null,"is_loop":false,"extra":null,"fueling_info":null,"timeline":[{"status":"Rejected","finished":false,"finished_timestamp":null}],"created_timestamp":1784563600000,"updated_timestamp":1784563620000}
+```
+
+### Failed TRON native-asset withdrawal example
+
+```json
+{"transaction_id":"aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa","cobo_id":"202607210006","request_id":"withdrawal-20260721-003","wallet_id":"44444444-4444-4444-8444-444444444444","type":"Withdrawal","status":"Failed","sub_status":"FailedOnChain","failed_reason":"The transaction failed on-chain.","chain_id":"TRON","token_id":"TRON","asset_id":null,"source":{"source_type":"Org-Controlled","wallet_id":"44444444-4444-4444-8444-444444444444","address":"TSource33333333333333333333333333333"},"destination":{"destination_type":"Address","address":"TDestination333333333333333333333333","amount":"10.000000"},"result":null,"fee":{"fee_type":"Fixed","token_id":"TRON","fee_used":"1.000000"},"initiator":"operator@example.com","initiator_type":"API","confirmed_num":0,"confirming_threshold":19,"transaction_hash":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","block_info":null,"raw_tx_info":{"used_nonce":null,"raw_tx":"0a02...","unsigned_raw_tx":"0a02...","selected_utxos":null,"utxo_changes":null},"replacement":null,"category":[],"cobo_category":[],"description":"Treasury withdrawal","is_loop":false,"extra":null,"fueling_info":null,"timeline":[{"status":"Failed","finished":false,"finished_timestamp":null}],"created_timestamp":1784563700000,"updated_timestamp":1784563720000}
+```
diff --git a/v2/guides/webhooks-callbacks/webhook-event-type.mdx b/v2/guides/webhooks-callbacks/webhook-event-type.mdx
index 0acafca6..188877a5 100644
--- a/v2/guides/webhooks-callbacks/webhook-event-type.mdx
+++ b/v2/guides/webhooks-callbacks/webhook-event-type.mdx
@@ -31,22 +31,22 @@ For payment webhook events, please refer to [Order Status and Events](/v2/paymen
- wallets.transaction.created |
+ wallets.transaction.created |
Transaction |
A transaction has been detected on the blockchain, generating a transaction record. This event does not indicate that the transaction was successful. |
- wallets.transaction.updated |
+ wallets.transaction.updated |
Transaction |
- There are changes to a transaction's status or confirmation numbers.The wallets.transaction.updated event covers the entire lifecycle of a transaction, including creation, completion, and failure. If you want to track every status change, you need only subscribe to this event. |
+ There are changes to a transaction's status, confirmation progress, or other transaction data.A terminal transition produces this event in addition to wallets.transaction.succeeded or wallets.transaction.failed. Subscribe to wallets.transaction.updated to observe every lifecycle change. |
- wallets.transaction.succeeded |
+ wallets.transaction.succeeded |
Transaction |
A transaction has been successfully completed. |
- wallets.transaction.failed |
+ wallets.transaction.failed |
Transaction |
A transaction failed. |
@@ -109,22 +109,22 @@ For payment webhook events, please refer to [Order Status and Events](/v2/paymen
- wallets.mpc.tss_request.created |
+ wallets.mpc.tss_request.created |
TSSRequest |
A TSS request is created. |
- wallets.mpc.tss_request.updated |
+ wallets.mpc.tss_request.updated |
TSSRequest |
There are changes to the status of a TSS request. |
- wallets.mpc.tss_request.succeeded |
+ wallets.mpc.tss_request.succeeded |
TSSRequest |
The requested action has been successfully completed. |
- wallets.mpc.tss_request.failed |
+ wallets.mpc.tss_request.failed |
TSSRequest |
The requested action failed. |
@@ -152,11 +152,26 @@ For payment webhook events, please refer to [Order Status and Events](/v2/paymen
WalletInfo |
A new wallet has been created. |
+
+ wallets.updated |
+ WalletInfo |
+ A change to the wallet record has been saved and its current wallet information is available. |
+
mpc_vaults.created |
MPCVault |
A new MPC vault has been created. |
+
+ mpc_vaults.updated |
+ MPCVault |
+ An existing MPC vault's configuration or metadata has changed. |
+
+
+ mpc_vaults.deleted |
+ MPCVault |
+ An MPC vault has been deleted and is no longer available for wallet operations. |
+
@@ -297,4 +312,4 @@ For a complete introduction of the webhook event data and its data structure, re
Switch between the event data types to view the data structure of each event data type.
-Additionally, you can view all webhook events in your organization on **Cobo Portal** > **Developer**> **Webhook Events**.
\ No newline at end of file
+Additionally, you can view all webhook events in your organization on **Cobo Portal** > **Developer**> **Webhook Events**.
diff --git a/v2/guides/webhooks-callbacks/webhook-operations.mdx b/v2/guides/webhooks-callbacks/webhook-operations.mdx
new file mode 100644
index 00000000..15eb70ba
--- /dev/null
+++ b/v2/guides/webhooks-callbacks/webhook-operations.mdx
@@ -0,0 +1,43 @@
+---
+title: "Webhook and callback operations"
+lang: "en"
+description: "Handle common webhook and callback scenarios, recover failed deliveries, and reconcile state when delivery history is unavailable."
+---
+
+import WaasSkillReminder from '/snippets/waas_skill_reminder.mdx';
+
+
+
+## Overview
+
+Use this guide for operational decisions and recovery. See [Webhook event types](/v2/guides/webhooks-callbacks/webhook-event-type) for the catalog, [Transaction event payload](/v2/guides/webhooks-callbacks/transaction-events) and [MPC TSS request event payload](/v2/guides/webhooks-callbacks/mpc-tss-request-events) for payload contracts, and [Set up a callback or webhook endpoint](/v2/guides/webhooks-callbacks/set-up-endpoint) for endpoint mechanics.
+
+## Common scenarios
+
+| Scenario | What you receive | Recommended handling |
+| --- | --- | --- |
+| Deposit crediting | `created`, progress through `updated`, then `succeeded` or `failed`. | Follow [When to credit a deposit](/v2/guides/transactions/status#when-to-credit-a-deposit). |
+| Withdrawal progress and outcome | `updated` can report `PendingAuthorization`, `PendingSignature`, `Broadcasting`, and `Confirming`; a terminal outcome also produces `succeeded` or `failed`. | Use `updated` for UI progress and terminal events for outcome reconciliation. |
+| Rejected or canceled transaction | `wallets.transaction.failed` for `Failed`, `Rejected`, or `Canceled`, in addition to `updated`. | Use the [failed-event contract](/v2/guides/webhooks-callbacks/transaction-events#walletstransactionfailed) to handle these outcomes consistently. |
+| AutoSweep | A transaction whose `cobo_category` includes `AutoSweep`. | Branch on `cobo_category`; see [Cobo-defined categories](/v2/guides/transactions/manage-transactions#cobo-defined-categories). |
+| Compliance monitoring | Compliance status events and follow-up transactions categorized as `ComplianceRefund`, `ComplianceIsolate`, `ScreenAppRefund`, or `ScreenAppIsolate`. | Track the [compliance events](/v2/guides/webhooks-callbacks/webhook-event-type#compliance-events), then reconcile any categorized transaction independently. |
+| Portal-created activity | Portal-initiated transactions and registrations emit the same subscribed event types as API-initiated activity. | Apply the same event handlers regardless of where the activity was initiated. |
+| Wallet scopes | During endpoint registration, you choose the wallets and event types in scope. | Register only the scopes the endpoint is prepared to process. |
+| Out-of-order delivery | Events can arrive in a different order from their generation order. | Reconstruct state from `status`, `sub_status`, and timestamps, not arrival order. See [Respond to the API request](/v2/guides/webhooks-callbacks/set-up-endpoint#respond-to-the-api-request). |
+| Idempotency | Retries and multiple lifecycle events can repeat a logical state. | Follow the [idempotency guidance](/v2/guides/webhooks-callbacks/set-up-endpoint#important-notes). |
+| API reconciliation | Webhook or callback state is ambiguous, missed, or no longer queryable. | Use [Get transaction information](/v2/api-references/transactions/get-transaction-information) or [List all transactions](/v2/api-references/transactions/list-all-transactions). |
+
+## Recover missed or failed events
+
+1. Find affected webhook events with [List all webhook events](/v2/api-references/developers--webhooks/list-all-webhook-events). Filter by endpoint, `status`, and `type`, and continue with the `before` or `after` cursor. For callbacks, use [List all callback messages](/v2/api-references/developers/list-all-callback-messages).
+2. Inspect each attempt with [List webhook event logs](/v2/api-references/developers--webhooks/list-webhook-event-logs), or open the callback message's delivery logs in Cobo Portal.
+3. Fix the endpoint before resending. Use [Common delivery failures](/v2/guides/webhooks-callbacks/set-up-endpoint#common-delivery-failures) to diagnose common response, reachability, redirect, and TLS failures.
+4. Manual webhook-event retry requires the `WEBHOOK RESEND` permission in Cobo Portal. For a webhook event, click **Retry** in Cobo Portal or call [Retry event](/v2/api-references/developers--webhooks/retry-event). For a callback message, call [Retry callback message](/v2/api-references/developers/retry-callback-message).
+5. Deduplicate the resent delivery by its event or message ID according to the [idempotency guidance](/v2/guides/webhooks-callbacks/set-up-endpoint#important-notes).
+6. Reconcile the final transaction state with [Get transaction information](/v2/api-references/transactions/get-transaction-information) or [List all transactions](/v2/api-references/transactions/list-all-transactions). Successful redelivery confirms receipt, not the transaction outcome.
+
+This workflow applies while the event or message remains available through its list and log operations.
+
+## When history has expired
+
+When an event or callback message is no longer queryable, reconcile current state directly with [Get transaction information](/v2/api-references/transactions/get-transaction-information) or [List all transactions](/v2/api-references/transactions/list-all-transactions). Preserve your own idempotency and correlation records so reconciliation does not depend on delivery history alone.
diff --git a/v2_cn/guides/transactions/status.mdx b/v2_cn/guides/transactions/status.mdx
index 2657ac36..5f583b52 100644
--- a/v2_cn/guides/transactions/status.mdx
+++ b/v2_cn/guides/transactions/status.mdx
@@ -288,6 +288,16 @@ WaaS 2.0 定义了各种交易状态和子状态,以反映不同的处理阶
处于 `Confirming` 状态且子状态为 `PendingBlockConfirmations` 的交易,正在等待其所在链所需数量的区块确认。这是正常处理过程的一部分,并不表示交易卡住。所需的确认数量和预计确认时间因链而异。
+## 何时为充币入账
+
+请仅将 `Confirming` 及其产生的 `wallets.transaction.updated` 事件视为进度信息。处于 `Confirming` 的区块链充币尚不适合入账。交易的 `confirmed_num` 必须达到 `confirming_threshold`,之后才能完成确认处理。
+
+内部成功结果对外显示为 `Completed` 状态和 [`wallets.transaction.succeeded`](/v2_cn/guides/webhooks-callbacks/transaction-events#walletstransactionsucceeded) 事件。请在收到该事件后入账,或使用 [Get transaction information](/v2/api-references/transactions/get-transaction-information) 或 [List all transactions](/v2/api-references/transactions/list-all-transactions) 验证状态为 `Completed` 后入账。请按照 [Endpoint 处理说明](/v2_cn/guides/webhooks-callbacks/set-up-endpoint#注意事项)进行幂等对账。
+
+
+此入账说明仅适用于区块链充币,不适用于 `MessageSign` 或其他不涉及资金转移的交易类型。
+
+
## 可用操作
您可以根据交易状态执行以下操作:
@@ -302,4 +312,4 @@ WaaS 2.0 定义了各种交易状态和子状态,以反映不同的处理阶
有关被替换交易的状态如何变化的详细信息,请参阅 [RBF (Replace-By-Fee) 交易生命周期](/v2_cn/guides/transactions/rbf-transaction-lifecycle)。
-有关详细信息,请参阅[管理交易](/v2_cn/guides/transactions/manage-transactions)。
\ No newline at end of file
+有关详细信息,请参阅[管理交易](/v2_cn/guides/transactions/manage-transactions)。
diff --git a/v2_cn/guides/transactions/transaction-fields.mdx b/v2_cn/guides/transactions/transaction-fields.mdx
new file mode 100644
index 00000000..51243dcb
--- /dev/null
+++ b/v2_cn/guides/transactions/transaction-fields.mdx
@@ -0,0 +1,38 @@
+---
+title: "Transaction 字段参考"
+lang: "zh-hans"
+description: "通过理解标识、方向字段、替换关联和 Cobo 定义的分类来对账 Transaction。"
+---
+
+import WaasSkillReminder from '/snippets/waas_skill_reminder_cn.mdx';
+
+
+
+## 概述
+
+本文用于区分外观相似但对账用途不同的 Transaction 字段。完整 Payload 结构请参阅 [Transaction 事件 Payload](/v2_cn/guides/webhooks-callbacks/transaction-events),方向结构请参阅 [Transaction 来源与目标](/v2_cn/guides/transactions/sources-and-destinations),替换行为请参阅 [RBF 交易生命周期](/v2_cn/guides/transactions/rbf-transaction-lifecycle),完整 `cobo_category` 表请参阅[管理交易](/v2_cn/guides/transactions/manage-transactions#cobo-定义的交易类别)。
+
+## 字段字典
+
+| 字段 | 含义和条件 | 建议的对账用途 |
+| --- | --- | --- |
+| `chain_id` | 标识区块链网络。链上交易包含此字段,它与下列资产标识不同。 | 与 `token_id` 配合,用于链相关的处理分发。 |
+| `token_id` | 标识 Cobo 目录中的链上代币。原生资产与合约代币使用不同值;同一经济资产在不同链上也使用不同的 `token_id`。 | 用于代币余额、精度和链上转账处理。 |
+| `asset_id` | 标识 Exchange Wallet 中的资产,该余额不使用链上 `token_id` 表示。 | 用于交易所账户对账;不要将其视为网络标识。 |
+| `request_id` | 客户端请求的幂等和关联标识。充币等没有客户端请求的交易中,此字段为 `null`。 | 将 Webhook 或 API 结果与本地出账请求关联。 |
+| `source` | 由 `source_type` 决定结构。充币时通常表示外部发送方;提币时表示发送钱包。 | 判断方向以及资产移出的账户或地址。 |
+| `destination` | 由 `destination_type` 决定结构。充币时表示收款钱包地址;提币时表示外部目标。 | 判断方向以及接收操作的账户、地址、合约或签名输入。 |
+| `replaced_by_transaction_hash` | 仅在原交易被替换后出现在其 `replacement` 中,指向新交易哈希。 | 从原交易跟踪实际生效的 RBF 交易。 |
+| `cobo_category` | 适用时包含 Cobo 定义的运营分类。高信号值包括 `AutoSweep`、`ComplianceRefund`、`ComplianceIsolate`、`ScreenAppRefund` 和 `ScreenAppIsolate`。 | 根据明确分类处理系统活动,不要从地址推断。 |
+
+## 示例映射
+
+| 资产 | `chain_id` | `token_id` | `asset_id` |
+| --- | --- | --- | --- |
+| Ethereum 原生资产 | `ETH` | `ETH` | `ETH` |
+| Ethereum 上的 USDT | `ETH` | `ETH_USDT` | `USDT` |
+| TRON 原生资产 | `TRON` | `TRON` | `TRON` |
+| TRON 上的 USDT | `TRON` | `TRON_USDT` | `USDT` |
+| Bitcoin | `BTC` | `BTC` | `BTC` |
+
+`asset_id` 列显示对应的 Exchange Wallet 资产标识。Exchange Wallet 交易返回 `asset_id`,而不是链上 `chain_id` 和 `token_id` 组合。
diff --git a/v2_cn/guides/webhooks-callbacks/mpc-tss-request-events.mdx b/v2_cn/guides/webhooks-callbacks/mpc-tss-request-events.mdx
new file mode 100644
index 00000000..8f545462
--- /dev/null
+++ b/v2_cn/guides/webhooks-callbacks/mpc-tss-request-events.mdx
@@ -0,0 +1,71 @@
+---
+title: "MPC TSS request 事件 Payload"
+lang: "zh-hans"
+description: "了解 Portal 密钥生成和重新共享 Webhook 事件共用的 TSSRequest Payload。"
+---
+
+import WaasSkillReminder from '/snippets/waas_skill_reminder_cn.mdx';
+
+
+
+## 概述
+
+`wallets.mpc.tss_request.*` 事件系列用于报告在 Cobo Portal 发起的 MPC 密钥生成和重新共享请求。四种事件使用相同的 `TSSRequest` Payload。事件目录请参阅 [Webhook 事件类型](/v2_cn/guides/webhooks-callbacks/webhook-event-type)。
+
+## TSSRequest Payload 字段
+
+| 字段 | 类型 | 是否有条件 | 说明 |
+| --- | --- | --- | --- |
+| `tss_request_id` | string | 否 | TSS 请求的唯一标识。 |
+| `source_key_share_holder_group` | object, nullable | 是 | 重新共享请求的现有来源组。初始密钥生成请求不包含此对象。 |
+| `source_key_share_holder_group.key_share_holder_group_id` | string | 父对象存在时 | 来源密钥分片持有人组的标识。 |
+| `source_key_share_holder_group.tss_node_ids` | array of strings | 父对象存在时 | 来源组中参与操作的 TSS Node 标识。 |
+| `target_key_share_holder_group_id` | string | 否 | 请求创建或更新的目标组。 |
+| `type` | string | 否 | 请求类型,例如 `KeyGen` 或 `KeyGenFromKeyGroup`。 |
+| `status` | string | 否 | 请求的当前状态。 |
+| `description` | string, nullable | 是 | 请求附带的描述;未提供时为 `null`。 |
+| `created_timestamp` | integer | 否 | 请求创建时间,Unix 毫秒时间戳。 |
+
+
+## `wallets.mpc.tss_request.created`
+
+请求记录进入初始状态时触发。
+
+### 初始密钥生成示例
+
+```json
+{"tss_request_id":"20260721114129000132315000003970","source_key_share_holder_group":null,"target_key_share_holder_group_id":"11111111-1111-4111-8111-111111111111","type":"KeyGen","status":"PendingKeyHolderConfirmation","description":"Create the first Main Group","created_timestamp":1784563200000}
+```
+
+
+## `wallets.mpc.tss_request.updated`
+
+密钥持有人操作和 MPC 处理期间,请求进入不同中间状态时触发。
+
+### 重新共享更新示例
+
+```json
+{"tss_request_id":"20260721114129000132315000003971","source_key_share_holder_group":{"key_share_holder_group_id":"22222222-2222-4222-8222-222222222222","tss_node_ids":["cobo5yb7BNEBwwp5XXedbhnzQfvQtp132W4dH4Jz4x4eDp4KA"]},"target_key_share_holder_group_id":"33333333-3333-4333-8333-333333333333","type":"KeyGenFromKeyGroup","status":"MPCProcessing","description":null,"created_timestamp":1784563300000}
+```
+
+
+## `wallets.mpc.tss_request.succeeded`
+
+请求进入终态 `Success` 时触发。
+
+### 重新共享成功示例
+
+```json
+{"tss_request_id":"20260721114129000132315000003972","source_key_share_holder_group":{"key_share_holder_group_id":"22222222-2222-4222-8222-222222222222","tss_node_ids":["cobo5yb7BNEBwwp5XXedbhnzQfvQtp132W4dH4Jz4x4eDp4KA"]},"target_key_share_holder_group_id":"33333333-3333-4333-8333-333333333333","type":"KeyGenFromKeyGroup","status":"Success","description":null,"created_timestamp":1784563300000}
+```
+
+
+## `wallets.mpc.tss_request.failed`
+
+请求进入 `KeyHolderConfirmationFailed` 或 `KeyGeneratingFailed` 时触发。
+
+### 密钥生成失败示例
+
+```json
+{"tss_request_id":"20260721114129000132315000003973","source_key_share_holder_group":null,"target_key_share_holder_group_id":"11111111-1111-4111-8111-111111111111","type":"KeyGen","status":"KeyGeneratingFailed","description":"Create the first Main Group","created_timestamp":1784563200000}
+```
diff --git a/v2_cn/guides/webhooks-callbacks/set-up-endpoint.mdx b/v2_cn/guides/webhooks-callbacks/set-up-endpoint.mdx
index ae7e44c0..501cbe5a 100644
--- a/v2_cn/guides/webhooks-callbacks/set-up-endpoint.mdx
+++ b/v2_cn/guides/webhooks-callbacks/set-up-endpoint.mdx
@@ -19,6 +19,18 @@ Webhook 事件和 Callback 消息对于确保 WaaS 服务与您的 App 之间的
创建 Endpoint 后,您需要在服务器上实现逻辑以处理 Webhook 事件或 Callback 消息,包括解析 API 请求、验证签名、响应请求以及在必要时添加其他处理逻辑。
+### Callback 消息 Payload
+
+Callback 消息的 `data` 字段与 Transaction Webhook 事件使用相同的 `Transaction` 结构。完整字段表请参阅 [Transaction 事件 Payload](/v2_cn/guides/webhooks-callbacks/transaction-events)。这些值表示 Endpoint 必须返回 `ok` 或 `deny` 时已知的信息;不要将 Callback 视为交易终态。
+
+| 字段 | Callback 时的填充情况 |
+| --- | --- |
+| `cobo_id` | Cobo 尚未分配跟踪标识时可以为 `null`。 |
+| `asset_id` | Exchange Wallet 资产的值可用时填充,否则为 `null`。链上钱包交易改用 `token_id`。 |
+| `result` | 在 `MessageSign` 结果可用前为 `null`;对于不产生签名结果的交易类型始终为 `null`。 |
+
+其他可选字段取决于交易类型和值是否可用。完整结构请参阅 [Transaction 事件 Payload](/v2_cn/guides/webhooks-callbacks/transaction-events),对账语义请参阅 [Transaction 字段参考](/v2_cn/guides/transactions/transaction-fields)。如需后续状态,请通过 API 查询交易或处理后续 Transaction 事件。
+
### 验证签名
为了防止未经授权的访问,当您收到 Webhook 事件或 Callback 消息时,您需要通过验证签名来验证 API 请求的真实性。
@@ -80,7 +92,8 @@ Ed25519 签名是基于 HTTP 请求包体的原始字节精确计算的。您必
正确响应 Webhook 事件和 Callback 消息对于确保 Webhook 和 Callback 按预期处理至关重要。本节描述了 Webhook 和 Callback Endpoint 的预期响应。
-#### Webhook 事件
+
+#### Webhook 投递策略
当您的 Webhook Endpoint 收到 Webhook 事件时,它应该响应状态码 `200` 或 `201` 以指示事件已成功接收和处理。一旦发送此响应,WaaS 服务将停止重试发送事件,事件状态将变为**已送达**。
@@ -94,12 +107,15 @@ Cobo 不保证事件将按生成顺序交付。例如,创建转账将生成以
您的 Endpoint 不应假设事件将按此顺序到达。
-#### Callback 消息
+
+#### Callback 投递策略
当您的 Callback Endpoint 收到 Callback 消息时,它应该响应状态码 `200` 或 `201` 和响应包体 `ok` 或 `deny` 以指示交易批准或拒绝。一旦发送此响应,WaaS 服务将停止重试发送消息,Callback 消息状态将变为**已送达**。
如果 Callback Endpoint 没有响应,响应状态码不是 `200` 或 `201`,或响应包体不包含 `ok` 或 `deny`,WaaS 服务将继续重试发送消息。如果重试次数达到 30 次,WaaS 服务将停止发送消息,Callback 消息状态将变为**发送失败**。您可以使用 [Retry callback message](/v2/api-references/developers/retry-callback-message) 来重新发送消息。
+Webhook 事件和 Callback 消息记录会提供投递 `status` 和重试信息。对于 Webhook,请使用 [List webhook event logs](/v2/api-references/developers--webhooks/list-webhook-event-logs) 检查特定 Endpoint 的每次投递。您也可以通过下方 Portal 路径查看每次 Webhook 或 Callback 投递的响应状态和包体。完整恢复流程请参阅 Webhook 和 Callback 运营指南中的[恢复遗漏或失败的事件](/v2_cn/guides/webhooks-callbacks/webhook-operations#恢复遗漏或失败的事件)。
+
### 常见投递失败原因
下表列出了 Callback 消息和 Webhook 事件最常见的投递失败原因及修复方法。
@@ -126,6 +142,10 @@ Cobo 不保证事件将按生成顺序交付。例如,创建转账将生成以
## 进阶用法
+### 多个 Endpoint
+
+如果您运营多个 Webhook Endpoint,或同时运营 Webhook Endpoint 和 Callback Endpoint,请分别检查每个 Endpoint 的事件或消息记录以及特定于该 Endpoint 的投递日志。不要假设不同 Endpoint 共用一个投递状态。请按照[注意事项](#注意事项)让每个 Endpoint 的处理程序保持幂等。
+
### 使用钱包级别的 Webhook 分发
在某些业务场景中,您可能需要为不同的钱包设置不同的 Webhook 处理逻辑。例如:
@@ -175,4 +195,4 @@ async def handle_webhook(
- 在接收 Webhook 事件时,您的 Endpoint 应该首先快速返回正确的状态码,然后异步处理任何后续处理,以防止超时。
- 由于 Webhook 事件存在重试机制,Webhook Endpoint 有时会多次接收到相同的事件。为了防止重复事件处理,请记录已处理的 Event ID,Transaction Hash 或 Transaction ID,并避免处理已记录的事件。
-
\ No newline at end of file
+
diff --git a/v2_cn/guides/webhooks-callbacks/transaction-events.mdx b/v2_cn/guides/webhooks-callbacks/transaction-events.mdx
new file mode 100644
index 00000000..a5eb3f5a
--- /dev/null
+++ b/v2_cn/guides/webhooks-callbacks/transaction-events.mdx
@@ -0,0 +1,154 @@
+---
+title: "Transaction 事件 Payload"
+lang: "zh-hans"
+description: "了解四种 wallets.transaction.* Webhook 事件共用的 Transaction Payload 结构。"
+---
+
+import WaasSkillReminder from '/snippets/waas_skill_reminder_cn.mdx';
+
+
+
+## 概述
+
+`wallets.transaction.created`、`wallets.transaction.updated`、`wallets.transaction.succeeded` 和 `wallets.transaction.failed` 使用相同的 `Transaction` Payload 结构。本文统一说明该结构,并在各事件章节中说明不同的触发条件和生命周期含义。
+
+如需查看事件目录,请参阅 [Webhook 事件类型](/v2_cn/guides/webhooks-callbacks/webhook-event-type)。如需了解 `chain_id`、`token_id` 和 `asset_id` 等字段的对账用途,请参阅 [Transaction 字段参考](/v2_cn/guides/transactions/transaction-fields)。
+
+## Transaction Payload 字段
+
+| 字段 | 类型 | 是否有条件 | 说明 |
+| --- | --- | --- | --- |
+| `transaction_id` | string | 否 | Cobo 为交易记录分配的唯一标识。 |
+| `cobo_id` | string, nullable | 是 | Cobo 的交易跟踪标识;分配前可以为 `null`。 |
+| `request_id` | string, nullable | 是 | 创建交易的请求所使用的自定义标识。充币等没有客户端请求的交易为 `null`。 |
+| `wallet_id` | string | 否 | 充币交易的目标钱包,或出账交易的来源钱包。 |
+| `type` | string | 否 | 交易类型,例如 `Deposit`、`Withdrawal`、`ContractCall` 或 `MessageSign`。 |
+| `status` | string | 否 | 对外展示的生命周期状态。请参阅 [Transaction 状态和子状态](/v2_cn/guides/transactions/status)。 |
+| `sub_status` | string, nullable | 是 | `status` 内更具体的处理状态(如有)。 |
+| `failed_reason` | string, nullable | 是 | 未完成交易的失败详情。 |
+| `chain_id` | string, nullable | 是 | 链上交易所在的区块链标识。 |
+| `token_id` | string, nullable | 是 | 链上资产在 Cobo 代币目录中的标识。 |
+| `asset_id` | string, nullable | 是 | Exchange Wallet 的资产标识;该钱包类型使用此字段代替 `token_id`。 |
+| `source` | object | 否 | 交易来源。`source_type` 决定结构,其他字段可包括 `wallet_id`、`address`、`addresses` 或 `included_utxos`。 |
+| `destination` | object | 否 | 交易目标。`destination_type` 决定结构,其他字段可包括 `wallet_id`、`address`、`amount`、`account_output`、`utxo_outputs`,以及合约调用或消息签名输入。 |
+| `result` | object, nullable | 是 | 已完成 `MessageSign` 的结果。签名结果包含 `result_type` 和 `signature`;其他交易类型返回 `null`。 |
+| `fee` | object, nullable | 是 | 确定后返回的网络费用详情。字段由 `fee_type` 决定,可包括 `token_id`、`fee_used`、`estimated_fee_used` 和费用上限。 |
+| `initiator` | string, nullable | 是 | 可用时返回的发起人显示标识。 |
+| `initiator_type` | string, nullable | 是 | 可用时返回的交易发起渠道。 |
+| `confirmed_num` | integer, nullable | 是 | 当前已获得的链上确认数。 |
+| `confirming_threshold` | integer, nullable | 是 | 交易转为已确认前所需的确认数。 |
+| `transaction_hash` | string, nullable | 是 | 广播后返回的链上交易哈希。 |
+| `block_info` | object, nullable | 是 | 包含该交易的区块。交易被打包进区块前为 `null`。 |
+| `block_info.block_number` | integer | 父对象存在时 | 包含该交易的区块高度。 |
+| `block_info.block_timestamp` | integer | 父对象存在时 | 区块创建时间,Unix 毫秒时间戳。 |
+| `block_info.block_hash` | string | 父对象存在时 | 包含该交易的区块哈希。 |
+| `raw_tx_info` | object, nullable | 是 | 已构建的交易详情。原始交易数据可用前为 `null`。 |
+| `raw_tx_info.raw_tx` | string, nullable | 可用时 | 序列化的已签名交易数据。 |
+| `raw_tx_info.unsigned_raw_tx` | string, nullable | 可用时 | 签名前序列化的交易数据。 |
+| `raw_tx_info.used_nonce` | integer, nullable | 仅账户模型链 | 交易使用的 nonce。对于不使用账户 nonce 的链,此字段为 `null`。 |
+| `raw_tx_info.selected_utxos` | array of objects, nullable | 仅 UTXO 链 | UTXO 交易选中的输入。 |
+| `raw_tx_info.selected_utxos[].tx_hash` | string | `selected_utxos` 存在时 | 创建所选输出的交易哈希。 |
+| `raw_tx_info.selected_utxos[].vout_n` | integer | `selected_utxos` 存在时 | `tx_hash` 所标识交易中的输出索引。 |
+| `raw_tx_info.selected_utxos[].token_id` | string | `selected_utxos` 存在时 | 所选输出的代币标识。 |
+| `raw_tx_info.selected_utxos[].address` | string | `selected_utxos` 存在时 | 所选输出的所属地址。 |
+| `raw_tx_info.selected_utxos[].value` | string | `selected_utxos` 存在时 | 所选输出的代币单位数值。 |
+| `raw_tx_info.utxo_changes` | array of objects, nullable | 仅 UTXO 链 | UTXO 交易创建的找零输出。 |
+| `raw_tx_info.utxo_changes[].address` | string | `utxo_changes` 存在时 | 接收找零输出的地址。 |
+| `raw_tx_info.utxo_changes[].value` | string | `utxo_changes` 存在时 | 找零输出的代币单位数值。 |
+| `raw_tx_info.utxo_changes[].token_id` | string | `utxo_changes` 存在时 | 找零输出的代币标识。 |
+| `replacement` | object, nullable | 是 | RBF 关联信息。交易未替换其他交易且未被替换时为 `null`。 |
+| `replacement.replaced_by_type` | string, nullable | 仅原交易 | 对该交易执行的替换操作:`Drop`、`Resend` 或 `SpeedUp`。 |
+| `replacement.replaced_by_transaction_id` | string, nullable | 仅原交易 | 替换该交易的新交易的 Cobo 交易 ID。 |
+| `replacement.replaced_by_transaction_hash` | string, nullable | 仅原交易 | 替换该交易的新交易的链上哈希(可用后返回)。 |
+| `replacement.replaced_type` | string, nullable | 仅替换交易 | 该交易替换其他交易时使用的操作:`Drop`、`Resend` 或 `SpeedUp`。 |
+| `replacement.replaced_transaction_id` | string, nullable | 仅替换交易 | 被该交易替换的交易的 Cobo 交易 ID。 |
+| `replacement.replaced_transaction_hash` | string, nullable | 仅替换交易 | 被该交易替换的交易的链上哈希(可用后返回)。 |
+| `category` | array of strings, nullable | 是 | 自定义交易分类。 |
+| `cobo_category` | array of strings, nullable | 是 | Cobo 定义的运营分类,例如 `AutoSweep`。 |
+| `description` | string, nullable | 是 | 客户端提供的交易描述。 |
+| `is_loop` | boolean | 否 | 转账是否使用 Cobo Loop 而不是链上交易。 |
+| `extra` | array of strings, nullable | 是 | 适用时以字符串编码的额外结构化业务数据。 |
+| `fueling_info` | object, nullable | 是 | Fee Station 交易关联信息。未使用 Fee Station 时为 `null`。 |
+| `fueling_info.request_id` | string | 父对象存在时 | Fee Station 交易的请求标识。 |
+| `fueling_info.transaction_id` | string | 父对象存在时 | Fee Station 交易的 Cobo 交易 ID。 |
+| `fueling_info.main_transaction_id` | string, nullable | 仅费用交易记录 | 该记录所资助费用的父交易 Cobo 交易 ID。主交易不包含此字段。 |
+| `timeline` | array of objects, nullable | 是 | 交易经历的有序生命周期状态。 |
+| `timeline[].status` | string | `timeline` 存在时 | 该条目表示的生命周期状态,与顶层 `status` 字段使用相同的 Transaction 状态枚举。 |
+| `timeline[].finished` | boolean | `timeline` 存在时 | 该生命周期状态的处理是否已完成。 |
+| `timeline[].finished_timestamp` | integer, nullable | `timeline` 存在时 | 该生命周期状态完成的时间,Unix 毫秒时间戳。`finished` 为 `false` 时,此字段为 `null`。 |
+| `created_timestamp` | integer | 否 | 交易创建时间,Unix 毫秒时间戳。 |
+| `updated_timestamp` | integer | 否 | 最近一次交易更新时间,Unix 毫秒时间戳。 |
+
+如需查看所有 `source` 和 `destination` 结构,请参阅 [Transaction 来源与目标](/v2_cn/guides/transactions/sources-and-destinations)。费用变体和替换字段分别参见[预估交易费用](/v2_cn/guides/transactions/estimate-fees)和 [RBF 交易生命周期](/v2_cn/guides/transactions/rbf-transaction-lifecycle)。
+
+## 交易方向:充币与提币
+
+对于 `Deposit`,`wallet_id` 表示目标钱包,`source` 描述外部来源,`destination` 描述充币地址。对于 `Withdrawal`,`wallet_id` 和 `source` 表示发送钱包,`destination` 表示接收地址或账户输出。请结合 `type`、`source.source_type` 和 `destination.destination_type` 判断方向,不要仅根据地址推断。
+
+
+## `wallets.transaction.created`
+
+Cobo 首次记录交易时触发此事件。对于充币,该事件在链上检测到交易后触发;对于出账交易,该事件在根据请求创建交易记录后触发。此事件不表示交易已成功。
+
+### TRON 代币充币示例
+
+```json
+{"transaction_id":"55555555-5555-4555-8555-555555555555","cobo_id":null,"request_id":null,"wallet_id":"22222222-2222-4222-8222-222222222222","type":"Deposit","status":"PendingScreening","sub_status":"PendingCoboKYTCheck","failed_reason":null,"chain_id":"TRON","token_id":"TRON_USDT","asset_id":null,"source":{"source_type":"DepositFromAddress","address":"TSource11111111111111111111111111111"},"destination":{"destination_type":"DepositToAddress","address":"TDestination111111111111111111111111"},"result":null,"fee":null,"initiator":null,"initiator_type":"Blockchain","confirmed_num":0,"confirming_threshold":19,"transaction_hash":"5555555555555555555555555555555555555555555555555555555555555555","block_info":null,"raw_tx_info":null,"replacement":null,"category":[],"cobo_category":[],"description":null,"is_loop":false,"extra":null,"fueling_info":null,"timeline":[{"status":"PendingScreening","finished":false,"finished_timestamp":null}],"created_timestamp":1784563000000,"updated_timestamp":1784563000000}
+```
+
+### EVM 原生资产提币示例
+
+```json
+{"transaction_id":"66666666-6666-4666-8666-666666666666","cobo_id":null,"request_id":"withdrawal-20260721-000","wallet_id":"44444444-4444-4444-8444-444444444444","type":"Withdrawal","status":"Submitted","sub_status":null,"failed_reason":null,"chain_id":"ETH","token_id":"ETH","asset_id":null,"source":{"source_type":"Org-Controlled","wallet_id":"44444444-4444-4444-8444-444444444444","address":"0x3333333333333333333333333333333333333333"},"destination":{"destination_type":"Address","address":"0x4444444444444444444444444444444444444444","amount":"0.10000000"},"result":null,"fee":null,"initiator":"operator@example.com","initiator_type":"API","confirmed_num":0,"confirming_threshold":12,"transaction_hash":null,"block_info":null,"raw_tx_info":null,"replacement":null,"category":[],"cobo_category":[],"description":"Treasury withdrawal","is_loop":false,"extra":null,"fueling_info":null,"timeline":[{"status":"Submitted","finished":false,"finished_timestamp":null}],"created_timestamp":1784563100000,"updated_timestamp":1784563100000}
+```
+
+
+## `wallets.transaction.updated`
+
+交易数据发生变化(包括状态或确认进度变化)时触发此事件。交易进入终态时,除对应的 `succeeded` 或 `failed` 事件外,也会产生 `updated` 事件。订阅 `updated` 可观察所有生命周期变化;需要明确终态信号时,请使用终态事件。
+
+### EVM 代币充币示例
+
+```json
+{"transaction_id":"11111111-1111-4111-8111-111111111111","cobo_id":"202607210001","request_id":null,"wallet_id":"22222222-2222-4222-8222-222222222222","type":"Deposit","status":"Confirming","sub_status":"PendingBlockConfirmations","failed_reason":null,"chain_id":"ETH","token_id":"ETH_USDT","asset_id":null,"source":{"source_type":"DepositFromAddress","address":"0x1111111111111111111111111111111111111111"},"destination":{"destination_type":"DepositToAddress","address":"0x2222222222222222222222222222222222222222"},"result":null,"fee":null,"initiator":null,"initiator_type":"Blockchain","confirmed_num":4,"confirming_threshold":12,"transaction_hash":"0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","block_info":{"block_number":24001234,"block_timestamp":1784563200000,"block_hash":"0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"},"raw_tx_info":null,"replacement":null,"category":[],"cobo_category":[],"description":null,"is_loop":false,"extra":null,"fueling_info":null,"timeline":[{"status":"Confirming","finished":false,"finished_timestamp":null}],"created_timestamp":1784563180000,"updated_timestamp":1784563200000}
+```
+
+### UTXO 原生资产提币示例
+
+```json
+{"transaction_id":"33333333-3333-4333-8333-333333333333","cobo_id":"202607210002","request_id":"withdrawal-20260721-001","wallet_id":"44444444-4444-4444-8444-444444444444","type":"Withdrawal","status":"Broadcasting","sub_status":"Broadcasting","failed_reason":null,"chain_id":"BTC","token_id":"BTC","asset_id":null,"source":{"source_type":"Org-Controlled","wallet_id":"44444444-4444-4444-8444-444444444444","address":"bc1qsource000000000000000000000000000000000"},"destination":{"destination_type":"Address","address":"bc1qdestination0000000000000000000000000000","amount":"0.01000000"},"result":null,"fee":{"fee_type":"UTXO","token_id":"BTC","fee_used":"0.00001000"},"initiator":"operator@example.com","initiator_type":"API","confirmed_num":0,"confirming_threshold":6,"transaction_hash":"cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc","block_info":null,"raw_tx_info":{"used_nonce":null,"raw_tx":"0200000001...","unsigned_raw_tx":"0200000001...","selected_utxos":[{"tx_hash":"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd","vout_n":0}],"utxo_changes":[{"address":"bc1qchange000000000000000000000000000000000","value":"0.00499000","token_id":"BTC"}]},"replacement":null,"category":[],"cobo_category":[],"description":"Treasury withdrawal","is_loop":false,"extra":null,"fueling_info":null,"timeline":[{"status":"Broadcasting","finished":false,"finished_timestamp":null}],"created_timestamp":1784563300000,"updated_timestamp":1784563320000}
+```
+
+
+## `wallets.transaction.succeeded`
+
+交易进入成功终态时触发此事件。有关充币对账,请参阅[何时为充币入账](/v2_cn/guides/transactions/status#何时为充币入账)。
+
+### UTXO 原生资产充币示例
+
+```json
+{"transaction_id":"77777777-7777-4777-8777-777777777777","cobo_id":"202607210003","request_id":null,"wallet_id":"22222222-2222-4222-8222-222222222222","type":"Deposit","status":"Completed","sub_status":null,"failed_reason":null,"chain_id":"BTC","token_id":"BTC","asset_id":null,"source":{"source_type":"DepositFromAddress","address":"bc1qsource111111111111111111111111111111111"},"destination":{"destination_type":"DepositToAddress","address":"bc1qdestination1111111111111111111111111111"},"result":null,"fee":null,"initiator":null,"initiator_type":"Blockchain","confirmed_num":6,"confirming_threshold":6,"transaction_hash":"7777777777777777777777777777777777777777777777777777777777777777","block_info":{"block_number":900001,"block_timestamp":1784563400000,"block_hash":"8888888888888888888888888888888888888888888888888888888888888888"},"raw_tx_info":null,"replacement":null,"category":[],"cobo_category":[],"description":null,"is_loop":false,"extra":null,"fueling_info":null,"timeline":[{"status":"Confirming","finished":true,"finished_timestamp":1784563400000},{"status":"Completed","finished":false,"finished_timestamp":null}],"created_timestamp":1784563340000,"updated_timestamp":1784563400000}
+```
+
+### TRON 代币提币示例
+
+```json
+{"transaction_id":"88888888-8888-4888-8888-888888888888","cobo_id":"202607210004","request_id":"withdrawal-20260721-002","wallet_id":"44444444-4444-4444-8444-444444444444","type":"Withdrawal","status":"Completed","sub_status":null,"failed_reason":null,"chain_id":"TRON","token_id":"TRON_USDT","asset_id":null,"source":{"source_type":"Org-Controlled","wallet_id":"44444444-4444-4444-8444-444444444444","address":"TSource22222222222222222222222222222"},"destination":{"destination_type":"Address","address":"TDestination222222222222222222222222","amount":"25.000000"},"result":null,"fee":{"fee_type":"Fixed","token_id":"TRON","fee_used":"2.000000"},"initiator":"operator@example.com","initiator_type":"API","confirmed_num":19,"confirming_threshold":19,"transaction_hash":"9999999999999999999999999999999999999999999999999999999999999999","block_info":{"block_number":76001234,"block_timestamp":1784563500000,"block_hash":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},"raw_tx_info":{"used_nonce":null,"raw_tx":"0a02...","unsigned_raw_tx":"0a02...","selected_utxos":null,"utxo_changes":null},"replacement":null,"category":[],"cobo_category":[],"description":"Treasury withdrawal","is_loop":false,"extra":null,"fueling_info":null,"timeline":[{"status":"Broadcasting","finished":true,"finished_timestamp":1784563460000},{"status":"Completed","finished":false,"finished_timestamp":null}],"created_timestamp":1784563440000,"updated_timestamp":1784563500000}
+```
+
+
+## `wallets.transaction.failed`
+
+交易进入 `Failed`、`Rejected` 或 `Canceled` 时触发此事件。这些终态也会通过 `wallets.transaction.updated` 发送。
+
+### EVM 原生资产充币被拒绝示例
+
+```json
+{"transaction_id":"99999999-9999-4999-8999-999999999999","cobo_id":"202607210005","request_id":null,"wallet_id":"22222222-2222-4222-8222-222222222222","type":"Deposit","status":"Rejected","sub_status":"RejectedByCoboKYT","failed_reason":"The deposit did not pass transaction screening.","chain_id":"ETH","token_id":"ETH","asset_id":null,"source":{"source_type":"DepositFromAddress","address":"0x5555555555555555555555555555555555555555"},"destination":{"destination_type":"DepositToAddress","address":"0x2222222222222222222222222222222222222222"},"result":null,"fee":null,"initiator":null,"initiator_type":"Blockchain","confirmed_num":0,"confirming_threshold":12,"transaction_hash":"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee","block_info":null,"raw_tx_info":null,"replacement":null,"category":[],"cobo_category":[],"description":null,"is_loop":false,"extra":null,"fueling_info":null,"timeline":[{"status":"Rejected","finished":false,"finished_timestamp":null}],"created_timestamp":1784563600000,"updated_timestamp":1784563620000}
+```
+
+### TRON 原生资产提币失败示例
+
+```json
+{"transaction_id":"aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa","cobo_id":"202607210006","request_id":"withdrawal-20260721-003","wallet_id":"44444444-4444-4444-8444-444444444444","type":"Withdrawal","status":"Failed","sub_status":"FailedOnChain","failed_reason":"The transaction failed on-chain.","chain_id":"TRON","token_id":"TRON","asset_id":null,"source":{"source_type":"Org-Controlled","wallet_id":"44444444-4444-4444-8444-444444444444","address":"TSource33333333333333333333333333333"},"destination":{"destination_type":"Address","address":"TDestination333333333333333333333333","amount":"10.000000"},"result":null,"fee":{"fee_type":"Fixed","token_id":"TRON","fee_used":"1.000000"},"initiator":"operator@example.com","initiator_type":"API","confirmed_num":0,"confirming_threshold":19,"transaction_hash":"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb","block_info":null,"raw_tx_info":{"used_nonce":null,"raw_tx":"0a02...","unsigned_raw_tx":"0a02...","selected_utxos":null,"utxo_changes":null},"replacement":null,"category":[],"cobo_category":[],"description":"Treasury withdrawal","is_loop":false,"extra":null,"fueling_info":null,"timeline":[{"status":"Failed","finished":false,"finished_timestamp":null}],"created_timestamp":1784563700000,"updated_timestamp":1784563720000}
+```
diff --git a/v2_cn/guides/webhooks-callbacks/webhook-event-type.mdx b/v2_cn/guides/webhooks-callbacks/webhook-event-type.mdx
index 4653ec1e..3e6f905d 100644
--- a/v2_cn/guides/webhooks-callbacks/webhook-event-type.mdx
+++ b/v2_cn/guides/webhooks-callbacks/webhook-event-type.mdx
@@ -32,22 +32,22 @@ import WaasSkillReminder from '/snippets/waas_skill_reminder_cn.mdx';
- wallets.transaction.created |
+ wallets.transaction.created |
Transaction |
在区块链上检测到交易并生成记录。此事件不代表交易已成功。 |
- wallets.transaction.updated |
+ wallets.transaction.updated |
Transaction |
- 交易的状态或确认数发生变化。`wallets.transaction.updated` 涵盖交易的整个生命周期,包括创建、完成和失败。如果您想跟踪每个状态变化,订阅此事件即可。 |
+ 交易状态、确认进度或其他交易数据发生变化。进入终态时,除 wallets.transaction.succeeded 或 wallets.transaction.failed 外,还会产生此事件。订阅 wallets.transaction.updated 可观察所有生命周期变化。 |
- wallets.transaction.succeeded |
+ wallets.transaction.succeeded |
Transaction |
交易已成功完成。 |
- wallets.transaction.failed |
+ wallets.transaction.failed |
Transaction |
交易失败。 |
@@ -111,22 +111,22 @@ import WaasSkillReminder from '/snippets/waas_skill_reminder_cn.mdx';
- wallets.mpc.tss_request.created |
+ wallets.mpc.tss_request.created |
TSSRequest |
创建了 TSS 请求。 |
- wallets.mpc.tss_request.updated |
+ wallets.mpc.tss_request.updated |
TSSRequest |
TSS 请求的状态发生变化。 |
- wallets.mpc.tss_request.succeeded |
+ wallets.mpc.tss_request.succeeded |
TSSRequest |
请求的操作已完成。 |
- wallets.mpc.tss_request.failed |
+ wallets.mpc.tss_request.failed |
TSSRequest |
请求的操作失败。 |
@@ -154,11 +154,26 @@ import WaasSkillReminder from '/snippets/waas_skill_reminder_cn.mdx';
WalletInfo |
已创建新的钱包。 |
+
+ wallets.updated |
+ WalletInfo |
+ 钱包记录的变更已保存,并返回当前钱包信息。 |
+
mpc_vaults.created |
MPCVault |
已创建新的 MPC Vault。 |
+
+ mpc_vaults.updated |
+ MPCVault |
+ 现有 MPC Vault 的配置或元数据发生变化。 |
+
+
+ mpc_vaults.deleted |
+ MPCVault |
+ MPC Vault 已删除,无法再用于钱包操作。 |
+
@@ -299,4 +314,4 @@ import WaasSkillReminder from '/snippets/waas_skill_reminder_cn.mdx';
您可以在事件数据类型之间切换来查看每个事件数据类型的数据结构。
-另外,您可以在 **Cobo Portal** > **开发者** > **Webhook 事件** 中查看团队中的所有 webhook 事件。
\ No newline at end of file
+另外,您可以在 **Cobo Portal** > **开发者** > **Webhook 事件** 中查看团队中的所有 webhook 事件。
diff --git a/v2_cn/guides/webhooks-callbacks/webhook-operations.mdx b/v2_cn/guides/webhooks-callbacks/webhook-operations.mdx
new file mode 100644
index 00000000..23c24a22
--- /dev/null
+++ b/v2_cn/guides/webhooks-callbacks/webhook-operations.mdx
@@ -0,0 +1,43 @@
+---
+title: "Webhook 和 Callback 运营指南"
+lang: "zh-hans"
+description: "处理常见 Webhook 和 Callback 场景、恢复失败投递,并在投递历史不可用时完成对账。"
+---
+
+import WaasSkillReminder from '/snippets/waas_skill_reminder_cn.mdx';
+
+
+
+## 概述
+
+本文提供运营决策和恢复流程。事件目录请参阅 [Webhook 事件类型](/v2_cn/guides/webhooks-callbacks/webhook-event-type),Payload 结构请参阅 [Transaction 事件 Payload](/v2_cn/guides/webhooks-callbacks/transaction-events)和 [MPC TSS request 事件 Payload](/v2_cn/guides/webhooks-callbacks/mpc-tss-request-events),Endpoint 机制请参阅[设置 Callback 或 Webhook Endpoint](/v2_cn/guides/webhooks-callbacks/set-up-endpoint)。
+
+## 常见场景
+
+| 场景 | 您会收到的内容 | 建议处理方式 |
+| --- | --- | --- |
+| 充币入账 | `created`、通过 `updated` 发送的进度,随后是 `succeeded` 或 `failed`。 | 遵循[何时为充币入账](/v2_cn/guides/transactions/status#何时为充币入账)。 |
+| 提币进度与终态 | `updated` 可报告 `PendingAuthorization`、`PendingSignature`、`Broadcasting` 和 `Confirming`;终态还会产生 `succeeded` 或 `failed`。 | 使用 `updated` 展示进度,使用终态事件对账结果。 |
+| 被拒绝或取消的交易 | `Failed`、`Rejected` 或 `Canceled` 会产生 `wallets.transaction.failed`,同时也会产生 `updated`。 | 按照 [`failed` 事件结构](/v2_cn/guides/webhooks-callbacks/transaction-events#walletstransactionfailed)统一处理这些结果。 |
+| AutoSweep | `cobo_category` 包含 `AutoSweep` 的交易。 | 根据 `cobo_category` 分支处理;请参阅 [Cobo 定义的交易类别](/v2_cn/guides/transactions/manage-transactions#cobo-定义的交易类别)。 |
+| 合规监控 | 合规状态事件,以及分类为 `ComplianceRefund`、`ComplianceIsolate`、`ScreenAppRefund` 或 `ScreenAppIsolate` 的后续交易。 | 跟踪[合规事件](/v2_cn/guides/webhooks-callbacks/webhook-event-type#合规事件),并单独对账分类交易。 |
+| Portal 创建的活动 | Portal 发起的交易和注册会产生与 API 发起活动相同的已订阅事件类型。 | 无论活动从何处发起,都使用相同的事件处理程序。 |
+| 钱包范围 | 注册 Endpoint 时,您需要选择订阅的钱包和事件类型。 | 仅注册 Endpoint 能够处理的范围。 |
+| 乱序投递 | 事件到达顺序可能与生成顺序不同。 | 根据 `status`、`sub_status` 和时间戳重建状态,不要依赖到达顺序。请参阅[响应 API 请求](/v2_cn/guides/webhooks-callbacks/set-up-endpoint#响应-api-请求)。 |
+| 幂等性 | 重试和多个生命周期事件可能重复同一逻辑状态。 | 遵循[幂等处理说明](/v2_cn/guides/webhooks-callbacks/set-up-endpoint#注意事项)。 |
+| API 对账 | Webhook 或 Callback 状态不明确、遗漏或已无法查询。 | 使用 [Get transaction information](/v2/api-references/transactions/get-transaction-information) 或 [List all transactions](/v2/api-references/transactions/list-all-transactions)。 |
+
+## 恢复遗漏或失败的事件
+
+1. 使用 [List all webhook events](/v2/api-references/developers--webhooks/list-all-webhook-events) 查找受影响的 Webhook 事件。按 Endpoint、`status` 和 `type` 筛选,并使用 `before` 或 `after` 游标继续查询。Callback 请使用 [List all callback messages](/v2/api-references/developers/list-all-callback-messages)。
+2. 使用 [List webhook event logs](/v2/api-references/developers--webhooks/list-webhook-event-logs) 检查每次投递,或在 Cobo Portal 中打开 Callback 消息的投递日志。
+3. 先修复 Endpoint。使用[常见投递失败原因](/v2_cn/guides/webhooks-callbacks/set-up-endpoint#常见投递失败原因)排查响应、可访问性、重定向和 TLS 问题。
+4. 在 Cobo Portal 中手动重试 Webhook 事件需要 `WEBHOOK RESEND` 权限。对于 Webhook 事件,请在 Cobo Portal 中单击 **重新发送**或调用 [Retry event](/v2/api-references/developers--webhooks/retry-event)。对于 Callback 消息,请调用 [Retry callback message](/v2/api-references/developers/retry-callback-message)。
+5. 按照[幂等处理说明](/v2_cn/guides/webhooks-callbacks/set-up-endpoint#注意事项),根据事件或消息 ID 对重发投递去重。
+6. 使用 [Get transaction information](/v2/api-references/transactions/get-transaction-information) 或 [List all transactions](/v2/api-references/transactions/list-all-transactions) 对账交易终态。重发成功仅表示已收到消息,不表示交易结果。
+
+此流程适用于事件或消息仍可通过列表和日志操作查询的情况。
+
+## 历史记录已过期时
+
+如果事件或 Callback 消息已无法查询,请直接使用 [Get transaction information](/v2/api-references/transactions/get-transaction-information) 或 [List all transactions](/v2/api-references/transactions/list-all-transactions) 对账当前状态。请保留您自己的幂等和关联记录,避免对账仅依赖投递历史。