Appibase uses webhooks to notify your application about payment events. Webhooks are delivered as HTTPS POST requests to your endpoint and include a signed event JSON payload that includes a payment resource object.
You will use the webhook secret to verify signatures on incoming requests.
APPIBASE_WEBHOOK_SECRET).Each webhook request includes a single event object. The event wraps a payment resource object.
{
"id": "evt_QzHr5ixaH1SLnl7kvMitrdFm",
"type": "event",
"event_type": "payment.succeeded",
"data": {
"id": "pay_Pl7TBgM1d3tiiXf2o6rnfvRO",
"type": "payment",
"attributes": {
"order_id": 5286286641,
"payment_ref": "SVRN23uYmcdDSUAAAGLT",
"client_ref": "123456",
"gateway": "satim",
"currency": "dzd",
"amount_cents": 381000,
"amount_received_cents": 0,
"email": "name@gmail.com",
"status": "succeeded",
"paid": true,
"metadata": {}
}
}
}
Each webhook request includes the following headers:
Content-Type: application/json
User-Agent: Appibase/1.0
Appibase-Event-Id: evt_...
Appibase-Event-Type: payment.failed
Appibase-Webhook-Id: we_...
Appibase-Signature: t=TIMESTAMP,v1=HEX_SIGNATURE
The signature header contains two key/value pairs:
t: UNIX timestamp (seconds)v1: HMAC SHA-256 signatureThe signature is computed as:
signed_payload = "#{timestamp}.#{raw_body}"
signature = HMAC_SHA256(secret, signed_payload)
Pseudo-code to verify the signature:
parts = parse_header("t=...,v1=...")
ts = parts["t"]
v1 = parts["v1"]
expected = HMAC_SHA256(secret, "#{ts}.#{raw_body}")
secure_compare(expected, v1)
recommended: reject if |now - ts| > tolerance
Always verify the signature using the raw request body and your webhook secret. A tolerance window of 300 seconds is recommended to reduce replay risk.
Return 200 OK to acknowledge receipt. If your endpoint returns a 4xx or 5xx response, Appibase will retry delivery up to 15 times. After the final failure, the webhook endpoint is disabled and must be re-enabled in the dashboard.
id.Appibase-Event-Id and Appibase-Webhook-Id for troubleshooting.