Skip to main content
Wiser Webhooks
R
Written by Raniel
Updated over 5 months ago

Wiser Webhooks

Content

  • Introduction

  • What is a Webhook

  • Creating Webhooks

  • Configure server for Webhooks

  • Webhook events and payloads

  • Securing the Webhooks

  • Testing Webhooks

Introduction

We know first-hand that reacting to competitors' price changes is crucial for good sales performance and needs to be done fast, and this is a challenge that many companies face.

Wiser webhooks allow you to receive real-time notifications of competitive price changes. It removes the lag introduced by traditional data-sharing methods, allowing you to act faster.

What is a Webhook

Overview

A webhook is an HTTP-based callback function that allows lightweight, event-driven communication between 2 software systems. In simple terms, it is a push system.

With Wiser Webhooks, you'll be able to, for instance, receive price change push notifications directly in your systems as soon as we detect a competitor price change event, eliminating the reliance on batch-style reports and reducing the time it takes for you to become aware of competitor movements, so you can stay on top of the game and be more prepared to compete in a dynamic e-commerce landscape.

How Webhooks work

Webhooks are used by a wide variety of web apps to receive small amounts of data from other apps and to trigger automated workflows. When you subscribe to a webhook event, such as the 'ExtractedPriceChanged' event, our webhook service will monitor changes in the extracted prices of competitor products matched to your product catalog. Whenever a price change is detected, the webhook service will send an HTTPS POST request to the URL endpoint you have specified during webhook creation.

The payload of the webhook request will contain relevant information about the event and any additional data associated with the event. You can process this data on your server, trigger actions, or update your systems based on the received information.

To explore the complete list of available webhook events and their payloads, refer to the "Webhook events and payloads" documentation.

Creating Webhooks

Currently, we can support webhooks for "ExtractedPriceChanged" events only. To create a webhook subscription, go to Settings -> Webhooks and click on 'Create New Webhook':

Note: If you don't see this option in Settings, please reach out to your Wiser representative to enable it for you.

You'll be requested to provide the following information:

  • Webhook Name: A unique name to identify your webhook subscription. Choose a descriptive name that reflects the purpose or functionality of the webhook.

  • Endpoint URL: The URL of the endpoint where you want to receive the webhook notifications. This endpoint should be accessible and capable of handling incoming HTTPS POST requests. Ensure to provide the full URL, including the protocol (e.g., https://yourdomain.com/webhook). Note: HTTPS protocol is required.

  • Product List (optional): Specify a Product List ID(s) to receive notifications only for events coming from competitor products that belong to that SKU list. You will receive notifications for all products matched to your catalog if not specified.

  • Secret: A secret key to sign the content of the webhook payload. This secret key adds an extra layer of security by allowing you to verify the integrity of the received data. The webhook service will sign the payload using the SHA256 algorithm and include the signature in the request headers (x-w-signature-256).

Once the webhook subscription is created, you will start receiving webhook notifications to the specified endpoint URL whenever there is a change in the extracted price of the subscribed products.

Important notes:
To reduce noise, the Webhook System considers the competitor price as the same if the difference between the last extracted price and the previous price falls within the 'Price Comparison' setting defined in https://pricingintel.wiser.com/settings. Only price changes above this threshold will trigger "ExtractedPriceChanged" events.

The first extracted price of a newly discovered and matched product is also considered a price change to keep your systems up to date on all products matched to your target SKUs.

If you're subscribed to regional price intel - extracting prices from competitor websites from multiple locations (zip codes), know that monitoring price changes is done only for the average price across all zip codes or for the main zip code if defined.

In case of notification delivery failure, the webhook system has a built-in retry mechanism. The system will try to re-deliver the message a few times with growing intervals between the retries. The event notification will be discarded if it cannot be successfully delivered within 8 hours of the first failure.

Configure Your Server for Webhooks


Writing the server

Your server needs to:

  • Receive POST request.

  • Generate payload signature.

  • Verify signature from header x-w-signature-256 matches the generated.

You can utilize any language or framework for that.

For example, NodeJS (NestJS framework)
You can check the full example here https://github.com/WiserSolutions/platform-samples/blob/main/webhooks/node/webhook-server/README.md

1. Receive POST request.

```ts 
@Controller()
export class AppController {
/**
* Logger instance
*/
private readonly logger = new Logger(AppController.name);
constructor(private readonly appService: AppService) {}
@Post('webhook')
async processEvent(
@Headers(‘x-w-signature-256’) headerSignature: string,
@Body() data: DeliveryPayload,
) {
this.appService.verifySignature(headerSignature, data);
this.logger.log(`MESSAGE RECEIVED: ${JSON.stringify(data)}`);
}
}
```


2. Generate payload signature.

 ```ts 
/**
* Create Keyed-Hashing representation for text
* HMAC stands for Keyed-Hashing for Message Authentication.
*/
export const hmac = (
text: string,
secret: string,
encoding: BinaryToTextEncoding = 'hex',
algorithm = 'sha256',
addAlgorithmPrefix = true,
) => {
if (!text) return text;
const hash = createHmac(algorithm, secret).update(text).digest(encoding);
return addAlgorithmPrefix ? `${algorithm}=${hash}` : hash;
};
```

3. Verify if the signature from the header x-w-signature-256 matches the generated content data signature.

```ts 
/**
* Verify headerSignature exists.
* Compare data signature with the headerSignature.
*
* @throws exceptions when header signature does not exists or
*/
verifySignature(headerSignature: string, data: DeliveryPayload) {
// check x-w-signature-256 exists
if (!headerSignature)
throw new BadRequestException(`${X_W_SIGNATURE} header is missing`);
// generate payload signature
const payloadSignature = this.signPayload(data);
// verify header signature and content signature match
if (headerSignature !== payloadSignature)
throw new BadRequestException(
`Request signatures do not match. Header signature: ${headerSignature} Payload signature: ${payloadSignature}`,
);
}
```

Exposing localhost to the internet

  1. Install ngrok.

  2. Start the webhook application on localhost

  3. Expose your application from the localhost to public internet
    $ ngrok http 3000

    Version 3.1.1
    Region United States (us)
    Latency -
    Web Interface http://127.0.0.1:4040
    Forwarding https://09f5-2601-640-8000-d4a0-bd9d-56bf-9af3-790f.ngrok-free.app -> http://localhost:3000

  4. Use the generated endpoint https://09f5-2601-640-8000-d4a0-bd9d-56bf-9af3-790f.ngrok-free.app to create/update webhook Endpoint URL.

Webhook events and payloads

When subscribing to a webhook, you will receive event notifications along with specific payload data. This section provides an overview of the supported webhook events and their corresponding payloads.

Webhook delivery payload

The DeliveryPayload structure includes the following properties:

  • subscriptionId (string): The ID of the webhook subscription.

  • timestamp (number): The epoch timestamp when the delivery was made. This timestamp can be used to prevent replay attacks on the client.

  • eventType (string): The type of event, for example "ExtractedPriceChanged".

  • eventData (array of objects): An array containing the events data. For example, array of the "ExtractedPriceChanged" events.


ExtractedPriceChanged Event

The ExtractedPriceChanged provides information about the changed price of a product. It includes the following properties:

  • sku (string): The product SKU.

  • competitorName (string): The name of the seller or competitor.

  • productId (string): The internal product ID in Wiser system.

  • productTitle (nullable string): The title of the product.

  • matchType (string): The type of match for the product.

  • price (number): The updated price of the product.

  • shippingPrice (nullable number): The shipping price of the product, if applicable.

  • availability (nullable boolean): The availability status of the product.

  • crawlDate (string): The date of the product's last crawl in ISO 8601 format.

  • previous (object, optional): Previous extraction data, including the previous price, previous crawl date, and previous shipping price.

Note: every request/push to your endpoint will contain up to 100 events (batch size).


Securing the Webhooks

Securing webhooks is essential to protect the integrity and authenticity of the data transmitted through them. You can implement additional measures to enhance security. This section provides an overview of content signature and timestamp verification, as well as using HTTPS for secure communication.

Using HTTPS for secure communications

To ensure secure communication between your server and the webhook service, we require the use of HTTPS instead of HTTP. HTTPS encrypts the data transmitted between the two endpoints, providing confidentiality and integrity.

When configuring your server to receive webhook requests, make sure to use an SSL/TLS certificate to enable HTTPS. This will encrypt communication and help protect the webhook payload and sensitive information from eavesdropping and tampering.


Verifying content signature

To verify the integrity of the webhook payload, you can use a content signature. The hash signature x-w-signature-256 is included in each header of the incoming request. Follow these steps to verify the content signature:

  1. Retrieve the x-w-signature-256 header from the incoming request header.

  2. Compute the SHA256 hash of the raw payload data using the secret key specified when the webhook subscription was created.

  3. Compare the computed hash with the extracted signature value.

    1. If the computed hash matches the extracted signature, it indicates that the payload has not been tampered with and can be trusted.

    2. If the computed hash does not match the extracted signature, the payload has been altered or corrupted.

Verifying timestamp to prevent replay attacks

To prevent replay attacks, you can verify the timestamp included in the webhook payload. The timestamp represents the epoch time when the delivery was made. Follow these steps to verify the timestamp:

  1. Retrieve the timestamp from the webhook payload.

  2. Compare the timestamp with the current time on your server.

    1. If the timestamp is within an acceptable range (e.g., not too far in the past or future), consider the request as valid and process it.

    2. If the timestamp is outside the acceptable range, reject the request as potentially malicious or replayed.

Verifying the timestamp can mitigate the risk of receiving replayed webhook requests.

Testing the Webhooks

Testing the webhook is an important step to ensure that your webhook integration is working correctly and that you can receive and process events successfully.

Sending a Ping event

To test your webhook integration, you can use the Ping event, which allows you to send a test event to your configured webhook endpoint.

The Ping event includes the following properties:

  • zenId (string): A random ping ID to uniquely identify the event.

  • zenDate (string): The date when the event was generated, formatted in ISO 8601 format.

To send a Ping event and test your webhook integration, locate the create/edit webhook form and click on 'Send Ping Event' button to manually trigger it:


Once hit, the webhook service will send a test event to your configured webhook endpoint using the Ping event structure. The event will include a randomly generated zenId and the current date in ISO 8601 format as zenDate.


Please check the webhook endpoint to ensure that the Ping event is received successfully. You can inspect the payload and verify that the data matches the expected structure.


Still have questions? Please contact our support team at support@wiser.com. We'll be happy to assist you!

Did this answer your question?