> For the complete documentation index, see [llms.txt](https://docs.braidpay.com/braidpay/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.braidpay.com/braidpay/set-up-braidpay/webhooks.md).

# Webhooks

## BraidPay Webhooks Documentation

### Overview

BraidPay uses webhooks to notify your application when payment events occur. When an event occurs, we'll make an HTTP POST request to your configured webhook URL with event details.

### Setting Up Webhooks

1. Navigate to Settings > Webhooks in your BraidPay dashboard
2. Enter your webhook URL (must be HTTPS)
3. Enter a secure webhook secret
4. Save your configuration

### Security

Each webhook request includes a signature in the `X-Webhook-Signature` header. The signature is a HMAC SHA-256 hash of the payment address and amount using your webhook secret.

To verify that the webhook came from BraidPay:

```javascript
const crypto = require('crypto')

function verifyWebhookSignature(secret, toAddress, amount, signature) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(`${toAddress}${amount}`)
    .digest('hex')
  
  return signature === expectedSignature
}

// Example usage:
app.post('/webhook', (req, res) => {
  const signature = req.headers['x-webhook-signature']
  const { toAddress, amount } = req.body
  const webhookSecret = process.env.WEBHOOK_SECRET

  if (!verifyWebhookSignature(webhookSecret, toAddress, amount, signature)) {
    return res.status(401).json({ error: 'Invalid signature' })
  }

  // Process webhook...
  res.json({ received: true })
})
```

The signature is generated using:

* Your webhook secret (from BraidPay dashboard)
* The payment destination address (`toAddress`)
* The payment amount (`amount`)

Always verify the signature before processing webhooks to ensure the request came from BraidPay.

### Webhook Payload

Each webhook POST request contains a JSON payload with the following structure:

```json
{
  "paymentLinkID": "pl_xxx",
  "paymentID": "py_xxx",
  "fromAddress": "0x123...",
  "toAddress": "0x456...",
  "hash": "0xabc...",
  "network": "ETHEREUM",
  "token": "USDC",
  "amount": 100.00,
  "status": "COMPLETED",
  "createdAt": "2025-02-14T12:00:00Z",
  "Payer_Email": "customer@example.com"
}
```

#### Field Descriptions

* `paymentLinkID`: The ID of the payment link, check your payment link page URL in the BraidPay dashboard
* `paymentID`: Unique identifier for the payment
* `fromAddress`: The sender's blockchain address
* `toAddress`: Your receiving blockchain address
* `hash`: Transaction hash on the blockchain
* `network`: Blockchain network (ETHEREUM, POLYGON, BASE, SOLANA)
* `token`: Token used for payment (USDC, USDT, PYUSD)
* `amount`: Payment amount
* `status`: Payment status (PENDING, COMPLETED)
* `createdAt`: Timestamp when payment was created
* `Payer_Email`: Email address of the payer (if provided)

### Retry Policy

If your webhook endpoint returns a non-2xx response code or fails to respond within 10 seconds, we'll retry the webhook with the following schedule:

* 1st retry: 1 minute after initial failure
* 2nd retry: 5 minutes after the previous attempt
* 3rd retry: 15 minutes after the previous attempt
* 4th retry: 30 minutes after the previous attempt
* 5th retry: 1 hour after previous attempt

After 5 failed attempts, the webhook will be marked as failed and no further retries will be attempted.

### Best Practices

1. Verify the webhook signature to ensure the request came from BraidPay
2. Return a 2xx status code as quickly as possible
3. Process webhook data asynchronously
4. Handle duplicate webhook deliveries (use `paymentID` for idempotency)

### Testing Webhooks

1. Use the "Test Webhook" button in the webhook settings to send a test payload
2. Test payload will contain dummy data with "test" values
3. Verify your endpoint can:
   * Validate the signature
   * Parse the JSON payload
   * Handle the data appropriately
   * Respond within the timeout period

### Support

If you need help with webhooks:

1. Ensure your endpoint is accessible and properly configured
2. Verify your signature validation implementation
3. Contact support if issues persist
