# Creem

Connect Creem with an API key and a signed webhook so ProductLense records checkouts, subscription payments, refunds and disputes.

ProductLense reads your Creem customers, subscriptions and transactions, including refunds and disputes. ProductLense only reads: it never writes to your Creem account, never refunds, cancels or changes anything.

## What you need

| Field | Secret | Where to find it |
|---|---|---|
| API key | Yes | A `creem_...` key from Developers → API keys. |
| Webhook secret | Yes | The signing secret shown on the webhook endpoint you point at ProductLense. |

Every plan includes one billing connection per site, Free too; Growth and Scale allow any number. See [plans and limits](/docs/account/plans-and-limits).

## Permissions

Creem API keys are not scoped; ProductLense only reads with yours. It calls `GET /v1/customers/list`, `/v1/subscriptions/list` and `/v1/transactions/list` on the live API (`api.creem.io`).

## Set up

1. In Creem, open Developers → API keys and create a key.
2. In ProductLense, open your site's Settings → Billing connections → Creem, paste the key, check the Processor fees estimate, and click Connect and import history.
3. Copy the webhook URL from the connection card.
4. In Creem, open Developers → Webhooks, add an endpoint with that URL, and copy its signing secret into the connection in ProductLense.

## Webhook

URL: `https://api.productlense.app/api/webhooks/creem/<connection-id>` (ProductLense shows the exact URL after you save).

Events ProductLense uses:

- `checkout.completed`
- `subscription.paid`
- `subscription.active`, `subscription.canceled`, `subscription.expired`, `subscription.update`, `subscription.trialing`, `subscription.paused`, `subscription.unpaid`
- `refund.created`
- `dispute.created` (recorded as a chargeback)

Verification: the `creem-signature` header, an HMAC-SHA256 of the raw body with your webhook secret. Creem signatures carry no timestamp; replays are rejected by event id.

## What ProductLense reads

- **Customers**: email, name and metadata, merged with the checkout's metadata.
- **Subscriptions**: status, interval and amount.
- **Payments**: transactions and completed checkouts, at the amount the customer paid.
- **Refunds and chargebacks**: refunded amounts, refunds and disputes.
- **History**: the last 12 months on first connect, then a nightly reconcile at 03:00 UTC from the last sync minus 48 hours.

## How fees are derived

Creem does not itemise its fee in the API, so every payment arrives with a fee of 0.

A fee estimate can be set under Processor fees on the connection card (percent, fixed amount per payment, and its currency), for example Creem's published rate. It starts at 0 and is applied only to charges that arrive with a zero fee. Estimated fees are flagged, and the dashboard shows the share of fees in a period that is estimated. An estimate is only as accurate as the rate you enter.

## Match payments to visitors

ProductLense reads the user id from the customer's metadata merged with the checkout or subscription metadata: `pl_user_id`, `user_id`, `userId` or `uid`. Use the same id you pass to `identify`. A ProductLense visitor id in `pl_visitor_id` or `visitor_id` is also accepted. Without either, ProductLense falls back to the customer email, matched to the `email` trait sent with `identify`, or to a user id that is that email.

```json title="Checkout request body, metadata part"
{ "metadata": { "pl_user_id": "user_123" } }
```

See [how payments are attributed](/docs/revenue/attribution).
