> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pwnbook.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Billing

> Configure Stripe for subscription billing, manage organization plans, and set up webhooks. Billing is optional — Pwnbook runs without it, but enabling it unlocks plan-based feature gating.

## Overview

Pwnbook uses Stripe for subscription billing. Billing is entirely optional — if you don't configure Stripe, all features are available without restriction. When billing is enabled, organizations are placed on plans (Starter, Business, Enterprise) that control their access to specific features and seat limits.

<Tip>For self-hosted deployments used internally by a single organization, you likely don't need to configure billing. Skip this section unless you are running Pwnbook as a multi-tenant SaaS.</Tip>

## Enabling billing

To enable billing, you need a Stripe account and a secret key:

1. Create or log in to your [Stripe account](https://dashboard.stripe.com).
2. Obtain your **Secret Key** from **Developers** → **API Keys**. Use the live key for production, test key for testing.
3. Add the key to your Pwnbook environment:

```bash theme={null}
STRIPE_SECRET_KEY=sk_live_...
```

4. Restart the backend service:

```bash theme={null}
docker compose restart backend
```

Once the `STRIPE_SECRET_KEY` is set, billing features are activated and visible in the admin panel.

## Configuring subscription plans

Pwnbook maps Stripe products and prices to internal plan tiers. To configure this:

1. In Stripe, create products for each plan (Starter, Business, Enterprise).
2. Add a price to each product (monthly and/or annual).
3. In the Pwnbook admin panel, go to **Billing** → **Plan Configuration**.
4. Map each Stripe price ID to the corresponding Pwnbook plan tier.
5. Set the feature limits for each plan (seats, engagements, etc.).
6. Save.

### Plan tiers

| Plan           | Description                                                                            |
| -------------- | -------------------------------------------------------------------------------------- |
| **Starter**    | For small teams. Basic feature set, limited seats.                                     |
| **Business**   | Growing teams. Includes custom roles, SSO, API access, and priority support.           |
| **Enterprise** | Large organizations. Custom pricing, dedicated support, SLA, and self-hosting options. |

## Setting up Stripe webhooks

Stripe uses webhooks to notify Pwnbook of billing events (payment succeeded, subscription cancelled, etc.). Without webhooks configured, subscription status changes won't be reflected in Pwnbook.

<Steps>
  <Step title="Get your webhook endpoint URL">
    Your Pwnbook webhook endpoint is:

    ```
    https://your-pwnbook-domain.com/api/billing/webhook
    ```

    Replace `your-pwnbook-domain.com` with your actual domain.
  </Step>

  <Step title="Create the webhook in Stripe">
    1. In the Stripe dashboard, go to **Developers** → **Webhooks**.
    2. Click **Add endpoint**.
    3. Enter your webhook endpoint URL.
    4. Select the events to listen to (see [Webhook events](#webhook-events) below).
    5. Click **Add endpoint**.
  </Step>

  <Step title="Add the webhook secret to Pwnbook">
    After creating the webhook, Stripe provides a **Signing Secret**.

    Add it to your environment:

    ```bash theme={null}
    STRIPE_WEBHOOK_SECRET=whsec_...
    ```

    Restart the backend:

    ```bash theme={null}
    docker compose restart backend
    ```
  </Step>
</Steps>

### Webhook events

Configure Stripe to send the following events to your webhook endpoint:

| Event                           | Description                          |
| ------------------------------- | ------------------------------------ |
| `customer.subscription.created` | A new subscription was activated     |
| `customer.subscription.updated` | Subscription plan or status changed  |
| `customer.subscription.deleted` | Subscription was cancelled           |
| `invoice.payment_succeeded`     | A payment was successfully processed |
| `invoice.payment_failed`        | A payment attempt failed             |
| `customer.created`              | A new Stripe customer was created    |

## Managing organization subscriptions

From the admin panel's **Billing** section, you can view and manage subscriptions for individual organizations:

1. Go to **Server Admin** → **Billing** → **Organizations**.
2. Find the organization and click on it.
3. View current plan, billing cycle, next payment date, and payment method.

### Upgrading or downgrading a plan

To change an organization's plan:

1. Open the organization in the Billing admin.
2. Click **Change Plan**.
3. Select the new plan.
4. Confirm the change.

Plan changes take effect immediately for upgrades (features become available right away) and at the end of the current billing period for downgrades.

### Cancelling a subscription

To cancel an organization's subscription:

1. Open the organization in the Billing admin.
2. Click **Cancel Subscription**.
3. Choose immediate cancellation or cancel at period end.
4. Confirm.

After cancellation, the organization is downgraded to the default free tier (if configured) or access to paid features is restricted.

## Testing billing

Before going live, test your billing configuration using Stripe test mode:

1. Use a Stripe test secret key (`sk_test_...`) in your environment.
2. Use [Stripe test cards](https://stripe.com/docs/testing#cards) for payments.
3. Trigger webhook events using the Stripe CLI: `stripe trigger customer.subscription.created`.

Switch to live mode keys only when you're ready to accept real payments.
