Skip to main content
Webhooks let Syncgram Pay push event notifications to your server the moment something happens — a payment succeeds, a payout is delivered, or a refund completes. Instead of polling the API for status changes, you register an endpoint and we deliver a signed HTTP POST request to it. Use webhooks when you need to:
  • Trigger fulfillment after a payment succeeds
  • Update order status in your database
  • Notify customers of payout delivery
  • Reconcile transactions in real time
Syncgram Pay delivers webhooks in both test and live environments. Use your test API key to receive test events before going live.

Setting up a webhook endpoint

1

Create a public HTTPS endpoint

Your endpoint must be publicly reachable over HTTPS and must return an HTTP 200 response to acknowledge delivery. Any non-2xx response is treated as a failure and triggers a retry.
2

Register your URL

Call PUT /api/v1/notifications/webhooks/configuration with your endpoint URL and an optional secret for signature verification.
curl -X PUT https://api.syncgrampay.com/api/v1/notifications/webhooks/configuration \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "webhook_url": "https://yourapp.com/webhooks/syncgram",
    "webhook_secret": "your-secret-at-least-8-chars"
  }'
Request body
FieldTypeRequiredDescription
webhook_urlstringYesYour HTTPS endpoint URL. Set to null to disable webhooks.
webhook_secretstringNo8–64 character secret used to sign requests. Strongly recommended.
Response
{
  "success": true,
  "message": "Webhook endpoint updated successfully",
  "webhook_url": "https://yourapp.com/webhooks/syncgram",
  "has_secret": true,
  "is_active": true
}
3

Verify your configuration

Retrieve your current webhook configuration at any time.
curl https://api.syncgrampay.com/api/v1/notifications/webhooks/endpoint \
  -H "Authorization: Bearer YOUR_API_KEY"
{
  "success": true,
  "webhook_url": "https://yourapp.com/webhooks/syncgram",
  "has_secret": true,
  "is_active": true
}
has_secret indicates whether a secret is stored. The secret value itself is never returned.
4

Send a test event

Trigger a test delivery to confirm your endpoint is reachable and handling requests correctly.
curl -X POST https://api.syncgrampay.com/api/v1/notifications/webhooks/test \
  -H "Authorization: Bearer YOUR_API_KEY"
This sends a collection.succeeded event with test data to your configured URL. See the test payload below for the exact shape.

Payload structure

Every webhook is a JSON POST body with the following top-level fields:
FieldTypeDescription
idstringUnique event ID, prefixed with evt_.
typestringEvent type (e.g., collection.succeeded).
created_atstringISO 8601 timestamp of when the event was created.
dataobjectEvent-specific data. Shape varies by event type — see Events.
{
  "id": "evt_3f9a1b2c4d5e6f7a8b9c0d1e",
  "type": "collection.succeeded",
  "created_at": "2024-01-15T10:30:00Z",
  "data": {
    "reference": "order_9182",
    "status": "success",
    "amount": "50.00",
    "currency": "USD",
    "customer": {
      "email": "customer@example.com"
    },
    "completed_at": "2024-01-15T10:30:00Z"
  }
}

Test payload

When you call the test endpoint, your URL receives this payload:
{
  "id": "evt_test_webhook",
  "type": "collection.succeeded",
  "created_at": "2024-01-15T10:30:00Z",
  "data": {
    "reference": "test_payment_123",
    "status": "success",
    "amount": 100.00,
    "currency": "USD",
    "customer": {
      "email": "test@example.com"
    },
    "completed_at": "2024-01-15T10:30:00Z",
    "test": true
  }
}

Webhook security

When you configure a webhook_secret, Syncgram Pay signs every request using HMAC-SHA256. Verifying the signature ensures the request genuinely came from Syncgram Pay and that the payload was not tampered with in transit.

Signature headers

Each webhook request includes two headers:
HeaderDescription
X-Syncgram-TimestampUnix timestamp (seconds) when the request was sent.
X-Syncgram-SignatureHMAC-SHA256 hex digest of the signed message.

How the signature is constructed

The signed message is:
{timestamp}.{raw_request_body}
The signature is HMAC-SHA256(secret, signed_message) encoded as a hex string.

Verifying the signature

Always verify the signature before processing a webhook. Reject requests with invalid or missing signatures.
import hashlib
import hmac
import time
from flask import Flask, request, abort

app = Flask(__name__)
WEBHOOK_SECRET = "your-webhook-secret"

def verify_signature(payload_bytes: bytes, timestamp: str, signature: str) -> bool:
    signed_message = f"{timestamp}.{payload_bytes.decode('utf-8')}"
    expected = hmac.new(
        WEBHOOK_SECRET.encode(),
        signed_message.encode("utf-8"),
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

@app.route("/webhooks/syncgram", methods=["POST"])
def handle_webhook():
    timestamp = request.headers.get("X-Syncgram-Timestamp", "")
    signature = request.headers.get("X-Syncgram-Signature", "")

    if not verify_signature(request.get_data(), timestamp, signature):
        abort(400, "Invalid signature")

    event = request.get_json()
    process_event(event)

    return "", 200

def process_event(event):
    if event["type"] == "collection.succeeded":
        print(f"Payment succeeded: {event['data']['reference']}")
    # handle other event types...
Use a constant-time comparison function (e.g., hmac.compare_digest in Python, crypto.timingSafeEqual in Node.js) when comparing signatures to prevent timing attacks.

Retries

If your endpoint returns a non-2xx status code or is unreachable, Syncgram Pay retries delivery automatically using an exponential backoff schedule:
AttemptDelay after previous failure
21 minute
35 minutes
415 minutes
51 hour
After 5 failed attempts, delivery stops for that event.
Your endpoint must return 200 promptly. Process the webhook asynchronously if your handler takes more than a few seconds — acknowledge receipt first, then do the work.

Disabling webhooks

Set webhook_url to null to disable webhook delivery:
curl -X PUT https://api.syncgrampay.com/api/v1/notifications/webhooks/configuration \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"webhook_url": null}'