Skip to main content

Configure Webhook

Get current config​

GET /api/v2/webhooks/config

Returns 404 if nothing is configured.

Response:

{
"url": "https://yourapp.com/webhooks/4pay",
"secret_set": true,
"event_types": ["card_transaction", "card_state"],
"is_active": true
}

secret_set: true means a signing secret is stored (the value itself is never returned).


Set or update config​

PUT /api/v2/webhooks/config
Content-Type: application/json

Request body​

FieldTypeRequiredDescription
urlstring (URI)YesYour HTTPS endpoint
secretstringNoUsed to compute api-notification-sign (SHA-512). If omitted, the signature header is still sent using the provider's own key.
event_typesstring[]NoSubset to receive. null or omit → all events.
is_activebooleanNoDefault true

Available event types: card_transaction, account_transaction, account_topup, card_state.

curl -s -X PUT "https://api.4pay.cc/api/v2/webhooks/config" \
-H "X-API-Token: YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/incoming",
"secret": "your-secret-string",
"event_types": ["card_transaction", "account_transaction", "account_topup", "card_state"],
"is_active": true
}'

Response (200): same shape as GET config.


Delete config​

DELETE /api/v2/webhooks/config

204 — forwarding stops immediately.


Verifying the signature​

Each POST request we send to your endpoint includes:

X-Webhook-Signature: <hex-encoded HMAC-SHA256>

To verify in Python:

import hmac, hashlib

def verify(secret: str, body: bytes, header_value: str) -> bool:
digest = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(digest, header_value)

To verify in Node.js:

const crypto = require('crypto');

function verify(secret, body, headerValue) {
const digest = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return crypto.timingSafeEqual(Buffer.from(digest), Buffer.from(headerValue));
}
caution

Always use a constant-time comparison (hmac.compare_digest, crypto.timingSafeEqual, etc.) to prevent timing attacks. Reject requests where the signature does not match.