← Back to home
developer
Webhook events
PayF posts a webhook each time a payment moves through its lifecycle. Below: every event type, when it fires, and a sample payload you can test against.
Verify signatures
Every webhook carries an X-PayF-Signature header. Always verify it before processing the body — bare HMAC isn't enough, the helper enforces a 5-minute freshness window to defeat replay.
Node / TypeScript
import { verifyWebhook } from "@payf/sdk";
app.post("/webhook", (req, res) => {
const raw = req.rawBody; // raw bytes, NOT req.body
const sig = req.header("x-payf-signature");
if (!verifyWebhook(raw, sig, process.env.PAYF_WEBHOOK_SECRET!)) {
return res.status(401).send();
}
const event = JSON.parse(raw.toString());
// ... handle event.event_type ...
});Python
import payf
from flask import request
@app.post("/webhook")
def webhook():
body = request.get_data() # raw bytes
sig = request.headers["X-PayF-Signature"]
if not payf.verify_webhook_strict(SECRET, body, sig):
return "", 401
event = request.get_json()
# ... handle event["event_type"] ...
return "ok"Go
import payf "github.com/payf-ai/payf-go"
http.HandleFunc("/webhook", func(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
if !payf.VerifyWebhookStrict(
secret, body,
r.Header.Get("X-PayF-Signature"),
time.Now(), payf.DefaultWebhookTolerance,
) {
http.Error(w, "bad signature", 401)
return
}
// ... json.Unmarshal(body, &event) ...
})