# Send the payment-failed email from a v0 app (Next.js App Router, BuildBase sign-in)

Turn on the email BuildBase sends when a card fails, plus one prompt for a signed webhook route handler in a v0 app for your own side effects.

v0 can also connect to BuildBase itself while it builds: [Use BuildBase in v0](/console/ai-agents/v0).

When a renewal fails, BuildBase emails the workspace owner from your sending domain. That needs no code, only two switches in the console. The prompt makes the webhook route handler do what you want to happen besides, such as flagging the workspace, verified with your webhook secret. This page assumes the app already signs people in with @buildbase/sdk, as the [v0 guide](https://www.buildbase.app/guides/add-sign-in-teams-and-paid-plans-to-a-v0-app) sets up. If it signs people in with something else, such as Supabase or Clerk, read [keep your existing sign-in](/sign-in-setup/keep-your-sign-in) first.

> **Note:**
  A sender connected ([connect a sender](/email/connect-a-sender)) and the
  **Payment Failed** notification event switched on
  ([notification events](/notifications/events)). For the route, an endpoint at
  `https://your-domain.com/api/webhooks/buildbase` under **Settings** >
  **Webhooks**, with `payment.failed` ticked ([add an
  endpoint](/webhooks/add-an-endpoint)).

## The prompt

v0's docs document no link that opens v0 with a prompt filled in, so copy this into your project's chat.

```text
This app signs people in with BuildBase (@buildbase/sdk), set up as https://www.buildbase.app/guides/add-sign-in-teams-and-paid-plans-to-a-v0-app shows. If it does not, stop and tell me.
Read https://docs.buildbase.app/webhooks/overview.md first and do not invent event names.
In app/api/webhooks/buildbase/route.ts, export POST. Verify it with parseWebhookEvent from @buildbase/sdk on the raw body from request.text(), the x-buildbase-signature and x-buildbase-timestamp headers and process.env.BUILDBASE_WEBHOOK_SECRET; answer 401 when it returns null.
On payment.failed, flag the workspace in my database; do not send an email, BuildBase sends it. Answer 200 to every other event.
```

## Where the secrets go

The console shows the endpoint's signing secret once, when you create it. Add it to the Vercel project's environment variables as `BUILDBASE_WEBHOOK_SECRET` (**Project menu** > **Settings** > **Environment Variables** in v0), with no `NEXT_PUBLIC_` prefix, then redeploy: a deployment keeps the values it was built with.

## The v0 trap

Paid, but nothing happened in your app: the endpoint in the console points at a preview's `vercel.app` address, which changes with every branch, or `BUILDBASE_WEBHOOK_SECRET` is empty on the deployment that answered. Point the endpoint at your production domain. The console's delivery log shows each attempt: a 401 means the secret, a timeout or a 404 means the route.

If the secret shows up in the deployed JavaScript, it was prefixed `NEXT_PUBLIC_` or read in a client component. Rotate it in the console, fix the name and redeploy.

## Full guides

- [Add sign-in, teams and paid plans to a v0 app](https://www.buildbase.app/guides/add-sign-in-teams-and-paid-plans-to-a-v0-app)
- [Failed payments](/billing/failed-payments): retries, grace days and the emails
- [Add BuildBase to v0's instructions](/ai-builders/v0-import)
