Webhooks
StarPay POSTs a signed JSON payload to your endpoint URLs when events occur. Register endpoints (each gets its own signing secret, shown once) and subscribe to the events you care about.
Payload
{
"id": "evt_123",
"event": "charge.success",
"data": { "id": "ch_abc", "amount": 250000, "currency": "GHS", "status": "success" }
}
Events include charge.success, charge.failed, transfer.success,
transfer.failed, transfer.reversed, deposit.confirmed, payout.success,
payout.failed, and trade.settled (Phase 2).
Verify the signature
Each request carries X-Starpay-Timestamp and X-Starpay-Signature =
HMAC_SHA256(endpoint_secret, "{timestamp}.{sha256(raw_body)}"). Compute the
hash over the raw body, before parsing, and reject timestamps older than
300 seconds.
Python
import hashlib, hmac, time
def verify(secret, timestamp, raw_body: bytes, signature, tolerance=300) -> bool:
if abs(time.time() - int(timestamp)) > tolerance:
return False
body_hash = hashlib.sha256(raw_body).hexdigest()
expected = hmac.new(secret.encode(), f"{timestamp}.{body_hash}".encode(), hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature)
Node.js
const crypto = require("crypto");
function verify(secret, timestamp, rawBody, signature, tolerance = 300) {
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > tolerance) return false;
const bodyHash = crypto.createHash("sha256").update(rawBody).digest("hex");
const expected = crypto.createHmac("sha256", secret)
.update(`${timestamp}.${bodyHash}`).digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}
PHP
function starpay_verify($secret, $timestamp, $rawBody, $signature, $tolerance = 300): bool {
if (abs(time() - (int) $timestamp) > $tolerance) return false;
$bodyHash = hash('sha256', $rawBody);
$expected = hash_hmac('sha256', "{$timestamp}.{$bodyHash}", $secret);
return hash_equals($expected, $signature);
}
Retries
Respond 2xx to acknowledge. Failures are retried up to 5 times with backoff —
1m, 5m, 30m, 2h, 12h — then dead-lettered and surfaced in your dashboard,
where you can inspect and redeliver them.