> ## Knowledge Base Index
> Fetch the complete knowledge base index at: https://support.webnus.net/sitemap.xml
> Use this file to discover available pages before exploring further.
> Pure-Markdown content can be obtained by appending a '.md' suffix to the content URLs listed in the sitemap (without the trailing slash).

# Stripe Webhook Setup

In this article, we will walk you through configuring Stripe webhooks so MEC completes bookings reliably, even when the customer never returns to your website.

## Why Webhooks?

By default, MEC confirms a Stripe booking when the customer is redirected back to your website after payment. If the customer closes the browser tab, loses connection, or the redirect is blocked, the payment succeeds in Stripe, but the booking never completes.

With webhooks, Stripe notifies your website directly about successful payments. MEC then confirms the booking on its own, regardless of what the customer's browser does. This significantly reduces support requests about "paid but not booked" tickets.

Webhooks work for both the **Stripe** and **Stripe Connect** gateways.

**Note:** Webhooks are optional but strongly recommended. Without a webhook, MEC falls back to the redirect-only behavior.

## Step 1 - Copy Your Webhook URL

Go to **MEC Settings > Booking > Payment Gateways > Stripe** and locate the **Webhook Secret** field. The helper text below the field displays your site's webhook URL:

[Screenshot: the Stripe settings with the Webhook Secret field and URL]

```
https://yourdomain.com/wp-json/mec/v1/stripe/webhook
```

Copy this URL, you will paste it into your Stripe dashboard in the next step.

## Step 2 - Add the Endpoint in Stripe

1. Log in to your [Stripe dashboard](https://dashboard.stripe.com/).
2. Navigate to **Developers > Webhooks**.
3. Click **Add endpoint**.
4. Paste the webhook URL you copied in Step 1.
5. Under **Select events**, choose the following event only:
   - **payment_intent.succeeded**
6. Click **Add endpoint**.

[Screenshot: Stripe dashboard, Add endpoint dialog with the URL and event selected]

## Step 3 - Copy the Signing Secret

After the endpoint is created, Stripe displays its **Signing secret** (it starts with `whsec_`). Click **Reveal** and copy it.

## Step 4 - Paste the Secret in MEC

Back in **MEC Settings > Booking > Payment Gateways > Stripe**, paste the signing secret into the **Webhook Secret** field and save the settings.

That's it. MEC now verifies every webhook message using this secret, requests that do not come from your Stripe account are rejected.

## Stripe Connect

If you use the **Stripe Connect** gateway, configure the webhook for your **platform account** the same way:

1. The webhook URL pattern is identical (`/wp-json/mec/v1/stripe/webhook` on your website).
2. Subscribe to `payment_intent.succeeded`.
3. Paste the signing secret into the **Webhook Secret** field of the Stripe Connect settings.

When the **Organizer Payment module** is enabled and organizers connect their own Stripe accounts, the per-organizer settings include the same Webhook Secret field for their connected-account endpoint.

## Testing Your Webhook

1. Enable **Sandbox/Test mode** in the Stripe gateway settings (or use Stripe's test keys).
2. Book an event with Stripe's [test card](https://docs.stripe.com/testing) (e.g. `4242 4242 4242 4242`).
3. Close the browser tab immediately after paying, before the redirect happens.
4. After a few seconds, check **MEC > Bookings**: the booking should appear as confirmed, delivered by the webhook, not the redirect.

You can also inspect deliveries under **Developors > Webhooks > your endpoint** in the Stripe dashboard to see each event MEC received.

## Troubleshooting

**"Invalid Stripe webhook signature"**
The signing secret does not match. Reveal the secret of the exact endpoint you created and paste it again in MEC. If you recreated the endpoint, remember the new endpoint gets a new secret.

**"Stripe webhook secret is not configured"**
The Webhook Secret field in MEC is empty. Complete Step 4.

**Events appear in Stripe but bookings are not confirmed**
Make sure the endpoint is subscribed to `payment_intent.succeeded` (not `checkout.session.completed` or other events), and that the webhook URL points to the same website that holds the booking.