# Payment Summary Report

The Payment Summary Report aggregates transaction outcomes across your business and splits them into two payment buckets — **first-charge (FC)** and **recurring** — alongside refund, chargeback, gross and net revenue metrics.

Use it to monitor approval rates, track refunds and chargebacks, and compare gateway, product, or campaign performance.

## Open the report

In the ODUS Dashboard, navigate to **Insights → Payments**. The page shows a summary chart of revenue, refunds, and chargebacks, with a detailed breakdown table below.

## Date range and timezone

The date range selector filters payments by their **`createdAt`** timestamp. Switch between **UTC** and your merchant timezone to align daily boundaries with your business hours. The merchant timezone is configured in **Settings → Merchant Configuration**; if unset, the report falls back to UTC.

Unlike the [Customer Value Report](https://docs.odus.com/docs/guides/reports/customer-value-report.md), every payment is evaluated independently — there is no cohort anchoring. A payment is included whenever its creation time falls inside the window.

## Grouping

Use the **Group by** tabs to organize rows by product, currency, calendar day, gateway profile, UTM source, or UTM campaign. Switching grouping updates the chart and table immediately.

## Filtering

Open the **Filters** panel from the top-right of the report to narrow it to a segment of your book. Filters apply to the chart, the table and the CSV export alike, and they are written into the page URL — so a filtered view can be bookmarked, reloaded, or shared with a colleague. The filters you apply are also remembered per report in this browser, so returning to it later reopens the slice you left it on — unless you arrive on a link that already carries filters, which always win. **Clear all** forgets them. Nothing is refetched until you press **Apply**.

Filtering never changes how a payment's revenue is attributed. A row that survives a filter carries exactly the number it carried before — filtering selects rows, it does not recalculate them.

When you filter by product or price **and** group by product, only the filtered product's row is shown. A payment whose cart also held other products still counts in full towards that row, but its cart-mates do not appear as rows of their own.

| Filter                                                   | Notes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Product**, **Price**                                   | Selects payments whose cart contains a line item for that product or price. A cart with several line items still counts once, at its full amount. Excluding a product (`nin`) removes every payment carrying it, even alongside others. The pickers offer your whole catalogue, newest first — deactivated entries included and labelled `(inactive)`, since historical payments still reference them; when several entries share a name, each also shows its creation date.                                    |
| **Payment type**                                         | `initial` or `recurring`. Prefer this over `offSessionType`, which is unset on an initial charge and therefore skips them all under a "not recurring" filter.                                                                                                                                                                                                                                                                                                                                                   |
| **Gateway profile**                                      | The profile the payment was actually processed on, read from its latest transaction — which a cascade may have changed. The *requested* profile (`paymentMethodOptions.card.gatewayProfile`) is filterable on the API but not offered in the panel.                                                                                                                                                                                                                                                             |
| **Currency**, **Status**, **Amount**                     | Payment-level fields.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| **Card brand**, **Last four**, **Expiry**                | Read from the payment method.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| **BIN**                                                  | Read from the payment method. Choose **is** to match one BIN exactly, or **is between** to select a range: each bound stands for every card number that starts with it, so `4688` to `4688` selects every BIN beginning with `4688`. A payment whose BIN has fewer digits than your bounds is left out when it could fall on both sides of a bound — see [Filtering by a range of card BINs](https://docs.odus.com/docs/guides/api-features/pagination-filtering-sorting.md#filtering-by-a-range-of-card-bins). |
| **Billing country**                                      | The country on the customer's billing address, chosen by name from the country list. Pick several to report on a whole market. Note this is the address they gave you, not the country that issued the card.                                                                                                                                                                                                                                                                                                    |
| **Shipping country**                                     | The customer's shipping-address country — where the order goes. Chosen the same way. A customer with no shipping address on file has no country to match, so those payments drop out of the report whenever this filter is set.                                                                                                                                                                                                                                                                                 |
| **UTM source / medium / campaign / term / content / id** | Attribution captured at checkout.                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |

Filterable on the API but not offered in the panel: **Cascade**, **Payment method type**, **Card mode**, **Card expiry**, the **requested** gateway profile (`paymentMethodOptions.card.gatewayProfile`, as opposed to the used one above), **Decline type** (`soft_decline`, `hard_decline` or `not_attempted`) and **Retry attempts**. Every parameter the route publishes is listed in the [API reference](https://docs.odus.com/docs/api/core/v2/reporting-controller-get-payment-summary-report).

## What counts as a payment

A payment enters the counts once it can be classified: it was **approved**, it **failed**, or — for a first-charge payment — it is **incomplete**, meaning the customer is still with their bank or wallet approving it. Every counted payment falls into exactly one outcome column, so:

* **FC Payments Count** = FC Successful + FC Incomplete + FC Failed
* **Recurring Payments Count** = Recurring Successful + Recurring Declined

A renewal is charged without the customer present, so the recurring bucket has no incomplete column, and a renewal counts as declined whenever its latest attempt came back with a `declineType` — whatever that type says. That covers a refusal, an outcome the processor never resolved, and a payment that was never authorized against the payment method at all. A renewal attempt that failed without producing a `declineType` is not classified and is counted nowhere; the same first-charge attempt counts as failed.

Two more kinds of payment cannot be classified and are counted nowhere: a checkout that was opened but never submitted (display status `unattempted`), and a payment cancelled without ever being declined — withdrawn by you, or blocked by one of your customer restrictions before it reached the gateway. The second kind is left out of the report entirely, so it cannot produce a row of its own either. A payment that *was* declined and cancelled afterwards is still a decline, and is counted as one.

Each payment is classified as either **first-charge (FC)** or **recurring** based on its `offSessionType`:

* **Recurring** — payments generated by the subscription billing engine to renew an active subscription (`offSessionType = recurring`).
* **First-charge (FC)** — every other payment. This includes on-session checkout payments and unscheduled merchant-initiated charges. The "FC" label is a bucket name for "non-recurring" — it does **not** mean the customer's first-ever payment.

note

"FC" in this report has a different meaning than in the [Customer Value Report](https://docs.odus.com/docs/guides/reports/customer-value-report.md). There, FC strictly means a customer's lifetime first charge. Here, it is shorthand for any non-subscription-renewal payment, regardless of whether the customer has paid before.

Both buckets are reported side-by-side so you can compare new payment activity against subscription renewal performance.

## Metrics

### First-charge metrics

| Metric                  | Definition                                                                                                                                                                                                                                                                                                                     |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **FC Payments Count**   | Non-recurring payments classified as approved, failed or incomplete: the sum of FC Successful, FC Incomplete and FC Failed.                                                                                                                                                                                                    |
| **FC Successful Count** | FC payments with status `succeeded`, `reversed`, `partially_reversed`, `uncaptured`, or `chargeback`.                                                                                                                                                                                                                          |
| **FC Successful Items** | Total line items across all successful FC payments (a multi-item cart contributes one row per line item).                                                                                                                                                                                                                      |
| **FC Incomplete Count** | FC payments still awaiting the customer, who was sent to their bank or wallet to approve the payment and has not yet returned (`displayStatus` `incomplete`).                                                                                                                                                                  |
| **FC Failed Count**     | FC payments whose latest attempt came back with a `declineType`, whatever it says (one you cancelled afterwards still counts), plus those that ended in a failed state without one — sent to a redirect the customer did not complete within a day, or ended before the gateway answered. Most carry `displayStatus` `failed`. |
| **FC Revenue**          | Gross revenue from successful FC payments.                                                                                                                                                                                                                                                                                     |
| **FC Approval Rate**    | `FC Approved / (FC Approved + FC Failed) × 100`, where *approved* excludes chargebacks. Incomplete payments are on neither side until they resolve.                                                                                                                                                                            |

### Recurring metrics

| Metric                         | Definition                                                                                                                                                                                                                                                                             |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Recurring Payments Count**   | Recurring payments classified as approved or declined: the sum of Recurring Successful and Recurring Declined.                                                                                                                                                                         |
| **Recurring Successful Count** | Recurring payments with status `succeeded`, `reversed`, `partially_reversed`, `uncaptured`, or `chargeback`.                                                                                                                                                                           |
| **Recurring Successful Items** | Total line items across all successful recurring payments.                                                                                                                                                                                                                             |
| **Recurring Declined Count**   | Recurring payments whose latest attempt came back with a `declineType`, whatever it says. Counted whether a retry is scheduled, or the payment was cancelled because the failure was final or its retries ran out. A payment recovered by a later retry moves to Recurring Successful. |
| **Recurring Revenue**          | Gross revenue from successful recurring payments.                                                                                                                                                                                                                                      |
| **Recurring Approval Rate**    | `Recurring Successful / (Recurring Successful + Recurring Declined) × 100`; chargebacks are included in both values.                                                                                                                                                                   |

info

A renewal that is being retried counts as declined until a retry is approved, so the Recurring Approval Rate for a recent period rises as retries land.

### Refunds, chargebacks, and totals

| Metric                      | Definition                                                         |
| --------------------------- | ------------------------------------------------------------------ |
| **Refunded Payments Count** | Payments with status `reversed` or `partially_reversed`.           |
| **Refund Amount**           | Total refunded amount (full and partial).                          |
| **Refund Percentage**       | `Refund Amount / Gross Successful Revenue × 100`.                  |
| **Chargebacks Count**       | Payments with status `chargeback`.                                 |
| **Chargeback Amount**       | Total amount of chargebacked payments.                             |
| **Chargeback Percentage**   | `Chargeback Amount / Gross Successful Revenue × 100`.              |
| **Total Gross Revenue**     | All successful revenue across FC and recurring, before deductions. |
| **Total Net Revenue**       | `Total Gross Revenue − Refund Amount − Chargeback Amount`.         |

The **Total** row aggregates each metric across all groups.

All monetary metrics are converted to your **display currency** (set in **Settings → Merchant Configuration**) using the exchange rate effective at the time of each payment, so historical totals remain stable.

## Multi-item carts

When grouped by **Product**, a payment whose cart contains multiple line items is split across rows proportionally to each line item's share of the payment amount. Counts use a distinct-payment formula so a multi-item cart still counts as one payment. Other groupings assign each payment to exactly one row.

## Example

Say your store processed the following six payments on **2026-06-01**, all in your display currency:

| Payment | Type     | Amount | Outcome                   |
| ------- | -------- | ------ | ------------------------- |
| #1      | Checkout | $50    | Succeeded                 |
| #2      | Checkout | $50    | Declined                  |
| #3      | Checkout | $80    | Succeeded                 |
| #4      | Checkout | $80    | Refunded ($80)            |
| #5      | Rebill   | $30    | Succeeded                 |
| #6      | Rebill   | $30    | Declined, retry scheduled |

Grouped by **Day**, the report row for 2026-06-01 looks like this:

| FC Count | FC Successful | FC Failed | FC Revenue | FC Approval | Recurring Count | Recurring Successful | Recurring Revenue | Recurring Approval | Refund Amount | Total Gross | Total Net |
| -------- | ------------- | --------- | ---------- | ----------- | --------------- | -------------------- | ----------------- | ------------------ | ------------- | ----------- | --------- |
| 4        | 3             | 1         | $210       | 75%         | 2               | 1                    | $30               | 50%                | $80           | $240        | $160      |

How each number is derived:

* **FC Count = 4** — payments #1–#4 are all non-recurring (checkout).
* **FC Successful = 3** — #1, #3, #4 (a refunded payment was originally successful).
* **FC Revenue = $210** — gross of the three successful FC payments ($50 + $80 + $80), before subtracting refunds.
* **FC Approval = 75%** — `3 approved / (3 approved + 1 failed) × 100`.
* **Recurring Successful = 1** and **Approval = 50%** — one of the two rebills (#5, #6) succeeded. #6 counts as declined while its retry is pending; if the retry is approved, it moves to Recurring Successful and the rate becomes 100%.
* **Refund Amount = $80** — payment #4 was fully refunded.
* **Total Gross = $240** — `$210 FC + $30 recurring`.
* **Total Net = $160** — `$240 − $80 refund − $0 chargebacks`.

## Export to CSV

Click **Export CSV** in the top-right of the table to download the current view. The file contains one row per group plus a Total row, with monetary values in your display currency. The selected date range is included in the filename.

## API access

The same data is available via [`GET /v2/reports/payment-summary`](https://docs.odus.com/docs/api/core/v2/reporting-controller-get-payment-summary-report). The endpoint supports all grouping options, metric selection via `measures`, and every filter listed above — each published as a query parameter in the API reference, with the operators (`eq`, `ne`, `in`, `nin`, `gt`, `gte`, `lt`, `lte`, `like`, `ilike`) its type accepts. String filters are case-sensitive except `ilike`. `paymentMethod.card.bin` also takes a range with `gte` and `lte`, compared as the card numbers each BIN starts rather than as text — see [Filtering by a range of card BINs](https://docs.odus.com/docs/guides/api-features/pagination-filtering-sorting.md#filtering-by-a-range-of-card-bins).

The API additionally accepts a `secondaryGroupBy` parameter to split each group along a second dimension (e.g. `groupBy=displayStatus&secondaryGroupBy=currency`). When supplied, each response row carries a `secondaryGroupBy` field with the value of that second dimension.

### Example

```
GET /v2/reports/payment-summary?groupBy=product.name&createdAt[gte]=2026-01-01T00:00:00Z&createdAt[lte]=2026-01-31T23:59:59Z&displayStatus[ne]=unattempted
```

`displayStatus[ne]=unattempted` is optional: an unsubmitted checkout is already left out of every metric (see [What counts as a payment](#what-counts-as-a-payment)), so the filter changes no number. It does keep a group whose only payments were never submitted — a product with no other activity in the window — out of the response, where it would otherwise appear with every metric at zero. Do not exclude `cancelled`: a rebill that was declined and then cancelled once its retries ran out is a decline, and filtering it out removes it from Recurring Declined and inflates the approval rate.

Narrowed to one product, paid in EUR, acquired from a single campaign:

```
GET /v2/reports/payment-summary?groupBy=createdAt&granularity=day&createdAt[gte]=2026-01-01T00:00:00Z&createdAt[lte]=2026-01-31T23:59:59Z&product[eq]=prod_2ABc&currency[eq]=eur&attribution.utmSource[eq]=fb
```

The response contains a `data` array (one entry per group) and a `total` object with the aggregate across all groups.
