Validating Webhook Notification
To validate that the webhook notifications are coming from Wello, you will need another public key from us to check.
We will send and sign Webhook events to your endpoint and include the signature in the headers to you. We will have the same list of headers as those required for REST API requests, and use the same signature method to set the value for x-api-signature
(Check REST API authentication)
We will convert the data from Webhooks (which is the order details) into the key-value pairs along with the headers except x-api-signature, and join the elements by using “&”. Then we will use the secret key generated on our side to sign the payload and put the value in the x-api-signature.
The public key we provide to you by using SHA256withRSA can be used to decrypt the value of x-api-signature
, and check if the Webhook data is matched with values decrypted. The public key value will also be passed in the x-api-clientid
header. However, we would recommend you to use the one we told you instead of header value for better security, and we won’t frequently change the public key for webhook message validation.
Let’s use order success updates as an example:
{
data:
{
"welloPreOrderId": "4220317678178361088",
"merchantOrderId": "1221212121212",
"side": "BUY",
"cryptoCurrency": "ETH",
"fiatCurrency": "EUR",
"requestedCurrency": "EUR",
"requestedAmount": "1000",
"orderStatus": "SUCCESS",
"quotePrice": "4.40505409",
"fiatAmount": "1000",
"cryptoAmount": "1.1393",
"fees": {
"fiatFee": "10",
"tradeFee": "99",
"merchantFee": 0,
"networkFee": "0",
"total": "109"
},
"payment": {
"method": "SEPA",
"iban": ""
},
"crypto": {
"network": "ETH",
"address": "0x71C7656EC7ab88b098defB751B7401B5f6d8976F",
"txId": null
},
"failCode": "",
"failReason": "",
"createdAt": "1729508936145",
"updatedAt": "1722411925095"
}
}
Where you can retrieve the headers information from POST method as below:
{
method: “POST”,
headers:
{
x-api-clientid: <Wello Public Key to validate x-api-signature value>
x-api-nonce: <32-character random and unique nonce string>
x-api-timestamp: <timestamp string sent>
x-api-signature: <signed payload (data + x-api-clientid + x-api-nonce + x-api-timestamp)>
}
}
You can use the following sample code for the signature verification
Signature signature = Signature.getInstance("SHA256withRSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey));
PublicKey key = KeyFactory.getInstance("RSA").generatePublic(keySpec);
signature.initVerify(key);
signature.update(body.getBytes(StandardCharsets.UTF_8));
boolean verified = signature.verify(Base64.getDecoder().decode(signatureStr));
By decrypting the x-api-signature value and comparing it with the webhook’s data and other headers’ values, you can check if it is coming from Wello.
Updated 4 months ago