Webhooks
Receive real-time notifications when events occur in your ledger.
Overview
Webhooks let you build integrations that react to events in Soledgic. When an event occurs (like a sale or payout), we send an HTTP POST request to your configured endpoint.
Configure webhooks in your Settings → Webhooks page.
Event Types
Subscribe to specific events or use * to receive all events.
| Event | Description |
|---|---|
sale.created | A new sale was recorded |
sale.refunded | A sale was refunded |
payout.processed | A payout was initiated |
payout.executed | A payout was completed |
payout.failed | A payout failed |
creator.created | A new creator was added |
period.closed | An accounting period was closed |
statement.generated | A creator statement was generated |
Webhook Payload
Every webhook POST includes these headers and a JSON body:
Headers
| Header | Description |
|---|---|
Content-Type | application/json |
X-Soledgic-Signature | HMAC-SHA256 signature |
X-Soledgic-Event | Event type (e.g., sale.created) |
Example Payload
{
"id": "evt_abc123",
"type": "sale.created",
"created_at": "2025-12-18T10:30:00Z",
"livemode": true,
"data": {
"transaction_id": "txn_xyz789",
"reference_id": "order_123",
"creator_id": "creator_456",
"amount": 2999,
"currency": "USD",
"breakdown": {
"total": 29.99,
"creator_amount": 23.99,
"platform_amount": 6.00
}
}
}Verifying Signatures
Always verify webhook signatures to ensure requests are from Soledgic. The signature is computed using HMAC-SHA256 with your webhook secret.
Important: Your webhook secret is shown only once when you create the endpoint. Store it securely.
Node.js
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your webhook handler
app.post('/webhooks/soledgic', (req, res) => {
const signature = req.headers['x-soledgic-signature'];
if (!verifyWebhookSignature(req.body, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process the event
const event = req.body;
console.log('Received event:', event.type);
res.status(200).send('OK');
});Python
import hmac
import hashlib
import json
def verify_webhook_signature(payload, signature, secret):
expected = 'sha256=' + hmac.new(
secret.encode(),
json.dumps(payload).encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)
# In your webhook handler (Flask example)
@app.route('/webhooks/soledgic', methods=['POST'])
def webhook():
signature = request.headers.get('X-Soledgic-Signature')
if not verify_webhook_signature(request.json, signature, WEBHOOK_SECRET):
return 'Invalid signature', 401
event = request.json
print(f"Received event: {event['type']}")
return 'OK', 200Retry Policy
If your endpoint returns a non-2xx status code, we'll retry the webhook:
- Up to 5 retry attempts
- Exponential backoff: 1 min, 5 min, 30 min, 2 hours, 24 hours
- After 5 failures, the delivery is marked as failed
You can view delivery attempts in the Webhooks settings page.
Best Practices
Return 200 quickly
Acknowledge receipt immediately, then process asynchronously
Handle duplicates
Use the event ID to deduplicate in case of retries
Verify signatures
Always validate the X-Soledgic-Signature header
Use HTTPS
Webhook endpoints must use HTTPS for security
Testing Webhooks
Use the "Test" button in your webhook settings to send a test event. This sends a sample payload to verify your endpoint is configured correctly.
For local development, use a tool like ngrok to expose your local server to the internet.