Skip to main content

Webhooks

With webhooks your system can subscribe to updates from Walley. By registrating one or many URLs at Walley, we can call it when we need to update you with new information.

Use Webhooks​

Webhooks is in preview

Currently the webhook functionality is in preview mode and may change before general availability

Step 1. Expose an HTTPS endpoint​

To receive webhooks you are required to have an HTTPS endpoint.

Endpoint requirements

  • Must listen to HTTP POST method
  • Must be able to receive JSON body
  • Must support HTTPS with TSL 1.2 or 1.3

Endpoint recommendations

  • Basic authentication with username or password
  • Support for HTTP2
  • Validating the Walley-Signature header with HMAC key

Step 2. Accept webhooks​

When you receive a webhook request you are required to respond with a http status code in the 2xx series.

Step 3. Configure webhooks in Walley Merchant Hub​

To view webhook management in Merchant Hub, click here: Merchant Hub - Webhooks

Step 4. Test and enable for Production​

Not available right now.

Structure​

You will receive a request body formated in JSON which will contain a type property with the name of the event, the timestamp when the event occured and a payload that can be diffrent for each event.

{
"type": string,
"timestamp": date,
"payload": object
}

Events​

Events are grouped into these categories:

Retries​

Please note the webhooks will attempt to notify the configured webhook URI multiple times with increasing backoff time until a HTTP status code 2XX is received in the response. Our retry mechanism is built in a way that we guarantee at-least-once-delivery and the webhook URI endpoint must therefore support being called multiple times without side effects.

The webhook is sent instantly and if the endpoint does not answer with a 2XX status a retry will be made after:

  • 5 seconds
  • 10 seconds
  • 3 minutes
  • 1 hour
  • 4 hours
  • 8 hours
  • 16 hours
  • 24 hours

If the webhook endpoint did not answer with a 2XX status after the last retry (after about 80 hours), we will handle this manually and contact you before retrying again.

Headers​

These headers will be included in the webhook requests

KeyDescription
User-AgentStandard http header the value would be something like, Walleybot 0.1 (+https://dev.walleypay.com)
Walley-CorrelationIdThe id of the request that triggered the webhook request, if you have issues with any request please provide this value in the support ticket.
Walley-TimestampUNIX timestamp when this event occured, this is used for HMAC validation see below.
Walley-SignatureComputed signature from Walley, this is used for HMAC validation see below.
Walley-LiveTrue or False, this is used to know if the request to the webhook is made from Walleys production or a test triggered from the MerchantHub. True indicates production data.

Verifying the request with HMAC​

When you set up a webhook, you'll get a HMAC key for it. You can use this key to check that requests you retrieve originates from Walley by using the follow method:

  1. Retrive the request header Walley-Timestamp
  2. Concatenate the version number, the timestamp, and the body of the request to form a basestring. Use a semicolon as the delimiter between the three elements. The version number right now is always v0. Exampel v0:{Timestamp};{Body}
  3. Hash the string described above with the HMAC SHA256 implementation of you systems platform, using the HMAC secret for the webhook.
  4. Compare the computed signature with the request header Walley-Signature

Examples​

static string ComputeHash(string secret, string timestamp, string payload)
{
byte[] bytes = Encoding.UTF8.GetBytes(secret);
HMACSHA256 hmac = new HMACSHA256(bytes);
bytes = Encoding.UTF8.GetBytes($"v0;{timestamp};{payload}");

return Convert.ToHexString(hmac.ComputeHash(bytes)).ToLower();
}

static bool IsHashValid(string secret, string timestamp, string payload, string verify)
{
string hash = ComputeHash(secret, timestamp, payload);
ReadOnlySpan<byte> hashBytes = Convert.FromHexString(hash);
ReadOnlySpan<byte> verifyBytes = Convert.FromHexString(verify);

return CryptographicOperations.FixedTimeEquals(hashBytes, verifyBytes);
}