Skip to main content

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 successfully
  • payment.failed - Payment processing failed
  • payment.refunded - Payment refunded

Subscription Events

  • subscription.created - New subscription activated
  • subscription.renewed - Subscription renewed
  • subscription.expired - Subscription expired
  • subscription.cancelled - Subscription cancelled

Account Events

  • account.updated - Profile information changed
  • account.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

  1. Respond Quickly: Return 200 status immediately, process in background
  2. Handle Retries: Implement idempotency using event IDs
  3. Log Events: Keep audit trail of received webhooks
  4. Use HTTPS: Webhooks only delivered to HTTPS endpoints
  5. 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