Disclaimer: This article contains AI translations and should only be used as reference. Contact Cobo’s support team through [email protected] if you have any questions.
Webhook Events
Which events should you subscribe to?
Subscribe to the events that match how you use Payments. Click any event name for details.| Scenario | Event | Fires when |
|---|---|---|
| Order Mode only | payment.order.status.updated | The order status changes (Pending, Completed, Expired, Underpaid) — your main signal for order fulfillment. |
payment.transaction.late | A compliant deposit arrives after the order reached a final state. | |
| Top-up Mode only | payment.transaction.created | A top-up address receives a new deposit. |
payment.address.updated | A payer’s top-up address is replaced. | |
| Both pay-in modes | payment.transaction.completed | A deposit passes compliance screening and is credited. |
payment.transaction.failed | A deposit fails compliance screening. | |
payment.transaction.external.created | An unexpected deposit is detected (outside any order/top-up plan, or in an unsupported token). | |
payment.transaction.external.completed | An unexpected deposit is credited to your developer balance. | |
payment.account.balance.updated | An account balance changes for a token — useful for internal accounting. | |
| Payout | payment.payout.status.updated | A single-destination payout/transfer request’s status changes. |
payment.refund.status.updated | A refund order’s status changes (only if you issue refunds). | |
payment.bulk_send.status.updated | A bulk send request’s status changes (only if you use Bulk Send for crypto payouts). | |
payment.bulk_send.item.status.updated | A single bulk send item’s status changes (only if you use Bulk Send for crypto payouts). | |
| Settlement Network | payment.transaction.settlement_network.created | A Settlement Network transaction is created. |
payment.transaction.settlement_network.completed | The transaction completes and settled funds are reflected in your Payment account balance. |
1. Pay-in Related
payment.order.status.updated
Trigger condition: Triggered when a payment order status changes (Order Mode only). Key nodes include:
Pending: Triggered only when an order is successfully created via a payment link.Completed: Full payment received within the order validity period.Expired: No completed deposit transactions within the validity period, or the order was canceled.Underpaid: Completed deposit transactions exist, but the total amount received is less than the expected amount.
order_id(required) — The order ID.merchant_id(optional) — The merchant ID.merchant_order_code(optional) — A unique reference code assigned by the merchant.psp_order_code(required) — A unique reference code assigned by the developer to identify this order.pricing_currency(optional) — The pricing currency of the order.pricing_amount(optional) — The base amount of the order, excluding the developer fee.fee_amount(required) — The developer fee for the order.payable_currency(optional) — The ID of the cryptocurrency used for payment.chain_id(required) — The ID of the blockchain network.payable_amount(required) — The cryptocurrency amount to be paid for this order.exchange_rate(required) — The exchange rate betweenpayable_currencyandpricing_currency.amount_tolerance(optional) — The allowed amount deviation.receive_address(required) — The recipient wallet address for the payment transaction.status(required) — The current order status. One of:Pending,Processing,Completed,Expired,Underpaid.received_token_amount(required) — The total cryptocurrency amount received for this order.expired_at(optional) — The expiration time, in Unix timestamp (seconds).created_timestamp(optional) — The creation time, in Unix timestamp (seconds).updated_timestamp(optional) — The last update time, in Unix timestamp (seconds).transactions(optional) — An array of payment transactions associated with this order.
payment.transaction.late
Trigger condition: In Order Mode, a deposit transaction that passed compliance scanning is received after the payment order has reached a final state (Underpaid, Expired, or Completed).
Event content: All fields from Transaction fields, plus these Payment-specific fields:
acquiring_type(required) — The collection type. Value:Order(Order Mode only).order_id(optional) — The pay-in order ID.psp_order_code(optional) — A unique reference code assigned by the developer to identify this order.
payment.transaction.created
Trigger condition: In Top-up Mode, a new deposit transaction is detected on a deposit address.
Event content: All fields from Transaction fields, plus these Payment-specific fields:
acquiring_type(required) — The collection type. Value:TopUp(Top-up Mode only).payer_id(optional) — A unique identifier assigned by Cobo to track and identify individual payers.custom_payer_id(optional) — A unique identifier assigned by the developer to track and identify individual payers.
payment.address.updated
Trigger condition: In Top-up Mode, triggered when the payer’s top-up address is replaced.
Event content:
custom_payer_id— Payer identifier in your system.payer_id— Payer identifier assigned by Cobo.chain— The chain of the address.previous_address— Address before replacement.updated_address— Address after replacement.
payment.transaction.completed
Trigger condition: Applies to both pay-in modes:
- Order Mode: For every transaction received within the order’s validity period, once the funds pass compliance screening, they are credited and recorded in the Actual Receipt amount.
- Top-up Mode: Once a collection transaction passes compliance screening, the funds are credited and recorded in the Actual Receipt amount.
- Order Mode:
acquiring_type(required, valueOrder),order_id(optional),psp_order_code(optional). - Top-up Mode:
acquiring_type(required, valueTopUp),payer_id(optional),custom_payer_id(optional).
payment.transaction.external.created
Trigger condition: In either pay-in mode, an unexpected deposit transaction is detected (e.g., transactions not within current orders/deposit plans, or deposits in unsupported tokens).
Event content: All fields from Transaction fields.
payment.transaction.external.completed
Trigger condition: In either pay-in mode, the unexpected deposit transaction passed compliance scanning and has been successfully credited to the developer balance.
Event content: All fields from Transaction fields.
payment.transaction.failed
Trigger condition: In either pay-in mode, the collection transaction failed the compliance screening.
Event content: All fields from Transaction fields, plus these Payment-specific fields:
acquiring_type(required) — The collection type.Orderfor Order Mode,TopUpfor Top-up Mode.order_id(optional) — The pay-in order ID.psp_order_code(optional) — A unique reference code assigned by the developer to identify this order.payer_id(optional) — A unique identifier assigned by Cobo to track and identify individual payers.custom_payer_id(optional) — A unique identifier assigned by the developer to track and identify individual payers.
For an order that receives multiple partial transfers before completion,
payment.transaction.completed fires once per successful receipt as funds are credited, while payment.order.status.updated reflects the order’s cumulative, terminal outcome (Completed or Underpaid). See Partial payments for details.payment.transaction.late reports a receipt that arrived after the order already reached a terminal status. It does not reopen or otherwise change the order’s final status. See Late payment for the full lifecycle.2. Pay-out Related
payment.refund.status.updated
Trigger condition: Triggered when a refund order status changes. Key nodes include:
Pending: Triggered only when a refund order is successfully created via a refund link.Completed: All refund transactions are completed.Failed: All refund transactions failed.
refund_id(required) — The refund order ID.request_id(optional) — The request ID you provided when creating the refund.order_id(optional) — The ID of the pay-in order corresponding to this refund.merchant_id(optional) — The merchant ID.token_id(required) — The ID of the cryptocurrency used for the refund.chain_id(required) — The ID of the blockchain network.amount(required) — The cryptocurrency amount to be returned for this refund.to_address(required) — The recipient wallet address.status(required) — The current refund status. One of:AddressPending,AddressSubmitted,Pending,Processing,Completed,Failed,PendingConfirmation.refund_type(optional) — The source of funds. One of:Merchant,Psp.created_timestamp(required) — The creation time, in Unix timestamp (seconds).updated_timestamp(required) — The last update time, in Unix timestamp (seconds).initiator(optional) — The initiator of the refund request.transactions(optional) — An array of payment transactions associated with this refund.charge_merchant_fee(optional) — Whether to charge the developer fee to the merchant.merchant_fee_amount(optional) — The developer fee amount to charge the merchant.merchant_fee_token_id(optional) — The ID of the cryptocurrency used for the developer fee.commission_fee(optional) — Commission fee details.
payment.payout.status.updated
Trigger condition: Triggered when a payout/transfer request status changes:
Completed: All payouts/transfers completed.PartiallyCompleted: Some completed, some failed.Failed: All failed.RejectedByBank: The recipient bank rejected the Off-Ramp payout.
payout_id(required) — The payout ID.request_id(required) — The request ID you provided when creating the payout.payout_channel(required) — The payout channel. One of:Crypto,OffRamp.source_account(optional) — The source account from which the payout is made.payout_items(optional) — An array of payout items.recipient_info(optional) — The recipient information.initiator(optional) — The initiator of the payout request.actual_payout_amount(optional) — The actual amount delivered to the recipient.commission_fees(optional) — An array of commission fees for this payout.remark(optional) — A note or comment about the payout.status(required) — The current payout status. One of:Pending,Preparing,Transferring,Completed,PartiallyCompleted,Failed,RejectedByBank.created_timestamp(required) — The creation time, in Unix timestamp (seconds).updated_timestamp(required) — The last update time, in Unix timestamp (seconds).transactions(optional) — An array of payment transactions associated with this payout.
payment.bulk_send.status.updated
Trigger condition: Triggered when a bulk send request status changes:
Completed: All sends completed.PartiallyCompleted: Some completed, some failed.Failed: All failed.
bulk_send_id(required) — The bulk send ID.request_id(optional) — The request ID you provided when creating the bulk send.source_account(required) — The source account from which the bulk send is made.description(optional) — The description for the entire bulk send batch.execution_mode(required) — The execution mode.status(required) — The current bulk send status.created_timestamp(required) — The creation time, in Unix timestamp (seconds).updated_timestamp(required) — The last update time, in Unix timestamp (seconds).
payment.bulk_send.item.status.updated
Trigger condition: Triggered when the status of a single bulk send item changes. Use it to track item-level execution results for a bulk send, especially when a batch completes partially or individual items fail validation or transfer.
Event content:
bulk_send_item_id(required) — The bulk send item ID.bulk_send_id(required) — The bulk send ID that this item belongs to.request_id(optional) — The request ID of the bulk send batch.source_account(required) — The source account ID of the bulk send batch.token_id(required) — The token ID of the cryptocurrency sent to the recipient.receiving_address(required) — The recipient’s cryptocurrency address.amount(required) — The cryptocurrency amount sent to the recipient.description(optional) — A note or comment about the bulk send item.tx_hash(optional) — The transaction hash of the bulk send item.status(required) — The item execution status. One of:Pending,Processing,Completed,Failed,NotExecuted.validation_status(required) — The item validation status. One of:Pending,Validated,ValidationFailed,NotExecuted.failed_reason(optional) — The reason why the bulk send item failed.created_timestamp(required) — The creation time, in Unix timestamp (seconds).updated_timestamp(required) — The last update time, in Unix timestamp (seconds).
event_type set to payment.bulk_send.item.status.updated.
payment.account.balance.updated
Trigger condition: Triggered when the available balance of a Payments account changes for a specific token.
Event content:
source_account(required) — The source account of the balance change. For a merchant account, this is the merchant ID; for the developer account, this isdeveloper.source_id(required) — The source ID of the balance change.source_type(required) — The source type of the balance change (for example,OrderIn,Payout,RefundOut,BulkSend).token_id(required) — The token ID.amount/amount_raw(required) — The balance change amount, truncated to two decimal places and in the token’s decimal precision respectively.balance_before/balance_before_raw(required) — The account balance before the change.balance_after/balance_after_raw(required) — The account balance after the change.flow_direction(required) — The direction of the balance change. One of:in,out.update_time(required) — The time when the balance was updated, in Unix timestamp (seconds).
3. Settlement Network Related
payment.transaction.settlement_network.created
Trigger condition: Triggered when a Settlement Network transaction is created.
Event content: The base fields from Transaction fields. See the Settlement Network guide.
payment.transaction.settlement_network.completed
Trigger condition: Triggered when a Settlement Network transaction is completed. On completion, the settled funds are reflected in your Payment account balance with the SettlementNetwork source_type.
Event content: The base fields from Transaction fields. See the Settlement Network guide.
Transaction fields
The following fields are included in allpayment.transaction.* events. Not all fields are populated in every scenario — see the required/optional note on each field. Each payment.transaction.* event also adds its own Payment-specific fields, listed under that event above.
This section only covers the fields most relevant to payment scenarios. For the complete list of transaction fields and their meanings, see Get transaction information.
transaction_id(string, UUID, required) — The transaction ID.cobo_id(string, optional) — The Cobo ID used to track a transaction.request_id(string, optional) — The request ID used to track the transaction request.type(string, optional) — The transaction type.status(string, required) — The transaction status (e.g.Submitted,PendingScreening,Confirming,Completed,Failed,Rejected). See Transaction statuses and sub-statuses for the full lifecycle. ThePendingAuthorizationstatus covers both manual approval steps and internal automated risk-control/KYT/compliance checks — it does not necessarily require a human action.sub_status(string, optional) — A more granular status alongsidestatus(e.g.PendingApproverCheck,RejectedKYT,FailedOnChain). See the same statuses and sub-statuses guide for the full list.failed_reason(string, optional) — Why the transaction failed. Populated only for approval failures and signature failures.initiator(string, optional) — The transaction initiator.chain_id(string, optional) — The chain ID.token_id(string, optional) — The token ID.transaction_hash(string, optional) — The on-chain transaction hash (txid). Populated only after the transaction is broadcast on-chain, so it may benullor absent before then — unliketransaction_id, which is assigned at creation and always present.source(object, required) — Where the deposit came from, typically an external wallet address (source_type: DepositFromAddress).destination(object, required) — Where the deposit went, typically a deposit address (destination_type: DepositToAddress). Key sub-fields:address— The receiving address.amount— The received amount. For example, if 1.5 USDT was deposited, the value is1.5.memo— The memo identifying which account to credit (only on certain chains).
result(object, optional) — The transaction result.fee(object, optional) — The transaction fee. Its shape depends on the chain’s fee model (e.g. EIP-1559, UTXO).confirmed_num(integer, optional) — The number of confirmations this transaction has received.confirming_threshold(integer, optional) — The minimum number of confirmations required to deem a transaction secure (e.g. commonly 6 for a Bitcoin transaction).block_info(object, optional) — Details of the block the transaction was included in:block_number— The block number.block_timestamp— When the block was created, in Unix timestamp (milliseconds).block_hash— The block hash.
raw_tx_info(object, optional) — Details of the raw transaction:used_nonce— The transaction nonce.selected_utxos— The UTXOs consumed in the transaction.raw_tx— The raw transaction data.unsigned_raw_tx— The unsigned raw transaction data.utxo_changes— The UTXO change outputs in the transaction.
replacement(object, optional) — Populated when this transaction replaced, or was replaced by, another (drop/resend/speed-up):replaced_by_type/replaced_type— The replacement type:Drop,Resend, orSpeedUp.replaced_by_transaction_id/replaced_by_transaction_hash— The ID/hash of the transaction that replaced this one.replaced_transaction_id/replaced_transaction_hash— The ID/hash of the transaction this one replaced.
created_timestamp(integer, int64, required) — The creation time, in Unix timestamp format (milliseconds).updated_timestamp(integer, int64, required) — The last update time, in Unix timestamp format (milliseconds).
Webhook message example
All webhook messages share the same top-level structure:event_id, url, created_timestamp, type, data (the event-specific content, with its shape indicated by data_type), and status. The following example shows a payment.transaction.created event.
This example is illustrative and constructed from the field definitions in the Payment spec; optional fields may be absent in actual webhook deliveries.
Tips
To ensure absolute data accuracy and avoid concurrency conflicts, the Webhook message does not include real-time balance changes or detailed fee deductions. If your use case requires this information, please refer to the following:- To update balances promptly based on Webhook notifications: Upon receiving a Webhook, immediately call the List merchant balances or Get developer balances endpoint to obtain the accurate balance for internal accounting.
- To obtain fee details associated with a transaction for reconciliation: Use the corresponding transaction query endpoints or Generate reports to retrieve fee reports for data verification.
- To monitor Fee Station balance changes and prevent business disruption: Periodically call List Fee Station token balance and set up internal alerting based on your consumption rate to avoid service interruptions due to insufficient fees.
