6. Webhooks

Get automatic notifications on FXaaS via webhooks.

With FX as a Service webhooks you can register a URL of your application, in order to receive notifications regarding changes in customer and transaction status.

How do webhooks work?


After registering the desired URL through our services, you will be notified whenever there is a change in the status of the customer or transaction.

Event subscription


The FXaaS API allows each event to be enrolled in a single webhook subscription. For example, the CUSTOMER_STATUS_UPDATED event can only be registered in one webhook subscription.

It's important to note that this rule applies to each environment, and if a webhook subscription is deleted, the events that were previously registered in it can be enrolled in other webhooks.

By following these guidelines, we can ensure proper event management and streamline webhook subscriptions in the FXaaS API.

Verification


Every notification sent by the FX as a Service webhook to your endpoint is signed.
We do this by including a header named x-fxaas-signature in each event we send. This will allow you to verify and ensure that the event sent is originally from FXaaS.
You will need to verify signatures manually with your own solution.

Customized user-agent


To enhance integration reliability, all requests made through the FXaaS API will be accompanied by a customized user-agent. This user-agent acts as an extra layer of security, making it difficult for third-party systems or malicious individuals to impersonate Remessa Online.

For added security, please note the following information about this feature:

  • The user-agent will be provided to partners alongside their access credentials.
  • Partners must ensure that their firewall allows requests originating from this specific user-agent.
  • To maintain optimal security measures, we recommend that partners only allow the FXaaS user-agent and avoid releasing any other user-agent.

By following these guidelines, you will have a more secure integration with the FXaaS API.

Responding to webhook events


Once you have received an event from one of your webhook subscriptions, it is essential to reply with a successful status code. This way, the API will understand that you have successfully consumed the message and are aware of the event that took place.

This step is crucial to prevent the retransmission of new events to you. In cases where we do not receive a successful response, our system attempts to resend the event up to 5 times. The purpose of these retry attempts is to ensure that our partners are informed about the occurred event and can reflect it in their systems.

Validating the signatures


📍 1. Extract timestamp and signature from Header

Split in the header using the character , as a separator to get the list of elements.
Once that's done, do another split using the = character as a separator, to get the prefix and value.
The value obtained in the prefix t corresponds to the timestamp and the v1 corresponds to the signature. You can discard other values.

📍 2. Prepare string to subscribe

You need to create a string and concatenate the following information:

  • The timestamp (as string)
  • The caractere .
  • The JSON payload (request body, in string format)

📍 3. Set the expected signature

Compute the HMAC with the SHA256 hash function. Use the secret received when creating the webhook and use the string signed_payload as the message.

Example in Node.JS:

it.only('should validate signature', async () => {
    const expectedTimestamp = 1670617397963;
    const eventString = '{"id":"295d0ac3-d7a1-4ac9-a518-5eeac10b820f","createdAt":"2022-12-09T20:23:17.143Z","event":"CUSTOMER_STATUS_UPDATED","data":{"customerId":"e0ef0339-48bc-4b39-9d7d-07c55d18dd8e","status":"UNDER_ANALYSIS"}}';
    console.log(eventString);

    const secret = '96cef49dea3278d6322ddc78749c8244e78a247ff41181b8e7c014d4a8018d10';

    const expectedSignature = crypto
      .createHmac('sha256', secret)
      .update(`${expectedTimestamp}.${eventString}`)
      .digest('hex');

    jest
      .useFakeTimers()
      .setSystemTime(new Date(expectedTimestamp));

    console.log(expectedSignature);

    expect('a727f52fee33d7c4c20b618e210ff21caa493692ee0dba3129ad24fb457252ed').toEqual(expectedSignature);
  });

📍 4. Compare signatures

Compare the signature sent by FX as a Service in the Header with the signature you generated in Step 2.

Events


All webhook events come with a core payload (as described in the code example).

TypeEventDescription
CUSTOMERCUSTOMER_STATUS_UPDATEDA customer has been updated in the FXaaS.
TRANSACTIONTRANSACTION_STATUS_UPDATEDA transaction has been updated in the FXaaS.
BATCHBATCH_DAILY_REPORTEDThe Inbound transaction batches of the day were closed.
PAYMENT ORDERPAYMENT_ORDER_RECEIVEDA customer has received a payment request.

Customer


{
    "id": "649a384f-c8bd-41de-a178-cf3085bb67e3",
    "createdAt": "2022-04-18T19:06:47.252Z",
    "event": "CUSTOMER_STATUS_UPDATED",
    "data": {
        "customerId": "9d3fca1a-b03a-40d0-8fbf-4fa044c5bff0",
        "status": "UNDER_ANALYSIS"
    }
}

📘

Customer status

Check the Customer Registration Guide to learn more about it.

Transaction


{
    "id": "50441034-af1f-4119-981a-673e60e0e8ff",
    "createdAt": "2022-05-05T17:54:41.447Z",
    "event": "TRANSACTION_STATUS_UPDATED",
    "data": {
        "status": "CANCELED",
        "transactionId": "c59171ea-7e23-481c-b31e-0839d065e740"
    }
}

📘

Transaction status

Check the Transaction Guide to learn more about it.

Batch


{
        "id": "bb299d5b-0653-4f09-a8fd-6577d6faca93",
        "createdAt": "2022-05-05T17:54:41.447Z",
        "callbackUrl": "https://eobes1k2kvp9auc.m.pipedream.net",
        "eventType": "BATCH_DAILY_REPORTED",
        "data": [
            {
                "direction": "INBOUND",
                "currency": "EUR",
                "batchId": "2ded51b0-4708-450f-ba39-619541ff79e5",
                "numberOfTransactions": 4,
                "respectiveDate": "2022-05-05",
                "totalAmount": {
                    "value": 1234.56,
                    "currency": "EUR"
                }
            }
        ]
    }

📘

Batch Payment

Check the Money Flow Guide to learn more about it.

Payment Order

{
        "id": "f6d84a01-a153-4beb-8e18-943d57787e32",
        "createdAt": "2022-10-20T19:31:17.734Z",
        "callbackUrl": "https://eobes1k2kvp9auc.m.pipedream.net",
        "eventType": "PAYMENT_ORDER_RECEIVED",
        "data": {
            "paymentOrderId": "acc32370-3174-479e-80a5-5869fa9487bc"
        }

📘

Payment Order

Check the Payment Order Guide to learn more about it.