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

# Connect Stripe to Precipiq for automatic billing events

> Forward Stripe webhooks to Precipiq so every payment, refund, and dispute automatically creates a Financial Event in your AI ledger.

Precipiq includes a built-in webhook receiver for Stripe. Point Stripe at the endpoint once and every `payment_intent.succeeded`, `charge.refunded`, and `charge.dispute.created` event automatically creates a Financial Event in your ledger — no polling, no manual entry. Once events land, Precipiq's correlation worker scores them against recent AI decisions so you can see which agent actions drove which revenue outcomes.

## Setup

<Steps>
  <Step title="Get your Precipiq API key">
    In the Precipiq dashboard, go to **Settings → API keys** and copy your `pq_live_...` value. You'll need it in the next step.
  </Step>

  <Step title="Create the Stripe webhook endpoint">
    In the [Stripe dashboard](https://dashboard.stripe.com/webhooks), create a new endpoint pointing at:

    ```
    https://api.precipiq.dev/api/v1/financial-events/webhook/stripe
    ```

    Subscribe at minimum to these three events:

    * `payment_intent.succeeded`
    * `charge.refunded`
    * `charge.dispute.created`

    After saving, Stripe displays a signing secret starting with `whsec_` — copy it.
  </Step>

  <Step title="Add the Precipiq API key as a custom header">
    On the same Stripe webhook endpoint, add a **custom header** so Precipiq can identify your organisation:

    | Header           | Value         |
    | ---------------- | ------------- |
    | `X-Precipiq-Key` | `pq_live_...` |
  </Step>

  <Step title="Save the signing secret in Precipiq">
    In the Precipiq dashboard, go to **Settings → Integrations → Stripe**, paste the `whsec_...` secret, and save. Precipiq uses this to verify the `stripe-signature` header on every incoming payload and rejects anything that doesn't match.
  </Step>

  <Step title="Send a test event">
    Back in Stripe's webhook dashboard, click **Send test webhook**. Within seconds the event appears on the Precipiq **Financial Events** view.
  </Step>
</Steps>

## What happens when an event lands

When Stripe delivers a webhook, Precipiq processes it in four stages:

1. **Signature verification** — the `stripe-signature` header is checked against your saved `whsec_` secret. Payloads that fail verification are rejected immediately.
2. **Duplicate detection** — Stripe retries webhooks aggressively. If Precipiq has already seen the `stripe_event.id`, the duplicate is silently discarded with `processed: false, reason: "duplicate event; already processed"`.
3. **Financial Event creation** — the amount, currency, and event type are extracted from the payload and written as a new Financial Event in your ledger.
4. **Correlation** — the correlation worker runs every 5 minutes and scores the new event against recent decisions. High-confidence matches become auto-links; middling matches appear as suggested links for you to review.

## Sign conventions

Stripe always sends positive amounts. Precipiq applies the correct sign at ingestion based on the event type:

| Stripe event               | Precipiq type | Sign |
| -------------------------- | ------------- | :--: |
| `payment_intent.succeeded` | `payment`     |   +  |
| `charge.refunded`          | `refund`      |   −  |
| `charge.dispute.created`   | `chargeback`  |   −  |

## Zero-decimal currencies

<Warning>
  Precipiq divides all Stripe amounts by 100 at ingestion, which is correct for USD, EUR, and GBP (where Stripe stores amounts in cents) but produces values that are 100× too small for zero-decimal currencies like JPY, KRW, and IDR. If you process payments in zero-decimal currencies, multiply the stored amounts by 100 as a post-hoc correction until a future currency-metadata release addresses this automatically.
</Warning>

## Security

* The webhook receiver **fails closed** — if no `STRIPE_WEBHOOK_SECRET` is configured, signature verification is impossible and no webhooks are ingested.
* Both a valid `stripe-signature` header **and** a valid `X-Precipiq-Key` header are required. Possession of either one alone is not enough to inject events into your ledger.
* The endpoint is rate-limited at 100 requests per second. This is well above normal Stripe traffic volumes and acts as a safeguard against replay floods if a signing secret is ever leaked.
