Back to Help Center

Webhooks Guide

Receive real-time notifications when payment events occur.

What are Webhooks?

Webhooks are HTTP callbacks that notify your server when events happen in Moneta. Instead of polling the API, webhooks push data to you in real-time.

Setting Up Webhooks

  1. Go to your Moneta dashboard
  2. Navigate to Settings → Webhooks
  3. Add your endpoint URL (must be HTTPS)
  4. Select the events you want to receive
  5. Save and copy your webhook secret

Webhook Events

EventDescription
payment.createdA new payment link was created
payment.processingTransaction detected, awaiting confirmation
payment.completedPayment confirmed and settled
payment.failedPayment failed or was rejected
payment.expiredPayment link expired

Webhook Payload

Each webhook sends a JSON payload with event details:

{
  "id": "evt_abc123",
  "type": "payment.completed",
  "created_at": "2024-01-15T10:30:00Z",
  "data": {
    "payment_id": "pay_xyz789",
    "amount": "100.00",
    "currency": "USDC",
    "status": "completed",
    "tx_hash": "0x...",
    "recipient_address": "0x...",
    "metadata": {
      "order_id": "ORD-1234"
    }
  }
}

Verifying Webhook Signatures

Always verify webhook signatures to ensure requests are from Moneta:

// Node.js example
const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

The signature is sent in the X-Moneta-Signature header.

Best Practices

Security

  • Always verify signatures
  • Use HTTPS endpoints only
  • Keep webhook secrets secure

Reliability

  • Return 200 quickly
  • Process async if needed
  • Handle duplicates idempotently

Retry Policy

If your endpoint doesn't return a 2xx status, we'll retry with exponential backoff:

  • 1st retry: 1 minute
  • 2nd retry: 5 minutes
  • 3rd retry: 30 minutes
  • 4th retry: 2 hours
  • 5th retry: 24 hours

After 5 failed attempts, the webhook is marked as failed and won't be retried.

Testing Webhooks

Use these tools to test your webhook implementation:

  • Moneta Dashboard: Send test events from Settings → Webhooks
  • ngrok: Expose local endpoints for testing
  • webhook.site: Inspect webhook payloads

Example Implementation

// Express.js webhook handler
app.post('/webhooks/moneta', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-moneta-signature'];
  
  if (!verifyWebhook(req.body, signature, WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  const event = JSON.parse(req.body);
  
  switch (event.type) {
    case 'payment.completed':
      // Fulfill the order
      fulfillOrder(event.data.metadata.order_id);
      break;
    case 'payment.failed':
      // Notify the customer
      notifyPaymentFailed(event.data.payment_id);
      break;
  }
  
  res.status(200).send('OK');
});

Pro Tip

Store the event ID and check for duplicates before processing. This ensures idempotency if the same webhook is delivered multiple times.