Webhooks provide a way to receive notifications for your transactions in real-time. While your transaction is being processed, its status progresses until it is completed. This makes it very important to get the final status for that transaction, and that's where webhooks are very beneficial.

Put simply, a webhook URL is an endpoint on your server that can receive API requests from Shutterscore’s server. Note that the request is going to be an HTTP POST request.

Setting your Webhook URL

You can specify your webhook URL in Webhooks and callbacks section on the the API tab of the Settings page of your dashboard. Make sure that the webhook URL is unauthenticated and publicly available.


The request to the webhook URL comes with a payload, and this payload contains the details of the transaction for which you are being notified.

Webhook Request Payload

FieldData TypeDescription
eventStringThe type of event e.g deposit.pending, deposit.success, deposit.failed, deposit.refunded, swap.pending, swap.success, swap.failed, withdrawal.pending, withdrawal.success, withdrawal.failed
dataObjectThe object containing transaction details: amount, fee, currency, status, reference, e.t.c
data.amountNumberThe amount sent by the merchant for the transaction. See Fee and Fee Bearers
data.amount_chargedNumberTotal amount debited from the merchant balance for the transaction. It usually will be the amount + fees for the transaction. See Fee and Fee Bearers
data.amount_settledNumberActual amount sent to the beneficiary in the case of a withdrawal or amount paid to the merchant in the case of a swap or deposit. See Fee and Fee Bearers
data.feeNumberTransaction fee
data.fee_bearerNumberThe bearer of the fees for the transaction. Fee bearer can either be Merchant or Beneficiary.
data.currencyStringTransaction settlement currency
data.from_amountNumber or NullFrom amount indicates the source or originating amount of the transaction
data.from_currencyString or NullFrom currency indicates the source or originating currency of the transaction
data.to_amountNumber or NullTo amount indicates the destination amount of the transaction
data.to_currencyString or NullTo currency indicates the destination currency of the transaction
data.statusStringTransaction status. This can be pending, success or failed.
data.referenceStringTransaction reference. This reference can be used to query the transaction
data.merchant_referenceStringTransaction reference provided by the merchant
data.created_atStringTransaction timestamp
signatureStringHMAC SHA256 signature of the request payload signed using your secret key. You should compare your hash to this value. If they are not the same, then the webhook request is not from us

Verifying Webhooks Request

It is important to verify that requests are coming from Shutterscore to avoid delivering value based on a counterfeit request. To verify our requests, you need to validate the signature assigned to the request.
Valid requests are sent with a signature property in the body of the request. The signature value is essentially an HMAC SHA256 signature of the request payload signed using your secret key.

const crypto = require(“crypto”);
const secretKey = SECK_LIVE_******
 
router.post(‘/your_webhook_url’, (req, res, next) => {
const hash = crypto.createHmac('sha256', secretKey).update(JSON.stringify(req.body.data)).digest('hex');
 
   If (hash === req.body.signature) {
     	// Continue with the request functionality
   } else {
    	 // Don’t do anything, the request is not from us.
   }
});
$secretKey = 'YOUR SECRET KEY';

$webhook = file_get_contents("php://input");

$webhookArray = json_decode($webhook, true); // converts webhook which is a JSON string to Array

$webhookJSON = json_encode($webhookArray['data']); //converts webhookArray Data to JSON string

$hash = hash_hmac('sha256', $webhookJSON, $secretKey);

if ($hash == $webhookArray['signature']) {
    // Continue with the request functionality
}else{
    // Don’t do anything, the request is not from us.
}

Responding to Webhooks Request

It is important to respond to the requests with a 200 status code to acknowledge that you have received the requests. Shutterscore does not pay attention to any request parameters apart from the request status code.
Please note that if any other response code is received, or there’s a timeout while sending the request, we retry the request periodically within a couple of hours after which retries stop.

Best Practices

It is recommended to do the following when receiving webhook notifications from us:

  • Keep track of all notifications received: It’s important to keep track of all notifications you’ve received. When a new notification is received proceed to check that this has not been processed before giving value. A retry of already processed notifications can happen if we do not get a 200 HTTP Status code from your notification URL, or if there was a request time out.
  • Acknowledge receipt of notifications with a 200 HTTP status code: It’s recommended you immediately acknowledge receipt of the notification by returning a 200 HTTP Status code before proceeding to perform other logics, failure to do so might result in a timeout which would trigger a retry of such notification.