Saltar al contenido principal

Webhook Event Reference

Complete reference for all EdenPay webhook events and their payload structures.

Event Structure

All webhook events follow this common structure:

{
"id": "evt_abc123",
"type": "payment.confirmed",
"createdAt": "2025-01-15T10:30:00Z",
"data": {
// Event-specific data
}
}
FieldTypeDescription
idstringUnique identifier for this event
typestringEvent type (see below for all types)
createdAtstringISO 8601 timestamp when event was created
dataobjectEvent-specific payload

Payment Events

payment.created

Triggered when a new payment is initiated.

Use case: Track payment creation, start monitoring, or update UI status.

{
"id": "evt_abc123",
"type": "payment.created",
"createdAt": "2025-01-15T10:30:00Z",
"data": {
"paymentId": "pay_xyz789",
"amount": "100.00",
"currency": "USDC",
"network": "ethereum",
"status": "pending",
"recipientAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"workspaceId": "ws_abc123",
"metadata": {
"orderId": "order_123",
"customerId": "cust_456"
}
}
}

payment.pending

Triggered when a payment transaction is detected on the blockchain but not yet confirmed.

Use case: Show "Payment detected, awaiting confirmation" status to customers.

{
"id": "evt_def456",
"type": "payment.pending",
"createdAt": "2025-01-15T10:31:00Z",
"data": {
"paymentId": "pay_xyz789",
"amount": "100.00",
"currency": "USDC",
"network": "ethereum",
"status": "pending",
"txHash": "0x1234567890abcdef...",
"confirmationsReceived": 1,
"confirmationsRequired": 12,
"recipientAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"workspaceId": "ws_abc123",
"metadata": {
"orderId": "order_123",
"customerId": "cust_456"
}
}
}

payment.confirmed ⭐

This is the most important event. Triggered when a payment has received sufficient blockchain confirmations and is considered final.

Use case: Fulfill orders, credit accounts, grant access, or trigger any business logic that requires payment confirmation.

Recommended Action

This is the event you should use to fulfill orders and grant access to paid content. The payment is irreversible at this point.

{
"id": "evt_ghi789",
"type": "payment.confirmed",
"createdAt": "2025-01-15T10:35:00Z",
"data": {
"paymentId": "pay_xyz789",
"amount": "100.00",
"currency": "USDC",
"network": "ethereum",
"status": "confirmed",
"txHash": "0x1234567890abcdef...",
"confirmationsReceived": 12,
"recipientAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"workspaceId": "ws_abc123",
"confirmedAt": "2025-01-15T10:35:00Z",
"metadata": {
"orderId": "order_123",
"customerId": "cust_456"
}
}
}

Confirmation Requirements by Network:

  • Ethereum: 12 confirmations (~2.5 minutes)
  • Polygon: 100 confirmations (~3.5 minutes)
  • Base/Optimism: 12 confirmations (~30 seconds)
  • Arbitrum: 12 confirmations (~20 seconds)
  • Sui: 1 confirmation (~2 seconds)
  • Aptos: 1 confirmation (~4 seconds)

payment.failed

Triggered when a payment fails or expires.

Use case: Cancel orders, notify customers, or clean up pending transactions.

{
"id": "evt_jkl012",
"type": "payment.failed",
"createdAt": "2025-01-15T11:00:00Z",
"data": {
"paymentId": "pay_xyz789",
"amount": "100.00",
"currency": "USDC",
"network": "ethereum",
"status": "failed",
"failureReason": "Payment expired after 30 minutes",
"recipientAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"workspaceId": "ws_abc123",
"metadata": {
"orderId": "order_123",
"customerId": "cust_456"
}
}
}

Common Failure Reasons:

  • Payment expired after 30 minutes - Customer didn't complete payment in time
  • Insufficient amount received - Customer sent less than required
  • Wrong network - Customer sent to wrong blockchain
  • Transaction reverted - Blockchain transaction failed

payment.refunded

Triggered when a payment is refunded to the customer.

Use case: Revoke access, update accounting, or notify customer of refund.

{
"id": "evt_mno345",
"type": "payment.refunded",
"createdAt": "2025-01-15T12:00:00Z",
"data": {
"paymentId": "pay_xyz789",
"amount": "100.00",
"currency": "USDC",
"network": "ethereum",
"status": "refunded",
"refundTxHash": "0xabcdef1234567890...",
"refundReason": "Customer requested refund",
"recipientAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb",
"workspaceId": "ws_abc123",
"refundedAt": "2025-01-15T12:00:00Z",
"metadata": {
"orderId": "order_123",
"customerId": "cust_456"
}
}
}

Checkout Session Events

checkout.session.created

Triggered when a new checkout session is created.

Use case: Track checkout funnel, monitor conversion rates.

{
"id": "evt_pqr678",
"type": "checkout.session.created",
"createdAt": "2025-01-15T10:29:00Z",
"data": {
"sessionId": "cs_abc123",
"status": "pending",
"amount": "100.00",
"currency": "USDC",
"network": "ethereum",
"productId": "prod_xyz789",
"workspaceId": "ws_abc123",
"checkoutUrl": "https://checkout.blockeden.xyz/cs_abc123",
"expiresAt": "2025-01-15T11:00:00Z",
"metadata": {
"orderId": "order_123"
}
}
}

checkout.session.completed

Triggered when a checkout session is successfully completed (payment confirmed).

Use case: Track successful checkouts, conversion analytics.

{
"id": "evt_stu901",
"type": "checkout.session.completed",
"createdAt": "2025-01-15T10:35:00Z",
"data": {
"sessionId": "cs_abc123",
"status": "completed",
"amount": "100.00",
"currency": "USDC",
"network": "ethereum",
"productId": "prod_xyz789",
"paymentId": "pay_xyz789",
"workspaceId": "ws_abc123",
"completedAt": "2025-01-15T10:35:00Z",
"metadata": {
"orderId": "order_123"
}
}
}

checkout.session.expired

Triggered when a checkout session expires without payment.

Use case: Track abandoned checkouts, send recovery emails.

{
"id": "evt_vwx234",
"type": "checkout.session.expired",
"createdAt": "2025-01-15T11:00:00Z",
"data": {
"sessionId": "cs_abc123",
"status": "expired",
"amount": "100.00",
"currency": "USDC",
"network": "ethereum",
"productId": "prod_xyz789",
"workspaceId": "ws_abc123",
"expiredAt": "2025-01-15T11:00:00Z",
"metadata": {
"orderId": "order_123"
}
}
}

Event Lifecycle

A typical payment flow produces events in this order:

Alternative flows:

  • Payment expires: payment.failedcheckout.session.expired
  • Payment refunded: payment.refunded (after successful payment)

Event Handling Best Practices

1. Handle Events Idempotently

Always check if you've already processed an event:

async function handleWebhook(event) {
// Check if already processed
const existing = await db.webhookEvents.findOne({
eventId: event.id
});

if (existing) {
console.log('Event already processed:', event.id);
return; // Skip duplicate
}

// Process the event
await processPayment(event.data);

// Mark as processed
await db.webhookEvents.create({
eventId: event.id,
type: event.type,
processedAt: new Date()
});
}

2. Use Metadata for Context

Pass your system's IDs through metadata:

// When creating a payment
const payment = await createPayment({
amount: '100.00',
currency: 'USDC',
metadata: {
orderId: 'order_123',
customerId: 'cust_456',
productSku: 'PROD-001'
}
});

// In your webhook handler
function handlePaymentConfirmed(data) {
const { orderId, customerId, productSku } = data.metadata;
await fulfillOrder(orderId, customerId, productSku);
}

3. Return 200 Quickly

Acknowledge receipt immediately, process asynchronously:

app.post('/webhooks', async (req, res) => {
// Verify signature first
if (!verifySignature(req)) {
return res.status(401).send('Unauthorized');
}

const event = JSON.parse(req.body.toString());

// Return 200 immediately
res.status(200).json({ received: true });

// Process asynchronously
processEventAsync(event).catch(err => {
console.error('Error processing event:', err);
// Log to error tracking service
});
});

4. Handle Unknown Event Types

Be defensive - new event types may be added:

switch (event.type) {
case 'payment.confirmed':
await handlePaymentConfirmed(event.data);
break;

case 'payment.failed':
await handlePaymentFailed(event.data);
break;

default:
// Log but don't fail
console.log('Unknown event type:', event.type);
// Still return 200 to acknowledge receipt
}

Choose based on your use case:

Minimal Setup (E-commerce)

  • payment.confirmed - Fulfill orders
  • payment.confirmed - Fulfill orders
  • payment.failed - Cancel orders and notify customers
  • checkout.session.expired - Track abandoned carts

Full Analytics Setup

  • checkout.session.created - Track checkout starts
  • payment.created - Track payment attempts
  • payment.pending - Update UI with progress
  • payment.confirmed - Fulfill orders
  • payment.failed - Handle failures
  • payment.refunded - Process refunds
  • checkout.session.completed - Track conversions
  • checkout.session.expired - Track abandonment

Testing Events

Test your webhook handler using the dashboard:

  1. Navigate to Accept PaymentsWebhooks
  2. Click Test button on your endpoint
  3. A webhook.test.event will be sent
  4. Check your server logs to verify receipt and processing

Common Payload Fields

FieldTypeAlways PresentDescription
paymentIdstringPayment eventsUnique payment identifier
sessionIdstringCheckout eventsUnique checkout session identifier
amountstringYesPayment amount (decimal string)
currencystringYesCurrency code (USDC, USDT, ETH, etc.)
networkstringYesBlockchain network
statusstringYesCurrent status
workspaceIdstringYesYour workspace identifier
metadataobjectYesCustom data you provided
txHashstringWhen availableBlockchain transaction hash
recipientAddressstringPayment eventsReceiving wallet address

Next Steps

Need Help?