Crediting Logic
Why are 10 blocks considered sufficient?Based on the Ethereum 2.0 Beacon Chain finality mechanism, the probability of a transaction being reverted after 10 blocks is extremely low. The official recommendation for full confirmation is 100 blocks (15–20 minutes), but 10 blocks already satisfy the safety requirements for the vast majority of business scenarios.
Payload Example
Field Reference
| Field | Type | Description |
|---|---|---|
event_id | string | Unique event identifier |
type | string | Event type (wallets.transaction.created / updated / succeeded) |
created_timestamp | number | Event creation timestamp (milliseconds) |
data.transaction_id | string | Unique transaction identifier |
data.wallet_id | string | Merchant wallet ID |
data.type | string | Transaction type (Deposit) |
data.status | string | Transaction status (Confirming / Completed) |
data.source.addresses | array | Source addresses of the deposit (the end user’s addresses) |
data.destination.amount | string | Deposit amount |
data.destination.address | string | Destination address of the deposit (the merchant’s deposit address) |
data.chain_id | string | Chain identifier |
data.token_id | string | Token identifier |
data.confirmed_num | number | Current on-chain confirmation count |
data.confirming_threshold | number | Required minimum confirmation count |
data.transaction_hash | string | On-chain transaction hash |
data.block_info | object | Block info (block number, timestamp) |
data.timeline | array | Status change timeline |
Handling Recommendations
Idempotency handling
Idempotency handling
A single deposit may trigger multiple Webhooks (created → updated → succeeded). Use
transaction_id for idempotency to avoid double-crediting.Verify wallet_id
Verify wallet_id
After receiving an event, first verify that
data.wallet_id matches your project’s wallet. Events from other projects should be ignored.Reconciliation fallback
Reconciliation fallback
In addition to Webhooks, we recommend periodically calling the Transaction Records endpoint as a reconciliation fallback in case Webhooks are lost.
Manual Acquiring
Manual acquiring reuses this callback: when a payer transfers funds to a fixed address created in the dashboard, the system pushes the event through the normal Webhook channel with exactly the same structure as online deposits. There is no new notification mechanism — merchants reuse their existing deposit-handling code as is.Project routing works the same as online:
data.wallet_id in the event is the project acquiring wallet ID (an existing field). NUSDpay provides each project’s wallet ID during onboarding; merchants route on it (e.g. forwarding only offline deposits to an ops notification group).Field Mapping
When migrating from a third-party acquiring service, common notification fields map to this callback as follows:| Common field | NUSDpay Webhook field | Notes |
|---|---|---|
walletName (address label) | — | The webhook does not carry the address description. Look it up merchant-side from data.destination.address against the description entered when creating the address |
chain | data.chain_id | Chain identifier (TBSC_BNB in the Payload example above is a testnet value; production values come from the actual callback) |
toAddress | data.destination.address | The fixed deposit address |
notifyTime | created_timestamp | Millisecond timestamp (UTC) |
orderAmount | data.destination.amount | Gross on-chain amount (before service fee and conversion) |
currency | data.token_id | Token identifier with chain prefix (e.g. TRON_USDT); full list in Supported Tokens & Chains |
hash | data.transaction_hash | On-chain transaction hash |
txId | data.transaction_id | NUSDpay transaction ID (idempotency key) |
status | type + data.status | Success = type is wallets.transaction.succeeded and status is Completed; or confirmed_num ≥ 10 (see Crediting Logic above) |
mchNo (merchant/project no.) | data.wallet_id | Use the project wallet ID (existing field) to distinguish projects; NUSDpay provides each project’s ID |