Skip to content

Handling Webhooks

Learn how to receive and process webhook events from Sesamy.

Overview

Sesamy sends webhook notifications to your configured endpoints when specific events occur. Webhooks are designed to be lightweight, containing only essential identifiers. Your application should use these identifiers to fetch the full details from the Sesamy API.

Webhook Request Format

Webhooks are sent as HTTP POST requests with the following structure:

json
{
  "eventType": "userVendor.1#new",
  "vendorId": "vendor_123",
  "userId": "user_456",
  "contractId": "contract_789",
  "entitlementId": "entitlement_012",
  "checkoutId": "checkout_345",
  "occured_at": "2025-11-10T12:00:00Z"
}

Payload Fields

FieldTypeDescription
eventTypestringThe type of event that occurred (see Event Types below)
vendorIdstringThe vendor identifier
userIdstringThe user identifier
occured_atstringISO 8601 timestamp of when the event occurred
contractIdstring(Optional) Contract identifier, if applicable
entitlementIdstring(Optional) Entitlement identifier, if applicable
checkoutIdstring(Optional) Checkout identifier, if applicable

Event Types

The following webhook events are available:

Event TypeDescription
userVendor.1#newA new user-vendor relationship was created
userVendor.1#updateA user-vendor relationship was updated
contract.1#purchasedA contract was purchased
contract.1#updateA contract was updated
contract#cancelRequestA cancellation request was made for a contract
checkout.1#confirmA checkout was confirmed

Setting Up Webhook Endpoints

Your webhook endpoint should:

  1. Accept POST requests
  2. Respond quickly (within a few seconds)
  3. Return a 2xx status code to acknowledge receipt
  4. Process the webhook asynchronously if needed

Example Endpoint

javascript
app.post('/webhooks/sesamy', async (req, res) => {
  const { eventType, vendorId, userId, contractId, occured_at } = req.body;

  // Acknowledge receipt immediately
  res.status(200).send('OK');

  // Process asynchronously
  processWebhook({ eventType, vendorId, userId, contractId, occured_at });
});

Fetching Full Event Data

Webhooks contain minimal data to reduce payload size. Use the provided identifiers to fetch complete information from the Sesamy API:

javascript
async function processWebhook({ eventType, vendorId, userId, contractId, checkoutId }) {
  switch (eventType) {
    case 'contract.1#purchased':
    case 'contract.1#update':
      // Fetch contract details
      const contract = await sesamyClient.getContract(contractId);
      // Process contract data
      break;

    case 'userVendor.1#new':
    case 'userVendor.1#update':
      // Fetch user-vendor relationship
      const userVendor = await sesamyClient.getUserVendor(vendorId, userId);
      // Process user data
      break;

    case 'checkout.1#confirm':
      // Fetch checkout details
      const checkout = await sesamyClient.getCheckout(checkoutId);
      // Process checkout data
      break;
  }
}

Best Practices

1. Validate Webhook Authenticity

Always verify that webhooks are coming from Sesamy. Check the request headers and implement signature verification if available.

2. Handle Idempotency

Webhooks may be delivered more than once. Ensure your processing logic is idempotent by tracking processed event IDs.

javascript
const processedEvents = new Set();

async function processWebhook(payload) {
  const eventId = `${payload.eventType}-${payload.occured_at}-${payload.userId}`;

  if (processedEvents.has(eventId)) {
    return; // Already processed
  }

  // Process the webhook
  // ...

  processedEvents.add(eventId);
}

3. Implement Retry Logic

If fetching data from the Sesamy API fails, implement exponential backoff retry logic:

javascript
async function fetchWithRetry(apiCall, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await apiCall();
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await new Promise((resolve) => setTimeout(resolve, Math.pow(2, i) * 1000));
    }
  }
}

4. Log All Webhooks

Keep a log of all received webhooks for debugging and auditing:

javascript
app.post('/webhooks/sesamy', async (req, res) => {
  // Log the webhook
  logger.info('Webhook received', {
    eventType: req.body.eventType,
    timestamp: req.body.occured_at,
    payload: req.body,
  });

  res.status(200).send('OK');
  processWebhook(req.body);
});

Testing Webhooks Locally

To test webhooks during development:

  1. Use a tool like ngrok to expose your local endpoint
  2. Configure the ngrok URL in your Sesamy vendor settings
  3. Trigger events in your test environment
  4. Monitor the webhook delivery in your local application
bash
# Start ngrok
ngrok http 3000

# Use the ngrok URL as your webhook endpoint
# https://abc123.ngrok.io/webhooks/sesamy

Troubleshooting

Webhooks Not Received

  • Verify your endpoint is publicly accessible
  • Check that your server responds with a 2xx status code
  • Ensure your firewall allows incoming connections
  • Review webhook logs in the Sesamy dashboard (if available)

Duplicate Webhooks

  • Implement idempotency checks using event identifiers
  • Store processed event IDs to prevent reprocessing

Missing Data

  • Always fetch complete data from the API using the provided identifiers
  • Don't rely solely on webhook payload for critical data

Released under the MIT License.