Highlight

Webhooks allow you to set up a notification system that can be used to receive updates on certain requests made to the GetEquity API.

Introduction

Generally, when you make a request to an API endpoint, you expect to get a near-immediate response. However, some requests may take a long time to process, which can lead to timeout errors. In order to prevent a timeout error, a pending response is returned. Since your records need to be updated with the final state of the request, you need to listen to events by using a webhook URL.
We recommend that you use webhook to provide value to your customers over using callbacks or polling. With callbacks, we don’t have control over what happens on the customer’s end. Neither do you. Callbacks can fail if the network connection on a customer’s device fails or is weak or if the device goes off after a transaction.

Create a webhook URL

A webhook URL is simply a POST endpoint that a resource server sends updates to. The URL needs to parse a JSON request and return a 200 OK:
// Using Express
app.post('/webhook-url', function (req, res) {
  // Retrieve the request's body
  const event = req.body;
  // Do something with event
  res.send(200);
});
When your webhook URL receives an event, it needs to parse and acknowledge the event. Acknowledging an event means returning a 200 OK in the HTTP header. Without a 200 OK in the response header, we’ll keep sending events for the next 15mins
If you have long-running tasks in your webhook function, you should acknowledge the event before executing the long-running tasks. Long-running tasks will lead to a request timeout and an automatic error response from your server. Without a 200 OK response, we retry as described in the paragraph above.

Verify event origin

Since your webhook URL is publicly available, you need to verify that events originate from GetEquity and not a bad actor. Signature validation is a way to ensure events to your webhook URL are from GetEquity:

Signature Validation

Events sent from GetEquity carry the x-getequity-signature header. The value of this header is a HMAC SHA256 signature of the event payload signed using your secret key. Verifying the header signature should be done before processing the event:
const crypto = require('crypto');
const secret = process.env.SECRET_KEY;

. . .
. . .

// Using Express
app.post('/webhook-url', function (req, res) {
  //validate event
  const hashParams = Buffer.from(JSON.stringify(req.body));
  const hash = crypto
    .createHmac('sha256', secret)
    .update(hashParams)
    .digest('base64');
  if (hash == req.headers['x-getequity-signature']) {
    // Retrieve the request's body
    const event = req.body;
    // Do something with event
  }
  res.send(200);
});

Go live checklist

Now that you’ve successfully created your webhook URL, here are some ways to ensure you get a delightful experience:
  1. Add the webhook URL on your GetEquity dashboard
  2. Ensure your webhook URL is publicly available (localhost URLs cannot receive events)
  3. Test your webhook to ensure you’re getting the JSON body and returning a 200 OK HTTP response
  4. If we don’t get a 200 OK HTTP response from your webhooks, we flagged it as a failed attempt
  5. Failed attempts are retried every 5 minutes for the next 15 minutes

Supported events

  {
  "webhook_event": "transaction.created",
  "transaction": {
  "type": "Sell",
  "status": "Completed",
  "_id": "65f2bb7574a8f6000261296d",
  "user": "622cb6057649950004776f03",
  "token": "622f3ca399482e00041b1a09",
  "currency": "USD",
  "reference": "GETXN_TKN_SELL_5QnhAAON8",
  "from": "622cb6057649950004776f03",
  "to": "65f0a19b25b2af00020c1233",
  "volume": 20,
  "price": 10,
  "owner_model": "organisation",
  "createdAt": "2024-03-14T08:55:17.749Z",
  "updatedAt": "2024-03-14T08:55:17.749Z",
  "__v": 0
  }
}

Types of Events

Below are the events we currently send. This list might be expanded accordingly in the future.
EventDescription
Transaction.createdA transaction order was successful
Order.createdan order was created successfully
Order.failedAn order failed