Webhook Overview

Stableyard sends real-time notifications to your server when important events occur. Configure a webhook endpoint to receive these updates.

Event Types

EventDescription
payment.createdPayment order created
payment.pendingPayment awaiting confirmation
payment.completedPayment successfully settled
payment.failedPayment failed
account.createdMoney Account registered
vault.createdVault deployed
vault.fundedDeposit received in vault
kyc.completedKYC verification passed
kyc.failedKYC verification failed

Webhook Payload

All webhooks follow this structure:
{
  "event": "payment.completed",
  "timestamp": "2024-01-15T10:30:00Z",
  "data": {
    // Event-specific data
  },
  "signature": "sha256=abc123..."
}

Event Payloads

payment.completed

{
  "event": "payment.completed",
  "timestamp": "2024-01-15T10:30:00Z",
  "data": {
    "transactionId": "tx_abc123",
    "quoteId": "quote_xyz789",
    "payerId": "user_sender",
    "payerAddress": "sender@partner",
    "recipientId": "user_recipient",
    "recipientAddress": "recipient@partner",
    "amount": "100.00",
    "token": "USDC",
    "chain": "Base",
    "status": "completed",
    "settledAt": "2024-01-15T10:30:00Z"
  }
}

account.created

{
  "event": "account.created",
  "timestamp": "2024-01-15T10:30:00Z",
  "data": {
    "userId": "user_abc123",
    "username": "alice",
    "paymentAddress": "alice@partner",
    "createdAt": "2024-01-15T10:30:00Z"
  }
}

vault.funded

{
  "event": "vault.funded",
  "timestamp": "2024-01-15T10:30:00Z",
  "data": {
    "userId": "user_abc123",
    "vaultAddress": "0x...",
    "amount": "500.00",
    "token": "USDC",
    "chain": "Ethereum",
    "txHash": "0x...",
    "sourceAddress": "0x..."
  }
}

kyc.completed

{
  "event": "kyc.completed",
  "timestamp": "2024-01-15T10:30:00Z",
  "data": {
    "userId": "user_abc123",
    "verificationLevel": "full",
    "completedAt": "2024-01-15T10:30:00Z"
  }
}

Signature Verification

Always verify webhook signatures to ensure authenticity:
import crypto from 'crypto';

function verifyWebhook(payload: string, signature: string, secret: string): boolean {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  return `sha256=${expectedSignature}` === signature;
}

// In your webhook handler
app.post('/webhook', (req, res) => {
  const signature = req.headers['x-stableyard-signature'];
  const isValid = verifyWebhook(
    JSON.stringify(req.body),
    signature,
    process.env.WEBHOOK_SECRET
  );

  if (!isValid) {
    return res.status(401).send('Invalid signature');
  }

  // Process webhook
  const { event, data } = req.body;
  // ...

  res.status(200).send('OK');
});

Retry Policy

AttemptDelay
1Immediate
21 minute
35 minutes
430 minutes
52 hours
After 5 failed attempts, the webhook is marked as failed.

Best Practices

Return 200 Quickly

Acknowledge receipt immediately, process async

Verify Signatures

Always validate webhook authenticity

Handle Idempotency

Events may be delivered multiple times

Log Everything

Store payloads for debugging

Configuring Webhooks

Contact support to configure your webhook endpoint:
  • Endpoint URL: Your HTTPS endpoint
  • Events: Which events to receive
  • Secret: Shared secret for signatures
Next: See SDKs — client libraries for easier integration.