How to subscribe, use Webhooks

Merchant webhooks tutorial

Merchant Webhooks has just been released! 🎉 Pulling event via API method stay another good alternative (plugin integration is using pulling for now) but using webhooks especially for merchants with custom API integration that want instantness of information could be the solution.

How to subscribe to Merchant webhooks

There 2 ways to do it: - through your merchant portal app - though APIs

1-Subscribe through merchant portal app

Connect your merchant portal app and start the Webhooks configuration on the dedicated tab of your personal information page.

Start configuring webhooks

Add a new webhook endpoint

You can add a new webhook endpoint by clicking "start" or "add a new endpoint".

Start entering a new webhook endpoint

Configure your endpoint with security fields

Mandatory fields *

  • Endpoint URL *: name of URL endpoint that will be callback when a event subscribed occurs.

  • Authentication method *: choose among the authentication method available [None | Basic auth | API key]

Fields to complete according authentication method:

None
Basic auth
API key

Secret *

Identifier/login *

Secret (API key) *

Signature key

Password *

Signature key

Signature key

Identifier/login and password fields are required for basic auth only.

Secret is required for authentication None or API key. Secret is a string shared between you and scalexpert.

Signature key is optional field for signing events with header X-BAAS-SIGNATURE. This add more security if needed.

Configure your endpoint to listen events

Chose events types to listen on the endpoint webhook url. Events types listed are the ones available for you that fit your solutions subscribed.

You can listen multiple events types on the same endpoint. But we recommend subscribing separated endpoints because it will be easier to parse the payload according event type structure. see more details on event types there.

Manage webhooks endpoints

Once webhooks added, you can manage your webhooks endpoints at the webhooks tab. Manage webhooks allow you to change the configuration, activate/deactivate events.

You can activate/deactivate webhooks at any time for all events subscribed or events by events.

Manage webhooks endpoints

Test your webhooks configuration

We have added a special event type "HELLO_WORLD" to allow you testing your webhooks url configuration.

Retrieve events

You can retrieve all events received and get details though merchant-webhooks API.

2-Subscribe through merchant-webhooks API

All the features described below and more are available though merchant-webhooks API.

The logic is the same as described in above chapters.

Configure your webhook endpoints url to listen events from one event type code with API PUT /webhooks

At minimum one "evenTypeCode" is required in the body of the request. The following values are possible: "ANY" if you want to listen all event types depending on your solutions subscription {a dedicated "evenTypeCode"} to listen all events from a dedicated event type code "HELLO_WORD" special value to test your configuration only

Complete your configuration with "url" and security attributes:

"url": enter your webhook url endpoint (required if configuration active)

Security attributes (required if configuration active):

"authMethod ": choose among the authentication method available [None | Basic auth | API key] Fields to complete according authentication method:

Mandatory fields *

None
Basic auth
API key

secret *

authLogin *

secret (API key) *

keyForSignature

authPassword *

keyForSignature

keyForSignature

Optional attributes:

"emailForAlerts": enter an email address to receive alerts when an event is not successfully delivered to your webhook

"activeEventCodes": list of "eventsCodes" you want to listen. by default all eventsCodes from the mentioned "eventTypeCode" are listened

Activate your configuration

You can update your configuration many times till attribute "activate": false is mentioned.

"active": true make your configuration active.

Example PUT /webhooks using webhook.site as receiver
{
    "eventTypeCode": "HELLO_WORLD",
    "active": true,
    "url": "https://webhook.site/<put here your generated token>",
    "authMethod": "NONE",
    "secret": "mySuperSecretOrMyAPIKey",
    "emailForAlerts": "<put here your generated token>@emailhook.site"
}

Test your configuration

You can Verify your configuration with API GET /webhooksTest your webhook endpoint with API POST /events/tests/_trigger to trigger an "HELLO_WORLD" event (see below example).

This will trigger an event "HELLO_WORLD" to the dedicated configuration. No parameter are required. Event received is factice and will be structured as normal event but with "HELLO_WORD" payload data.

Example "HELLO_WORLD" event
{
            "timestamp": "2024-12-13T15:20:26.391Z",
            "id": "03e14f55-845c-470e-bfec-eef18c76b111",
            "correlationId": "675c50b9110d5a53694b00eec5d27f3f",
            "eventTypeCode": "HELLO_WORLD",
            "data": {
                "eventTypeCode": "HELLO_WORLD",
                "helloWorldMessage": "Hello World ! This event was generated at 2024-12-13T15:20:26.391Z"
            },
            "status": "OK",
            "timestampOfLastDeliveryAttempt": "2024-12-13T15:20:26.620Z",
            "httpStatusCodeOfLastDeliveryAttempt": 200
        }
Result of getting event on Webhook.site

Consume webhooks events

Once your configuration is tested and activated you will received automatically events on your webhook url. Each event would be structured as:

Event request Body structure
{
    "timestamp": "2023-06-27T13:20:30.456Z",
    "id": "44f5060e-a89c-11ed-afa1-0242ac120002",
    "correlationId": "7d9670fe-a0cf-4073-afde-bdc61ca49f75",
    "eventTypeCode": "SC_SUBSCRIPTION",
    "eventCode": "SC_SUBSCRIPTION_PRE_ACCEPTED",
    "data": {
      "eventTypeCode": "SC_SUBSCRIPTION",
      "eventCode": "SC_SUBSCRIPTION_PRE_ACCEPTED",
      "merchantGlobalOrderId": "MYORDER-12345",
      "financedAmount": 500.00,
      "consolidatedStatus": "PRE_ACCEPTED"
    }
}

"Data" structure is depending on related "eventTypeCode". see more details on event types.

Once processed by your server and response is 200 OK or 201 CREATED, event is considered as consumed and will not be resent.

If the response <> 200 OK and 201 CREATED, then event is considered as not consumed and a replay operation will occur according the replay mechanism (every 10 minutes during 5 days). Each replay operation will be counted.

Retrieve webhooks events

At any moment, you can retrieve events sent with API /eventsfiltered by status [OK| ERROR|INACTIVE |NO_CONFIG] or a specific "eventTypeCode" or "eventCode" for a period.

Status meaning:

  • OK: Event with status 200 OK or 201 CREATED

  • ERROR : event with status <> 200 OK and 201 CREATED

  • INACTIVE: event with configuration inactive

  • NO_CONFIG: no configuration found for this event

  • (KILLED): event killed by scalexpert support team for internal reason

Even if a configuration is inactive or isn't found, you can still retrieve events through API GET /events. This functionality enables you to pull events on demand, allowing for more flexible data management.

A list of events with their status will be returned:

List of events sent
{
  "totalEventCount": 5,
  "events": [
    {
      "timestamp": "2023-11-02T01:30:00.00Z",
      "id": "bf6f6023-93a2-4266-9a2c-3579d803c09c",
      "correlationId": "7d9670fe-a0cf-4073-afde-bdc61ca49f75",
      "eventTypeCode": "SC_SUBSCRIPTION",
      "eventCode": "SC_SUBSCRIPTION_ACCEPTED",
      "data": {
        "eventTypeCode": "SC_SUBSCRIPTION",
        "eventCode": "SC_SUBSCRIPTION_ACCEPTED",
        "merchantGlobalOrderId": "340005489",
        "financedAmount": 119.9,
        "consolidatedStatus": "ACCEPTED"
      },
      "replayCount": 10,
      "status": "ERROR",
      "timestampOfLastDeliveryAttempt": "2023-01-29T10:05:38.429Z",
      "httpStatusCodeOfLastDeliveryAttempt": 401
    },
    {
      "timestamp": "2023-02-15T01:30:00.00Z",
      "id": "bf6f6023-93a2-4266-9a2c-3579d803c10c",
      "correlationId": "7d9670fe-a0cf-4073-afde-bdc61ca49f76",
      "eventTypeCode": "SC_SUBSCRIPTION",
      "eventCode": "SC_SUBSCRIPTION_REJECTED",
      "data": {
        "eventTypeCode": "SC_SUBSCRIPTION",
        "eventCode": "SC_SUBSCRIPTION_REJECTED",
        "merchantGlobalOrderId": "340005490",
        "financedAmount": 500.0,
        "consolidatedStatus": "REJECTED"
      },
      "replayCount": 0,
      "status": "ok",
      "timestampOfLastDeliveryAttempt": "2023-02-15T10:05:38.429Z",
      "httpStatusCodeOfLastDeliveryAttempt": 200
    },
    ...
  ]
}

Verify signature of webhooks events (optional)

In the webhook configuration, If you enter a "keyForSignature" value then for each event sent thse headers "X-BAAS-SIGNATURE" and "X-BAAS-SIGNATURE-TIMESTAMP" will be provided. "X-BAAS-SIGNATURE" header value will be computed using HMAC-SHA256 algorithm and combining the payload string of event and the "keyForSignature" value. This will ensure that payload of event are correct and not falsified by malevolent actor.

Thus, you would need to verify the header "X-BAAS-SIGNATURE" before parsing the event payload.

Header "X-BAAS-SIGNATURE-TIMESTAMP" is intended to check if event received is "freshly" sent and not a older one.

Java - sample of function to verify the X-BAAS-SIGNATURE (1/2)
**
* Example of a REST/JSON webhook endpoint with validation of the signature contained in the HTTP header X-BAAS-SIGNATURE.
*
* @param webhookEventAsString: Body of the http request as String. The body must be a JSON object with a structure compatible with the event format described in the developer portal.
* @param httpRequest:     The HttpServletRequest automatically injected by Spring (used to get headers)
* @return the response must be empty, the only important point is that you must return the status code 200-OK or 201-CREATED to acknowledge that the event has been taken into account/processed
* (if the returned status code is NOT 200-OK or 201-CREATED, the event will be retriggered/redelivered in few minutes)
*/
@PostMapping(value = "/webhooks/smart-credit-subscription", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Void> snippet_webhookForSmartCreditSubscription(@RequestBody String webhookEventAsString, HttpServletRequest httpRequest) {

    // Get the key to use to check the signature of the body of the http request. The key is defined by the merchant during the declaration of the webhook endpoint in the merchant portal.
    String keyForSignature = "123456";

    // Check if the signature of the request body (with keyForSignature) and the signature in the HTTP header X-BAAS-SIGNATURE match
    boolean isSignatureValid = snippet_isSignatureValid(webhookEventAsString, keyForSignature, httpRequest);

    if (isSignatureValid) {
        // If the signature is valid...
        //      parse the webhookEventAsString to some POJO class WebhookEvent ...
        //      process the webhookEvent...
        //      return the status code 200-OK or 201-CREATED
        return ResponseEntity.ok().build(); // The response body must be empty, only the returned HTTP status code is important
    } else {
        // If the signature is NOT valid...
        //      return the status code 400-BAD-REQUEST (could be also 403-FORBIDDEN...)
        return ResponseEntity.badRequest().build(); // The response body must be empty, only the returned HTTP status code is important
    }
}

Last updated

Was this helpful?