> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chipipay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Signature Validation

> Learn how to verify webhook signatures to ensure secure communication with Chipi Pay

# Signature Validation

For security, all webhooks from Chipi Pay include an HMAC signature in the `chipi-signature` header. You should verify this signature to ensure the webhook is from Chipi Pay and hasn't been tampered with.

## Why Verify Signatures?

<Warning>
  Always verify webhook signatures in production. This prevents unauthorized requests and ensures data integrity.
</Warning>

Webhook signature verification:

* **Prevents spoofing** - Ensures requests are from Chipi Pay
* **Protects data integrity** - Detects if payloads have been modified
* **Security best practice** - Industry standard for webhook security

## Getting Your Webhook Secret

1. Go to your [webhook configuration](https://dashboard.chipipay.com/configure/webhooks) page in the Chipi Dashboard
2. Copy your **Webhook Signing Secret** (it looks like `whsec_****`)
3. Store it securely as an environment variable

## Implementation

### Step 1: Install Required Dependencies

```bash theme={null}
npm install crypto
```

### Step 2: Create a Signature Verification Function

```typescript theme={null}
import { createHmac, timingSafeEqual } from 'crypto';

function verifyWebhookSignature(
  payload: string,
  receivedSignature: string,
  secretKey: string
): boolean {
  try {
    const expectedSignature = createHmac("sha256", secretKey)
      .update(payload)
      .digest("hex");

    // Use timing-safe comparison to prevent timing attacks
    return timingSafeEqual(
      Buffer.from(expectedSignature, "hex"),
      Buffer.from(receivedSignature, "hex")
    );
  } catch (error) {
    return false;
  }
}
```

### Step 3: Verify in Your Webhook Handler

```typescript theme={null}
// Example webhook handler (adjust based on your framework)
export async function POST(request: Request) {
  const payload = await request.text();
  const signature = request.headers.get('chipi-signature');
  const webhookSecret = process.env.CHIPI_WEBHOOK_SECRET!; // Your whsec_**** key

  if (!signature || !verifyWebhookSignature(payload, signature, webhookSecret)) {
    return new Response(
      JSON.stringify({ error: 'Invalid signature' }), 
      { status: 401 }
    );
  }

  const event = JSON.parse(payload);

  // Handle the webhook event
  if (event.event === 'transaction.sent' && event.data.transaction.status === 'SUCCESS') {
    // Handle successful payment
    const transaction = event.data.transaction;
    console.log(`Payment received: ${transaction.amount} USDC from ${transaction.senderAddress}`);
    
    // Update your database, send confirmation emails, fulfill orders, etc.
  }

  return new Response(JSON.stringify({ received: true }), { status: 200 });
}
```

## Security Best Practices

<Tip>
  * Always use timing-safe comparison functions to prevent timing attacks
  * Store your webhook secret in environment variables, never in code
  * Verify signatures before processing any webhook data
  * Log failed signature verifications for security monitoring
</Tip>

## Common Issues

### Signature Mismatch

If you're getting signature mismatches:

1. Ensure you're using the correct webhook secret from your dashboard
2. Verify you're reading the raw request body (not parsed JSON)
3. Check that the `chipi-signature` header is being read correctly
4. Make sure you're using SHA-256 HMAC

### Environment Variables

Store your webhook secret securely:

```bash theme={null}
# .env
CHIPI_WEBHOOK_SECRET=whsec_your_secret_key_here
```

## Next Steps

* Learn more about [webhook events](/sdk/api/introduction)
* Set up your [webhook configuration](https://dashboard.chipipay.com/configure/webhooks)
* Explore [React SDK hooks](/sdk/react/hooks/use-create-wallet)
