Skip to main content

Webhooks

Updated over a month ago

What they do

Webhooks push real-time notifications to your systems when competitors change price, eliminating the need to poll for updates.

Best for

  • Teams who need instantaneous awareness of price changes

  • Systems that trigger automated workflows based on competitive pricing

Typical use cases

  • Real-time pricing (automated pricing updates)

  • Triggering promotional adjustments

  • Rapid MAP violation escalation

Creating Webhooks

Currently, we 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 CSM 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.

Did this answer your question?