Skip to main content

Receiving webhooks

Your system receives webhooks on an HTTPS endpoint that you register in Merchant Hub. This page covers what the endpoint must support, what the requests look like, how retries work, and how to verify that a request comes from Walley.

Expose an HTTPS endpoint​

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

Endpoint requirements

  • Must accept HTTP POST requests
  • Must accept a JSON request body
  • Must support HTTPS with TLS 1.2 or 1.3

Endpoint recommendations

  • Require basic authentication with a username and password
  • Support HTTP2
  • Validate the Walley-Signature header with the HMAC key

Respond to webhooks​

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

Structure​

The request body is formatted as JSON. Type holds the name of the event and Timestamp is when the event occurred. Payload is different for each event.

{
"Type": string,
"Timestamp": date,
"Payload": object
}

Retries​

Webhooks are delivered at least once, so your endpoint must support being called multiple times with the same event without side effects. We retry delivery with increasing backoff time until we receive an HTTP status code in the 2xx series.

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 53 hours), we will handle this manually and contact you before retrying again.

Headers​

These headers are included in every webhook request:

KeyDescription
User-AgentStandard HTTP header. The value will 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, provide this value in the support ticket.
Walley-TimestampUNIX timestamp when this event occurred. Used for HMAC validation, see Verifying the request with HMAC.
Walley-SignatureComputed signature from Walley. Used for HMAC validation, see Verifying the request with HMAC.
Walley-LiveTrue or False. Used to know if the request to the webhook is made from Walley's production or a test triggered from the Merchant Hub. True indicates production data.

Verifying the request with HMAC​

When you set up a webhook, you'll get an HMAC key for it. You can use this key to verify that the requests you receive originate from Walley, using the following method:

  1. Retrieve 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. Example: v0;{Timestamp};{Body}
  3. Hash the string described above with the HMAC SHA256 implementation of your system's 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);

}