If you configure a webhook endpoint, Fluidcoins will notify you about certain events that occur. Events like crypto deposits, widget payments, and others

Security

When you add a webhook address to Fluidcoins, we will generate a secret key for that endpoint. We will then sign each request we make to the address with the secret so you can verify the webhook is actually being sent by Fluidcoins.

We also add information to help you guard against replay attacks.

📘

Secrets are unique per endpoint

You can create up to 5 webhook endpoints in Fluidcoins. Albeit only one can be active and each one comes with their own unique secret key

Verifying a webhook

We make use of Svix to send and manage our webhooks infrastructure and have linked the relevant link below. You can also find an example of what verification looks like below

const { Webhook } = require('svix');
const bodyParser = require('body-parser');

app.post(
  '/v1/hook',
  bodyParser.raw({ type: 'application/json' }),
  (req, res) => {
    res.json({});
    const payload = req.body;
    const headers = req.headers;

    const wh = new Webhook(secret);
    let msg;
    try {
      msg = wh.verify(payload, headers);
      console.log(msg);
      // Do something with the message...
    } catch (err) {
      console.log(err);
      return;
    }
  }
);
http.HandleFunc("/webhook", func(w http.ResponseWriter, r *http.Request) {
        headers := r.Header
        // var b = new(bytes.Buffer)
       // _,err := io.Copy(b,r.Body)
        payload, err := io.ReadAll(r.Body)
        if err != nil {
            w.WriteHeader(http.StatusBadRequest)
            return
        }

        err = wh.Verify(payload, headers)
        if err != nil {
            w.WriteHeader(http.StatusBadRequest)
            return
        }

        // Do something with the message...

        w.WriteHeader(http.StatusNoContent)

    })
use Svix\Webhook;
use Svix\Exception\WebhookVerificationException;

Route::post('webhook', function(Request $request) {
    $payload = $request->getContent();
    $headers = collect($request->headers->all())->transform(function ($item) {
        return $item[0];
    });

    try {
        $wh = new Webhook("secret");
        $json = $wh->verify($payload, $headers);

        # Do something with the message...

        return response()->noContent();
    } catch (WebhookVerificationException $e) {
        return response(null, 400);
    }
});
require 'svix'

class WebhookController < ApplicationController
  protect_from_forgery with: :null_session # disables CSRF middleware; required for API endpoints

  def index
    begin
      payload = request.body.read
      headers = request.headers
      wh = Svix::Webhook.new("secret")

      json = wh.verify(payload, headers)

      # Do something with the message...

      head :no_content
    rescue
      head :bad_request
    end
  end
end

More examples can be found below

Events

{
  "data": {
    "address_reference": "ADDR_nuMpy8d1neLg8Og79UVjM",
    "amount": 40990000,
    "coin": "XRP",
    "destination_tag": 76,
    "domain": "test",
    "from": "rn8ds8NkpPQHafYsaroh9g7XXyHrX4rzce",
    "hash": "160EEBB7896757134AE8A9CB6C33D973B67CB81E2495B6D66D414463B25CCF03",
    "human_readable_amount": 40.99,
    "on_chain": {
      "block_hash": "",
      "block_height": 20132410
    },
    "to": "rH31ezWWzunaGfcxuqE1wozGNDZ6aTL1Uj",
    "transaction_reference": "ADDR_TRANS_QbhOHoOXJ5JDNbcV0AQdH"
  },
  "event": "address.deposit"
}
{
  "data": {
    "customer": {
      "email": "[email protected]",
      "reference": "CUS_iXB9OpeONY1zKuSi3dcDF"
    },
    "domain": "test",
    "fiat": {
      "amount": 100000,
      "currency": "NGN",
      "human_readable_amount": 1000
    },
    "metadata": {
      "key": "value",
    },
    "payment": {
      "amount": 10000000000,
      "coin": "DOGE",
      "destination_tag": 0,
      "from": "",
      "hash": "f70bef760f0b533db3577ba78820cbccd8a473f3780d0f82cb72b7f6884b6dbe",
      "human_readable_amount": 100,
      "memo": "",
      "to": "npM7ARfbpc1wF1n3gqpgYF4QtNKBvZ2Zvu"
    },
    "status": "success",
    "transaction_reference": "TRANS_V5ZgLE3sqmQWAvi7PTesy"
  },
  "event": "widget.payment"
}

Retry schedule

Webhooks are retried exponentially and the current schedule is

  • Immediately
  • 5 seconds
  • 5 minutes
  • 30 minutes
  • 2 hours
  • 5 hours
  • 10 hours

📘

What happens after the 7th trial?

We will no longer try to send another webhook for this particular action. Others will continue processing as normal