Palomma sends events when something important happens. You can register a URL and Palomma will make an HTTP POST request to that URL, with all the information related to the event that occurred.

To enable webhooks, contact the Palomma team and provide us with the URL you want events to be sent to.

Request Structure

Headers

X-Encoded-Data
string

Base64 encoding of the request body

X-Signature
string

Signature used to verify integrity of X-Encoded-Data. Computed using an HMAC-SHA-256 of X-Encoded-Data with the integrityKey assigned to the merchant.

Body

webhookId
string

Unique ID for webhook notification. Should only be repeated if the notification fails to deliver, in which case more attempts to deliver the notification might be made.

timestamp
string

ISO string for when the webhook notification was created.

eventType
enum

One of the following: payin-link.update , payin-source.update , payin-request.update , payout-target.update , payout-request.update

event
object

Authentication

Every webhook Palomma sends is signed to ensure the integrity of the data being sent in the webhook.

Always verify the signature before trusting the contents of the event.

The recommended flow is the following:

  1. Retrieve the request headers X-Encoded-Data and X-Signature.
  2. X-Signature is an HMAC with the SHA256 hash function of X-Encoded-Data. Compute an HMAC-SHA-256 of X-Encoded-Data with the integrityKey assigned to you, and compare it to X-Signature. If the computed signature and X-Signature are not equal, the signature is invalid.
  3. X-Encoded-Data is a Base64 encoded string. Decode it and parse it into a JSON object. If the signature was correct in step 2, you can trust the data in this JSON.

Example

Here’s an example of the steps described above using Node.js.

webhookExample.js
const crypto = require("crypto");

app.post("/", (req, res) => {
  try {
    // Retrieve information from headers to perform validation.
    const encoded_data = req.headers["x-encoded-data"];
    const signature = req.headers["x-signature"];

    // The integrity key provided by Palomma.
    const integrityKey = process.env.PALOMMA_INTEGRITY_KEY;

    // Create an HMAC for validation purposes.
    const signatureRequest = crypto
      .createHmac("sha256", integrityKey)
      .update(encoded_data)
      .digest("hex");

    // Decode the base64-encoded string.
    const decodedData = Buffer.from(encoded_data, "base64").toString("utf-8");

    // Check if the signature matches
    if (signature === signatureRequest) {
      // Code to execute when a valid webhook is received.
      res.status(200).json({ msg: "Success: Webhook is valid!" });
    } else {
      // Response sent when the webhook is invalid.
      res.status(401).json({ msg: "Error: Webhook is NOT valid!" });
    }
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

Duplicate Requests

Palomma will try resending webhooks that fail to deliver. In these cases, the same webhookId and timestamp will be sent.

When you successfully process a webhook, we recommend you store the webhookId. If you see the same webhookId in the future, you can safely ignore it.

It is important that you do not process the same webhook multiple times.