DirectCryptoPay Docs

Webhook Events

This page documents all webhook event types sent by DirectCryptoPay.

Event Types#

Event Description When It Fires
payment.pending Transaction declared, awaiting blockchain confirmations Customer submits transaction hash
payment.processing Transaction found on-chain, being validated Transaction detected with partial confirmations
payment.succeeded Payment confirmed on-chain Transaction reaches required confirmations
payment.failed Payment failed Transaction reverted or validation failed
payment.expired Payment intent expired No transaction submitted before expiration
payment.late_confirmation Transaction confirmed after intent expired Late transaction detected on-chain

payment.pending#

Sent when a customer declares a transaction hash but it has not yet been found on-chain.

{
  "event": "payment.pending",
  "intent_id": "cm1abc2def3ghi",
  "tx_hash": "0x7a3f8b2c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0",
  "chain_id": 11155111,
  "currency": "USDC",
  "amount_wei": "49990000",
  "pending_at": "2025-01-15T11:30:00.000Z",
  "metadata": { "orderId": "ORD-12345" }
}
Field Type Description
event string payment.pending
intent_id string Payment intent ID
tx_hash string On-chain transaction hash
chain_id number EVM chain ID
currency string Token symbol (e.g., USDC)
amount_wei string Amount in the token's smallest unit
pending_at string ISO 8601 timestamp
metadata object Custom metadata from payment creation

payment.processing#

Sent when the transaction has been found on-chain but has not yet reached the required number of confirmations.

{
  "event": "payment.processing",
  "intent_id": "cm1abc2def3ghi",
  "tx_hash": "0x7a3f8b2c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0",
  "chain_id": 11155111,
  "currency": "USDC",
  "confirmations": 1,
  "processing_at": "2025-01-15T11:31:00.000Z",
  "metadata": { "orderId": "ORD-12345" }
}
Field Type Description
event string payment.processing
intent_id string Payment intent ID
tx_hash string On-chain transaction hash
chain_id number EVM chain ID
currency string Token symbol
confirmations number Current number of block confirmations
processing_at string ISO 8601 timestamp
metadata object Custom metadata from payment creation

payment.succeeded#

Sent when a blockchain transaction has been verified and the payment is considered complete. This is the primary event for fulfilling orders.

{
  "event": "payment.succeeded",
  "intent_id": "cm1abc2def3ghi",
  "tx_hash": "0x7a3f8b2c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0",
  "chain_id": 11155111,
  "amount_wei": "49990000",
  "currency": "USDC",
  "confirmations": 3,
  "paid_at": "2025-01-15T11:35:00.000Z",
  "metadata": { "orderId": "ORD-12345", "plan": "premium" }
}
Field Type Description
event string payment.succeeded
intent_id string Payment intent ID
tx_hash string On-chain transaction hash
chain_id number EVM chain ID (e.g., 137 for Polygon)
amount_wei string Amount paid in the token's smallest unit
currency string Token symbol (e.g., USDC, ETH)
confirmations number Number of block confirmations reached
paid_at string ISO 8601 timestamp when the payment was verified on-chain
metadata object Custom metadata you passed when creating the payment

When to Use#

This is the primary event for fulfilling orders. When you receive payment.succeeded, the payment has been independently verified by the DCP backend via blockchain RPC.

payment.failed#

Sent when a payment could not be completed.

{
  "event": "payment.failed",
  "intent_id": "cm1abc2def3ghi",
  "reason": "transaction_reverted",
  "tx_hash": "0x...",
  "failed_at": "2025-01-15T12:00:00.000Z"
}
Field Type Description
event string payment.failed
intent_id string Payment intent ID
reason string Failure reason (see table below)
tx_hash string? Transaction hash (if a transaction was submitted)
failed_at string ISO 8601 timestamp

Failure Reasons#

Reason Description
transaction_reverted The on-chain transaction was reverted
insufficient_confirmations Transaction did not reach required confirmations
amount_mismatch Amount received does not match the expected amount

payment.expired#

Sent when a payment intent expires before a transaction is submitted.

{
  "event": "payment.expired",
  "intent_id": "cm1abc2def3ghi",
  "expires_at": "2025-01-15T11:45:00.000Z"
}
Field Type Description
event string payment.expired
intent_id string Payment intent ID
expires_at string ISO 8601 timestamp when the intent expired

payment.late_confirmation#

Sent when a transaction is confirmed on-chain after the payment intent has already expired. This can happen if the customer submitted a transaction just before expiration.

{
  "event": "payment.late_confirmation",
  "intent_id": "cm1abc2def3ghi",
  "tx_hash": "0x...",
  "chain_id": 11155111,
  "currency": "USDC",
  "confirmations": 3,
  "confirmed_at": "2025-01-15T12:05:00.000Z",
  "metadata": { "orderId": "ORD-12345" }
}
Late confirmations require manual review. The customer did pay, but the intent had already expired. You may want to fulfill the order manually or issue a refund.

Headers#

Every webhook request includes these headers:

Header Description
Content-Type application/json
X-DCP-Signature Contains timestamp and HMAC-SHA256 signature in format t=<timestamp>,v1=<hmac_hex>
User-Agent DirectCryptoPay-Webhooks/1.0

The X-DCP-Signature header encodes both the timestamp and the signature in a single value. To verify, parse the t= and v1= components, then compute HMAC-SHA256(secret, "<timestamp>.<rawBody>") and compare the hex digest against v1. See the Webhooks guide for full verification examples.

Responding to Webhooks#

Your endpoint should:

  1. Return a 2xx status code (200, 201, 202, or 204)
  2. Respond within 10 seconds

Any non-2xx response or timeout triggers a retry according to the retry policy.

Tip: Return 200 OK immediately and process the payment asynchronously. This ensures you never hit the 10-second timeout, even if your fulfillment logic is slow.