Webhooks
Receive real-time notifications about events in your SoshiaConnect account.
Overview
Webhooks allow SoshiaConnect to send HTTP POST requests to your server when specific events occur, enabling real-time integrations without polling.
Supported Events
Payment Events
payment.succeeded- Payment processed successfullypayment.failed- Payment processing failedpayment.refunded- Payment refunded
Subscription Events
subscription.created- New subscription activatedsubscription.renewed- Subscription renewedsubscription.expired- Subscription expiredsubscription.cancelled- Subscription cancelled
Account Events
account.updated- Profile information changedaccount.verified- Email verification completed
Setting Up Webhooks
1. Create Endpoint
Create an HTTPS endpoint on your server to receive webhook events:
// Express.js example
app.post('/webhooks/soshiaconnect', (req, res) => {
const event = req.body;
switch (event.type) {
case 'payment.succeeded':
handlePaymentSuccess(event.data);
break;
case 'subscription.expired':
handleSubscriptionExpired(event.data);
break;
// Handle other events
}
res.json({ received: true });
});
2. Register Webhook URL
Currently, webhooks are configured through Stripe. The endpoint /stripe/webhook handles Stripe webhook events.
Webhook Payload
Structure:
{
"id": "evt_1234567890",
"type": "payment.succeeded",
"created": 1609459200,
"data": {
"object": {
"id": "pi_1234567890",
"amount": 9999,
"currency": "usd",
"status": "succeeded",
"metadata": {
"user_id": "123",
"subscription_id": "456"
}
}
}
}
Security
Verify Webhook Signatures
Always verify webhook signatures to ensure requests are from SoshiaConnect:
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const hmac = crypto.createHmac('sha256', secret);
const digest = hmac.update(payload).digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(digest)
);
}
app.post('/webhooks/soshiaconnect', (req, res) => {
const signature = req.headers['x-soshia-signature'];
const payload = JSON.stringify(req.body);
if (!verifyWebhook(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process webhook
res.json({ received: true });
});
Best Practices
- Respond Quickly: Return 200 status immediately, process in background
- Handle Retries: Implement idempotency using event IDs
- Log Events: Keep audit trail of received webhooks
- Use HTTPS: Webhooks only delivered to HTTPS endpoints
- Verify Signatures: Always validate webhook authenticity
Testing
Test your webhook endpoint using tools like:
- Postman: Send test requests
- ngrok: Expose local server for testing
- webhook.site: Inspect incoming webhooks
Troubleshooting
Webhooks Not Received:
- Verify endpoint is publicly accessible
- Check firewall rules
- Ensure HTTPS is enabled
- Verify URL is correct
Authentication Failures:
- Verify webhook secret
- Check signature validation logic
- Ensure payload is not modified