# Check the webhook signatures

# Overview 

Verify the events that Wooshpay sends to your webhook endpoints.

## Wooshpay signature header

The `Wooshpay-Signature` header included in each signed event contains a timestamp and signature.

The timestamp is prefixed by `t=`, and each signature is prefixed by `v1`.

***For example:***

```Plain
Wooshpay-Signature:t=1492774577,v1=6fdfb9c357542b8ee07277f5fca2c6f728bae2dce9be2f91412f4de922c1bae4
```

## Webhook secret key

Wooshpay generates a unique **secret key** for each webhook. `whsec_`

Before verify signatures, you need to retrieve your webhook secret from `webhook.secret` in webhook object.


![1280X1280.PNG](https://api.apifox.cn/api/v1/projects/1296482/resources/388595/image-preview)
 

# Verifying signatures

By comparing the the **signature in the header** to the **expected signature**, You can verify that the even were sent by Wooshpay, not by a third party. 

To verify the signature step by step, you can follow the guide below:

## Step 1: Extract the timestamp and signatures from the header

Split the header, using the `,` character as the separator, to get a list of elements. Then split each element, using the `=` character as the separator, to get a prefix and value pair.

The value for the prefix `t` corresponds to the timestamp, and `v1` corresponds to the signature. You can discard all other elements.

***For example:*** 

```
t=1687845304,v1=6fdfb9c357542b8ee07277f5fca2c6f728bae2dce9be2f91412f4de922c1bae4
```

## Step 2: Prepare the `signed_payload` string

The `signed_payload` string is created by concatenating:

- The timestamp (as a string)
- The character `.`
- The actual JSON payload (the request body)

***For example:*** 

*`1687845304`**+**`.`**+**`JSON payload`*

```JSON
1687845304.{
  "id": "evt_1NNUrjL6kclEVx6Mb1x5dKJ3",
  "object": "event",
  "api_version": "2022-11-15",
  "created": 1687845303,
  "data": {
    "object": {
      "id": "prod_O9oUVgsSaordCT",
      "object": "product",
      "active": true,
      "livemode": true,
      "name": "test",
      "type": "service",
  "livemode": true,
  "pending_webhooks": 1,
  "type": "product.created"
}
```

## Step 3: Determine the expected signature

Compute a HMAC with the SHA256 hash function. 

- Use the endpoint’s webhook secret as the **key**, which you can get it from `webhook.secret` in webhook object
- Use the `signed_payload` string as the **message** which you already prepared in step 2.

Through the **key** + **message**, you can compute a HMAC string, which is **expected signature**

***For example:*** 

```JavaScript
 public static void main(String[] args) {
        String webhookSecret = "whsec_261V2mfsXt1BsOjJbHaQOxnTzhWZKrUE";
        String timestamp = "1687845304";
        String requestBody = "{\"id\":\"evt_1NNUrjL6kclEVx6Mb1x5dKJ3\",\"object\":\"event\",\"api_version\":\"2022-11-15\",\"created\":1687845303,\"data\":{\"object\":{\"id\":\"prod_O9oUVgsSaordCT\",\"object\":\"product\",\"active\":true,\"livemode\":true,\"name\":\"test\",\"type\":\"service\",\"livemode\":true,\"pending_webhooks\":1,\"type\":\"product.created\"}";
        String signedPayload = timestamp+"."+requestBody;
        String signature = hmacSha256(webhookSecret,signedPayload);
        String WooshpaySignature = "t="+timestamp+",v1="+signature;
    }

    /**
     * HMAC-SHA256 
     */
    public static String hmacSha256(String secret, String message) {
        String res;
        try {
            Mac mac = Mac.getInstance("HmacSHA256");
            SecretKey secretKey = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
            mac.init(secretKey);
            byte[] hash = mac.doFinal(message.getBytes());
            res = Hex.encodeHexString(hash);
        } catch (Exception e) {
            return null;
        }
        return res;
    }
```

## Step 4: Compare the signatures

Compare the **signature in the header** to the **expected signature**. 

For an equality match, compute the difference between the **current timestamp** and the **received timestamp**, then decide if the difference is within your tolerance.

To protect against timing attacks, you can use a constant-time string comparison to compare the expected signature to each of the received signatures.

