SANDBOX ENVIRONMENT — payments on this deployment are simulated. No real money is moved.
Developers

Webhooks

Receive signed, real-time notifications when payments, refunds and payouts change.

Event types

  • payment.succeeded
  • payment.failed
  • payment.pending
  • refund.succeeded
  • refund.failed
  • payout.paid
  • payout.rejected
  • order.paid
  • invoice.paid

Delivery

We POST JSON to your endpoint with headers FlyPay-Signature and FlyPay-Event-Id. Respond with any 2xx within 10 seconds. Failed deliveries are retried after 1 min, 5 min, 30 min, 2 h and 6 h (6 attempts total). You can re-send any delivery from the dashboard.

Verifying signatures

The header looks like t=1760371200,v1=5f2c…. Compute HMAC-SHA256 of "{t}.{raw_body}" with your endpoint secret (whsec_…), compare in constant time, and reject timestamps older than 5 minutes.

Python

import hashlib, hmac, re, time

def verify_flypay_signature(raw_body: bytes, header: str, secret: str, tolerance: int = 300) -> bool:
    m = re.fullmatch(r"t=(\d+),v1=([a-f0-9]{64})", header or "")
    if not m or abs(time.time() - int(m.group(1))) > tolerance:
        return False
    signed = m.group(1).encode() + b"." + raw_body
    expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, m.group(2))

Node.js

import { createHmac, timingSafeEqual } from 'node:crypto';

export function verifyFlyPaySignature(rawBody, header, secret, toleranceSec = 300) {
  const m = /^t=(\d+),v1=([a-f0-9]{64})$/.exec(header ?? '');
  if (!m) return false;
  const t = Number(m[1]);
  if (Math.abs(Date.now() / 1000 - t) > toleranceSec) return false;
  const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
  return timingSafeEqual(Buffer.from(expected), Buffer.from(m[2]));
}

Idempotent processing

Store each processed FlyPay-Event-Id and ignore duplicates — retries and network issues can deliver the same event more than once.

Example payload

{
  "id": "evt_…",
  "type": "payment.succeeded",
  "created": "2026-10-13T10:24:00.000Z",
  "data": {
    "id": "txn_…", "reference": "FPN-261013-AB12CD34", "status": "succeeded", "mode": "sandbox",
    "amount_minor": 12000000, "currency": "TZS", "fee_minor": 300000, "net_minor": 11700000,
    "method": "sandbox_mpesa", "provider_reference": "SBX-…"
  }
}