API explorerPay APIsData APIs

Theme switcher

Webhook signing and callbacks

Webhook requests (payment status, consent status, job status) are signed so you can verify they come from FinqLink. You can also restrict incoming requests to our callback IPs.

Headers

Header Description
x-signature JWS compact string (header.payload.signature, Base64URL). The signed payload is the raw JSON body of the request.
x-signature-kid Key ID of the key used to sign; use it to select the key from the JWKS for verification.

How to verify

  1. Fetch the public keys: GET {base_url}/.well-known/jwks.json (use your environment base URL). Response shape: {"keys": [ { "kty", "kid", "alg", "use", "n", "e" }, ... ]}.
  2. From the webhook request: read the x-signature-kid and x-signature headers and the raw request body (UTF-8 JSON).
  3. Find the key in keys with matching kid. Verify the JWS in x-signature: the JWS payload must equal the raw body, and the signature must verify with that key (RS256 or ES256 per key's alg). Reject if kid is unknown, signature is invalid, or payload does not match body.

Bash verification example (RS256)

This example assumes the request body is in body.json, and X_SIGNATURE and X_SIGNATURE_KID are set from the webhook headers. It fetches JWKS, extracts the key by kid, and verifies the JWS with OpenSSL.

#!/bin/bash
BASE_URL="https://your-env.finqware.com"   # test or prod
JWKS_URL="$BASE_URL/.well-known/jwks.json"

# Fetch JWKS and get the key for the given kid (requires jq)
KEY_JSON=$(curl -s "$JWKS_URL" | jq --arg kid "$X_SIGNATURE_KID" '.keys[] | select(.kid == $kid)')
if [ -z "$KEY_JSON" ] || [ "$KEY_JSON" = "null" ]; then
  echo "Unknown kid: $X_SIGNATURE_KID"
  exit 1
fi

# JWS compact: header.payload.signature (Base64URL)
IFS='.' read -r HEADER_B64 PAYLOAD_B64 SIG_B64 <<< "$X_SIGNATURE"
SIGNED_DATA="$HEADER_B64.$PAYLOAD_B64"
echo -n "$SIGNED_DATA" | sed 's/-/+/g; s/_/\//g' | base64 -d 2>/dev/null > /dev/null || true
echo -n "$SIGNED_DATA" > signed_data.txt

# Decode signature (Base64URL to binary)
echo "$SIG_B64" | sed 's/-/+/g; s/_/\//g' | base64 -d > sig.bin

# Verify: use a JWT/JWS library or convert JWK to PEM and run:
# openssl dgst -sha256 -verify pubkey.pem -signature sig.bin signed_data.txt
# In production, use a proper JWS library (e.g. in your app) to verify with the JWK.

For production we recommend verifying in your application using a JWS/JWT library (e.g. that supports JWKS and RS256/ES256) rather than shell scripts.

Callbacks from fixed IPs

You can restrict your webhook endpoint to accept requests only from FinqLink's outbound IPs:

Environment Outbound IP
Test 34.89.170.122
Production 34.159.239.125

Use firewall or load-balancer rules to allow only these source IPs for the path that receives webhooks.

Was this section helpful?

What made this section unhelpful for you?

On this page
  • Webhook signing and callbacks
View as Markdown

Ask an AI

Open in ChatGPTOpen in ClaudeOpen in Perplexity

Code with AI

Open in Copilot