Webhooks
Webhooks let you receive real-time HTTP notifications when events occur in your GoConverso account. Use them to sync data with external systems, trigger automations, or build custom integrations.
GoConverso webhooks are powered by Stripe for payment events and Supabase Edge Functions for platform events. Each type has a different configuration flow.
How webhooks work
When an event occurs (such as a successful payment or a new booking), GoConverso sends an HTTP POST request to your configured endpoint URL with a JSON payload describing the event.
GoConverso Event --> HTTP POST --> Your Endpoint
(JSON payload)Your endpoint should:
- Accept
POSTrequests - Return a
2xxstatus code within 30 seconds - Verify the webhook signature to confirm authenticity
- Process the event asynchronously if it requires heavy computation
Stripe webhooks
Stripe webhooks handle all payment-related events. GoConverso processes these through a dedicated edge function (stripe-webhook) that validates signatures, updates subscription status, and records transactions.
Supported Stripe events
| Event | Description |
|---|---|
checkout.session.completed | A customer completed a Stripe Checkout session |
customer.subscription.created | A new subscription was created |
customer.subscription.updated | A subscription was modified (plan change, renewal) |
customer.subscription.deleted | A subscription was cancelled |
invoice.payment_succeeded | A recurring payment was successful |
invoice.payment_failed | A recurring payment failed |
payment_intent.succeeded | A one-time payment was completed |
Configuring Stripe webhooks
Get your webhook endpoint URL
Your GoConverso Stripe webhook endpoint is:
https://<project-id>.supabase.co/functions/v1/stripe-webhookAdd the endpoint in Stripe Dashboard
- Go to the Stripe Dashboard
- Click Add endpoint
- Enter your webhook URL
- Select the events listed above
- Click Add endpoint
Copy the signing secret
After creating the endpoint, Stripe provides a signing secret (whsec_...). Store this as an environment variable:
STRIPE_WEBHOOK_SECRET=whsec_1234567890abcdefVerify the configuration
Send a test event from the Stripe Dashboard to confirm your endpoint receives and processes it correctly.
The stripe-webhook edge function must be deployed with the --no-verify-jwt flag, since Stripe sends requests without a Supabase JWT. The function verifies authenticity using the Stripe webhook signature instead.
Stripe webhook payload
Here is an example payload for a checkout.session.completed event:
{
"id": "evt_1OqY4z2eZvKYlo2C8G9vU1qA",
"object": "event",
"type": "checkout.session.completed",
"data": {
"object": {
"id": "cs_test_a1b2c3d4",
"object": "checkout.session",
"customer": "cus_Px7k9abcde",
"customer_email": "user@example.com",
"mode": "subscription",
"payment_status": "paid",
"status": "complete",
"subscription": "sub_1OqY4z2eZvKYlo2C",
"metadata": {
"user_id": "550e8400-e29b-41d4-a716-446655440000",
"plan": "plus"
},
"amount_total": 4900,
"currency": "usd"
}
},
"created": 1706540400
}Signature verification
GoConverso verifies every incoming Stripe webhook using the stripe-signature header. This prevents spoofed requests from reaching your processing logic.
import Stripe from 'stripe'
const stripe = new Stripe(Deno.env.get('STRIPE_SECRET_KEY'))
const signature = request.headers.get('stripe-signature')
const body = await request.text()
const event = stripe.webhooks.constructEvent(
body,
signature,
Deno.env.get('STRIPE_WEBHOOK_SECRET')
)
// event is now verified and safe to processBooking notification webhooks
GoConverso can send webhook notifications when booking events occur. These are delivered through Supabase Edge Functions.
Supported booking events
| Event | Trigger |
|---|---|
booking.created | A new appointment is booked by a client |
booking.confirmed | The professional confirms a pending booking |
booking.cancelled | A booking is cancelled by either party |
booking.rescheduled | A booking date or time is changed |
booking.reminder | An automated reminder is sent (configurable) |
Booking event payload
{
"event": "booking.created",
"timestamp": "2026-02-01T14:30:00.000Z",
"data": {
"booking_id": "b7e8f9a0-1234-5678-abcd-ef0123456789",
"professional_id": "550e8400-e29b-41d4-a716-446655440000",
"client_name": "John Smith",
"client_email": "john@example.com",
"client_phone": "+1-555-0100",
"service": {
"id": "svc_abc123",
"name": "Haircut",
"price": 35.00,
"duration": 30,
"currency": "USD"
},
"scheduled_at": "2026-02-05T10:00:00.000Z",
"status": "confirmed",
"notes": "First time client, prefers short on sides"
}
}Building a webhook receiver
Here is a minimal example of a webhook receiver in Node.js:
const express = require('express')
const app = express()
app.use(express.json())
app.post('/webhooks/goconverso', (req, res) => {
const event = req.body
switch (event.event) {
case 'booking.created':
console.log('New booking:', event.data.booking_id)
// Sync to your CRM, send a Slack notification, etc.
break
case 'booking.cancelled':
console.log('Booking cancelled:', event.data.booking_id)
// Update your calendar, notify staff, etc.
break
default:
console.log('Unhandled event:', event.event)
}
// Always return 200 to acknowledge receipt
res.status(200).json({ received: true })
})
app.listen(3000, () => {
console.log('Webhook receiver running on port 3000')
})Retry policy
If your endpoint does not return a 2xx status code, GoConverso retries the webhook delivery:
| Attempt | Delay |
|---|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 30 minutes |
| 4th retry | 2 hours |
| 5th retry | 24 hours |
After 5 failed attempts, the webhook is marked as failed. You can view failed deliveries and retry them manually from the Stripe Dashboard.
Testing webhooks locally
During development, use the Stripe CLI to forward webhooks to your local environment:
# Install and login to the Stripe CLI
stripe login
# Forward events to your local Supabase edge function
stripe listen --forward-to localhost:54321/functions/v1/stripe-webhook
# Trigger a test event
stripe trigger checkout.session.completedWhen testing locally, the Stripe CLI provides a temporary webhook signing secret. Use this value for your local STRIPE_WEBHOOK_SECRET environment variable.
Security best practices
- Always verify signatures — Never process a webhook without first verifying the signature header. This prevents attackers from sending fake events to your endpoint.
- Use HTTPS — Webhook endpoints must use HTTPS in production. HTTP endpoints will not receive events.
- Respond quickly — Return a
2xxresponse within 30 seconds. If processing takes longer, acknowledge receipt immediately and process asynchronously. - Handle duplicates — Webhooks may be delivered more than once. Use the event
idto deduplicate. - Log everything — Store raw webhook payloads for debugging. This is invaluable when troubleshooting integration issues.
For more on payment integration, see the Stripe Checkout documentation . For API authentication, see the Authentication guide.