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

# Commas

> Receive Commas payments, installments, renewals, refunds, and lost disputes as revenue events.

When you finish, every Commas payment arrives in **Events** as revenue, linked to the ad click that started it.

Commas was formerly FanBasis.

## What Commas sends

DATALYR creates the Commas webhook for you. It subscribes to four Commas events.

| Commas event | Condition | DATALYR event | Money role |
| - | - | - | - |
| `payment.succeeded` | First charge | `purchase` | Cash, gross |
| `payment.succeeded` | A later installment or subscription renewal | `recurring` | Cash, gross |
| `subscription.renewed` | Same payment as its `payment.succeeded` | `recurring`, kept once | Cash, gross |
| `refund.created` | Status `success` | `refund` | Refund, recorded positive |
| `dispute.updated` | Status `lost` or `lost_rdr` | `chargeback` | Chargeback, recorded positive |

Every other delivery writes nothing. A won dispute moves no money, so it writes nothing too.

The event `value` is the Commas `amount` in dollars, gross. DATALYR records no value when `amount` is missing, negative, or above 1000000. Currency is the Commas currency, or `USD` when the delivery has none.

Refund and chargeback amounts are positive. They are separate metrics, and no report subtracts them from revenue. See [Refunds](/revenue/refunds).

The event ID comes from the Commas payment, refund, or dispute ID, so one payment is one row however many deliveries describe it.

<Note>
  Commas sends each webhook once and does not retry it.
</Note>

## Before you start

| Requirement | Detail |
| - | - |
| DATALYR access | Owner or admin of the workspace |
| Commas API key | Created in **Account → API Keys**, with the `webhooks` and `payments` scopes |
| Web tracking | The [tracking script](/getting-started/install-web-tracking) on the pages buyers visit before checkout |

## Connect Commas

<Steps>
  <Step title="Create an API key">
    In the Commas dashboard, open **Account → API Keys**. Create a key with the `webhooks` and `payments` scopes.
  </Step>

  <Step title="Open the Commas card">
    In DATALYR, open **Sources**. On the **Commas** card, select **connect**.
  </Step>

  <Step title="Paste the key">
    Paste the key into **API key**. Select **Connect Commas**.
  </Step>
</Steps>

DATALYR creates the webhook in your Commas account and stores its signing secret. Every delivery is checked against that secret.

Do not delete the DATALYR webhook in Commas. Without it, no payment reaches DATALYR. To recreate it, disconnect and connect again.

## How payments match to ad clicks

DATALYR checks these in order and stops at the first one that finds an ad click.

| Order | Source | Comes from |
| - | - | - |
| 1 | `dl_vid` in checkout metadata | The buyer's DATALYR `visitor_id`, set when you create the checkout session |
| 2 | Buyer email | The Commas buyer email, matched to an earlier visit, booking, or `identify()` call |

If you create checkout sessions through the Commas API, add `dl_vid` to the session metadata. Read the value with `datalyr.getVisitorId()` in the buyer's browser. Commas returns the metadata on every webhook under `api_metadata.data`.

DATALYR also reads these keys from the same metadata: `utm_source`, `utm_medium`, `utm_campaign`, `utm_content`, `utm_term`, `fbclid`, `gclid`, `ttclid`, `fbc`, `fbp`.

Without `dl_vid`, the buyer email does the match. A buyer who booked through [iClosed](/integrations/iclosed) or [Calendly](/integrations/calendly) with the same email matches that way.

With no match, `visitor_id` is `commas_` plus the Commas buyer ID.

## Set up conversion rules

Select the flag icon on the connected **Commas** card to open the starter rules.

| Event | Meta | TikTok | Snapchat | OpenAI |
| - | - | - | - | - |
| `purchase` | `Purchase` | `CompletePayment` | `PURCHASE` | `order_created` |
| `recurring` | `Purchase` | `CompletePayment` | `PURCHASE` | none |

Both send the payment amount as the value and the DATALYR conversion ID as the order ID. There is no refund rule, because refunds arrive positive.

If an [iClosed](/integrations/iclosed) `deal_won` rule already sends `Purchase` to the same pixel, leave the Commas `purchase` rule off. Each rule delivers separately, so Meta counts the sale twice.

## Verify

1. Open your sales page in a private window with `?utm_source=doctest`.
2. Buy a low-priced test product with a test email address.
3. Open **Events**. Find the `purchase` row with source `commas`.
4. Confirm `value`, `currency`, and `event_data.order_id`.
5. Confirm `utm_source` reads `doctest`.
6. Refund the payment in Commas. Confirm a `refund` row arrives.

## When it does not work

| Symptom | Cause | Check | Fix |
| - | - | - | - |
| **Connect Commas** shows `That API key was rejected by Commas` | The key is wrong or revoked | The key in **Account → API Keys** | Create a new key. Paste it again |
| **Connect Commas** shows an error that starts with `Commas:` | Commas refused the webhook request, most often because the key lacks `webhooks` or `payments` | The key's scopes | Create a key with both scopes |
| No Commas events | The DATALYR webhook was deleted in Commas | The webhook list in Commas | Disconnect and connect again |
| A payment is missing | Commas does not retry, so a failed delivery is not resent | The payment in Commas | Contact support with the payment ID |
| `visitor_id` starts with `commas_` | No `dl_vid` and no known email | The checkout metadata | Add `dl_vid` to the checkout session metadata |
| Revenue looks too high | Refunds are positive and never subtracted | `refund` rows in the date range | Read `refund` rows separately |
| Meta counts each sale twice | iClosed `deal_won` and Commas `purchase` both send `Purchase` | **Conversions** | Turn off one of the rules |

## Next

* [iClosed](/integrations/iclosed): send the booked call and the won deal before the cash arrives.
* [Subscriptions](/revenue/subscriptions): how installments and renewals show in reports.
* [Conversions](/product/conversions): read a delivery row.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.