# Payment summary report

`GET /v2/reports/payment-summary`

Core API v2, Reports.

Generates a payment summary report with flexible grouping and metric calculations.

**Authentication:** Send `Authorization: Bearer <token>`. To authenticate, generate a Secret API Key from your ODUS Dashboard and include it in the `Authorization` header as follows: `Authorization: Bearer <YOUR_SECRET_API_KEY>`

## Parameters

### Query parameters

- `groupBy` (string, required): Field to group results by. **Available fields:** `currency`, `status`, `displayStatus`, `createdAt`, `authorizedAt`, `capturedAt`, `customer`, `gatewayProfile`, `product.name`, `customer.shippingAddress.country`, `attribution.utmSource`, `attribution.utmCampaign`, `latestDeclineCode` Example: `currency`.
- `granularity` (string): Date granularity for `groupBy` when it is a date field. Defaults to `day`. `hour` additionally requires the query to be bounded to a `createdAt` range of at most two days. Accepts `hour`, `day`, `week`, `month`, `quarter`, `year`; anything else falls back to the default.
- `secondaryGroupBy` (string): Optional second axis for pivoting (must differ from groupBy). Each row will then carry both the primary `groupBy` value and a `secondaryGroupBy` value. **Available fields:** `currency`, `status`, `displayStatus`, `createdAt`, `authorizedAt`, `capturedAt`, `customer`, `gatewayProfile`, `product.name`, `customer.shippingAddress.country`, `attribution.utmSource`, `attribution.utmCampaign`, `latestDeclineCode`
- `secondaryGranularity` (string): Date granularity for `secondaryGroupBy` when it is a date field. Defaults to `day`.
- `measures` (string): Metrics to include in the results. Multiple measures can be specified as comma-separated values. If `measures` is not provided, all metrics specified in the config will be calculated. **Available metrics:** `fcPaymentsCount`, `fcSuccessfulCount`, `fcSuccessfulItemCount`, `fcIncompleteCount`, `fcFailedCount`, `fcRefundAmount`, `fcChargebackAmount`, `fcRevenue`, `fcApprovalRate`, `recurringPaymentsCount`, `recurringSuccessfulCount`, `recurringSuccessfulItemCount`, `recurringDeclinedCount`, `recurringRefundAmount`, `recurringChargebackAmount`, `recurringRevenue`, `recurringApprovalRate`, `refundedPaymentsCount`, `refundAmount`, `refundPercentage`, `chargebacksCount`, `chargebackAmount`, `chargebackPercentage`, `totalGrossRevenue`, `totalNetRevenue` Example: `fcPaymentsCount,fcSuccessfulCount,fcSuccessfulItemCount,fcIncompleteCount,fcFailedCount,fcRefundAmount,fcChargebackAmount,fcRevenue,fcApprovalRate,recurringPaymentsCount,recurringSuccessfulCount,recurringSuccessfulItemCount,recurringDeclinedCount,recurringRefundAmount,recurringChargebackAmount,recurringRevenue,recurringApprovalRate,refundedPaymentsCount,refundAmount,refundPercentage,chargebacksCount,chargebackAmount,chargebackPercentage,totalGrossRevenue,totalNetRevenue`.
- `withTotal` (boolean): Whether to include a rollup row aggregating every group. Pass `false` to omit it. Default `true`.
- `id` (filter): Send as `id[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `createdAt` (filter): Send as `createdAt[<operator>]=<value>`. Operators: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `nin`.
- `updatedAt` (filter): Send as `updatedAt[<operator>]=<value>`. Operators: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `nin`.
- `amount` (filter): Send as `amount[<operator>]=<value>`. Operators: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `nin`.
- `status` (filter): Send as `status[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `displayStatus` (filter): Send as `displayStatus[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `currency` (filter): Send as `currency[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `amountCaptured` (filter): Send as `amountCaptured[<operator>]=<value>`. Operators: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `nin`.
- `amountReversed` (filter): Send as `amountReversed[<operator>]=<value>`. Operators: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `nin`.
- `product` (filter): Send as `product[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `price` (filter): Send as `price[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `offSessionType` (filter): Send as `offSessionType[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `paymentType` (filter): Send as `paymentType[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `latestDeclineType` (filter): Send as `latestDeclineType[<operator>]=<value>`. Operators: `eq`, `ne`, `in`, `nin`.
- `retry.attempts` (filter): Send as `retry.attempts[<operator>]=<value>`. Operators: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `nin`.
- `customer.email` (filter): Send as `customer.email[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `customer.billingAddress.country` (filter): Send as `customer.billingAddress.country[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `customer.shippingAddress.country` (filter): Send as `customer.shippingAddress.country[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `paymentMethod` (filter): Send as `paymentMethod[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `paymentMethod.type` (filter): Send as `paymentMethod.type[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `invoice.type` (filter): Send as `invoice.type[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `captureMethod` (filter): Send as `captureMethod[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `captureDelay` (filter): Send as `captureDelay[<operator>]=<value>`. Operators: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `nin`.
- `captureAt` (filter): Send as `captureAt[<operator>]=<value>`. Operators: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `nin`.
- `statementDescriptor` (filter): Send as `statementDescriptor[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `isCaptured` (filter): Send as `isCaptured[<operator>]=<value>`. Operators: `eq`, `ne`.
- `isReversed` (filter): Send as `isReversed[<operator>]=<value>`. Operators: `eq`, `ne`.
- `isFullyReversed` (filter): Send as `isFullyReversed[<operator>]=<value>`. Operators: `eq`, `ne`.
- `isChargebacked` (filter): Send as `isChargebacked[<operator>]=<value>`. Operators: `eq`, `ne`.
- `isRedirectRequired` (filter): Send as `isRedirectRequired[<operator>]=<value>`. Operators: `eq`, `ne`.
- `latestTransaction` (filter): Send as `latestTransaction[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `latestTransaction.processorId` (filter): Send as `latestTransaction.processorId[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `latestTransaction.gatewayProfile` (filter): Send as `latestTransaction.gatewayProfile[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `customer` (filter): Send as `customer[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `paymentMethod.card.lastFour` (filter): Send as `paymentMethod.card.lastFour[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `paymentMethod.card.bin` (filter): Send as `paymentMethod.card.bin[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`, `gte`, `lte`.
- `paymentMethod.card.brand` (filter): Send as `paymentMethod.card.brand[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `paymentMethod.card.expYear` (filter): Send as `paymentMethod.card.expYear[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `paymentMethod.card.expMonth` (filter): Send as `paymentMethod.card.expMonth[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `paymentMethodOptions.card.gatewayProfile` (filter): Send as `paymentMethodOptions.card.gatewayProfile[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `paymentMethodOptions.card.cascade` (filter): Send as `paymentMethodOptions.card.cascade[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `paymentMethodOptions.card.mode` (filter): Send as `paymentMethodOptions.card.mode[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `paymentMethodOptions.paypal.gatewayProfile` (filter): Send as `paymentMethodOptions.paypal.gatewayProfile[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `attribution.utmSource` (filter): Send as `attribution.utmSource[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `attribution.utmMedium` (filter): Send as `attribution.utmMedium[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `attribution.utmCampaign` (filter): Send as `attribution.utmCampaign[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `attribution.utmTerm` (filter): Send as `attribution.utmTerm[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `attribution.utmContent` (filter): Send as `attribution.utmContent[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `attribution.utmId` (filter): Send as `attribution.utmId[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.
- `attribution.utmContentid` (filter): Send as `attribution.utmContentid[<operator>]=<value>`. Operators: `eq`, `ne`, `like`, `ilike`, `in`, `nin`.

## Responses

### `200`

OK

Type: object (PaymentSummaryReportResponseDTO).

- `data` (array of object, required): Report data rows grouped by the specified field.
  - `groupBy` (string, required, nullable): The value of the groupBy field (field name varies based on groupBy parameter) Example: `USD`.
  - `secondaryGroupBy` (string, nullable): The value of the secondaryGroupBy field (present only when secondaryGroupBy was supplied) Example: `eur`.
  - `fcPaymentsCount` (number): Number of first-charge payments classified as approved, failed, or incomplete. Example: `42`.
  - `fcSuccessfulCount` (number): Number of successful first-charge payments. Example: `35`.
  - `fcSuccessfulItemCount` (number): Total number of line items across successful first-charge payments. May exceed `fcSuccessfulCount` when payments contain multiple line items. Example: `58`.
  - `fcIncompleteCount` (number): Number of first-charge payments still awaiting the customer on a redirect (`displayStatus` `incomplete`) Example: `3`.
  - `fcFailedCount` (number): Number of first-charge payments classified as failed: the latest attempt carries a declineType, whatever it says (including a payment you cancelled afterwards), or the payment ended in a failed state without one — an attempt that never got an answer, or a redirect the customer did not complete. Example: `4`.
  - `fcRevenue` (number): Total revenue from first-charge payments (in display currency) Example: `15000`.
  - `fcApprovalRate` (number): Approval rate for first-charge payments: approved / (approved + failed), as a percentage. Approved excludes chargebacks, unlike `fcSuccessfulCount`. Example: `89.74`.
  - `recurringPaymentsCount` (number): Number of recurring payments classified as approved or declined. Example: `120`.
  - `recurringSuccessfulCount` (number): Number of successful recurring payments. Example: `110`.
  - `recurringSuccessfulItemCount` (number): Total number of line items across successful recurring payments. May exceed `recurringSuccessfulCount` when payments contain multiple line items. Example: `185`.
  - `recurringDeclinedCount` (number): Number of recurring payments whose latest attempt carries a declineType, whatever it says — a refusal, an unresolved processor outcome, or a payment never authorized against the payment method — including those still being retried. Example: `10`.
  - `recurringRevenue` (number): Total revenue from recurring payments (in display currency) Example: `45000`.
  - `recurringApprovalRate` (number): Approval rate for recurring payments: successful / (successful + declined), as a percentage. Example: `91.67`.
  - `refundedPaymentsCount` (number): Number of refunded payments. Example: `5`.
  - `refundAmount` (number): Total refund amount (in display currency) Example: `2500`.
  - `refundPercentage` (number): Refund percentage relative to gross revenue. Example: `4.17`.
  - `chargebacksCount` (number): Number of chargebacked payments. Example: `2`.
  - `chargebackAmount` (number): Total chargeback amount (in display currency) Example: `1000`.
  - `chargebackPercentage` (number): Chargeback percentage relative to gross revenue. Example: `1.67`.
  - `fcRefundAmount` (number): Total refund amount on first-charge payments (in display currency) Example: `1500`.
  - `fcChargebackAmount` (number): Total chargeback amount on first-charge payments (in display currency) Example: `600`.
  - `recurringRefundAmount` (number): Total refund amount on recurring payments (in display currency) Example: `1000`.
  - `recurringChargebackAmount` (number): Total chargeback amount on recurring payments (in display currency) Example: `400`.
  - `totalGrossRevenue` (number): Total gross revenue (in display currency) Example: `60000`.
  - `totalNetRevenue` (number): Total net revenue after refunds and chargebacks (in display currency) Example: `56500`.
- `total` (object): Aggregated totals across all groups (only present when withTotal is enabled)
  - `groupBy` (string, nullable): The value of the groupBy field (field name varies based on groupBy parameter) Example: `USD`.
  - `secondaryGroupBy` (string, nullable): The value of the secondaryGroupBy field (present only when secondaryGroupBy was supplied) Example: `eur`.
  - `fcPaymentsCount` (number): Number of first-charge payments classified as approved, failed, or incomplete. Example: `42`.
  - `fcSuccessfulCount` (number): Number of successful first-charge payments. Example: `35`.
  - `fcSuccessfulItemCount` (number): Total number of line items across successful first-charge payments. May exceed `fcSuccessfulCount` when payments contain multiple line items. Example: `58`.
  - `fcIncompleteCount` (number): Number of first-charge payments still awaiting the customer on a redirect (`displayStatus` `incomplete`) Example: `3`.
  - `fcFailedCount` (number): Number of first-charge payments classified as failed: the latest attempt carries a declineType, whatever it says (including a payment you cancelled afterwards), or the payment ended in a failed state without one — an attempt that never got an answer, or a redirect the customer did not complete. Example: `4`.
  - `fcRevenue` (number): Total revenue from first-charge payments (in display currency) Example: `15000`.
  - `fcApprovalRate` (number): Approval rate for first-charge payments: approved / (approved + failed), as a percentage. Approved excludes chargebacks, unlike `fcSuccessfulCount`. Example: `89.74`.
  - `recurringPaymentsCount` (number): Number of recurring payments classified as approved or declined. Example: `120`.
  - `recurringSuccessfulCount` (number): Number of successful recurring payments. Example: `110`.
  - `recurringSuccessfulItemCount` (number): Total number of line items across successful recurring payments. May exceed `recurringSuccessfulCount` when payments contain multiple line items. Example: `185`.
  - `recurringDeclinedCount` (number): Number of recurring payments whose latest attempt carries a declineType, whatever it says — a refusal, an unresolved processor outcome, or a payment never authorized against the payment method — including those still being retried. Example: `10`.
  - `recurringRevenue` (number): Total revenue from recurring payments (in display currency) Example: `45000`.
  - `recurringApprovalRate` (number): Approval rate for recurring payments: successful / (successful + declined), as a percentage. Example: `91.67`.
  - `refundedPaymentsCount` (number): Number of refunded payments. Example: `5`.
  - `refundAmount` (number): Total refund amount (in display currency) Example: `2500`.
  - `refundPercentage` (number): Refund percentage relative to gross revenue. Example: `4.17`.
  - `chargebacksCount` (number): Number of chargebacked payments. Example: `2`.
  - `chargebackAmount` (number): Total chargeback amount (in display currency) Example: `1000`.
  - `chargebackPercentage` (number): Chargeback percentage relative to gross revenue. Example: `1.67`.
  - `fcRefundAmount` (number): Total refund amount on first-charge payments (in display currency) Example: `1500`.
  - `fcChargebackAmount` (number): Total chargeback amount on first-charge payments (in display currency) Example: `600`.
  - `recurringRefundAmount` (number): Total refund amount on recurring payments (in display currency) Example: `1000`.
  - `recurringChargebackAmount` (number): Total chargeback amount on recurring payments (in display currency) Example: `400`.
  - `totalGrossRevenue` (number): Total gross revenue (in display currency) Example: `60000`.
  - `totalNetRevenue` (number): Total net revenue after refunds and chargebacks (in display currency) Example: `56500`.

### `202`

The merchant is entitled but its environment is not provisioned yet. Provisioning has been kicked off (exactly once) and is in progress; retry the request — it succeeds once the environment is ready. Returned only for identity-token (dashboard) requests bound to a merchant, not for secret-key API calls; any such endpoint can return it while provisioning is underway.

Type: object (ProvisioningInProgress).

- `status` (string, required): Signals the merchant environment is still being provisioned. One of `provisioning`.
- `merchantAccountId` (string, required): The merchant account whose environment is being provisioned. Example: `dAI3aa87ROOeupeBCjNSKCOBOisBCYjB`.

### Errors

- `400`: The request was rejected. `type` is `invalid_request_error` when the request itself is at fault — `errors` then lists every problem found, with field-attributable entries prefixed by the field’s path; or `invalid_state_error` when the request was well-formed but the resource is not in a state that allows it.
- `401`: No API key was supplied, or the key is not valid. `type` is `authentication_error`.
- `403`: The API key is valid but lacks the permission this operation requires. `type` is `permission_error`.
- `429`: Too many requests. A limit applies per operation; requests to other operations are unaffected. `type` is `rate_limit_error`. Use the `Retry-After-global` header to know when to retry.
- `500`: The request could not be completed because of an unexpected error. `type` is `api_error`.
- `503`: The request could not be served right now: the API is temporarily at capacity, or a dependency needed to authorize the request is unavailable — the auth service that verifies credentials, or the entitlement lookup behind it. `type` is `api_error`. It is raised before the operation runs, so the request had no effect, and unlike a plain 500 the condition is transient: retry with backoff.
- `504`: The request exceeded the processing time limit and was abandoned. `type` is `api_error` and `code` is `timeout` — unlike a plain 500 the request may still have taken effect, so retry with the same idempotency key rather than blindly.

Every error response has the same body: see [Errors](https://docs.odus.com/docs/guides/api-features/errors.md).

---

Generated from the Core API v2 OpenAPI document, https://api.odus.com/openapi.v2.json. Interactive page: https://docs.odus.com/docs/api/core/v2/reporting-controller-get-payment-summary-report
