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

# Amounts, fees, and listing

> Cents, service fees, and listing payments.

## Amounts

All monetary values are **integer cents** in `USD`. There is no decimal representation.

| Value | Meaning |
| - | - |
| `100` | \$1.00 |
| `1050` | \$10.50 |
| `10000` | \$100.00 |

Every money field, in requests and responses, is an integer number of cents and its name ends in `Cents`. A request that sends a field named `amount` is refused with `400 VALIDATION_ERROR`.

When creating a payment, `amountCents` **must equal the sum of all `lineItems[].amountCents`** values, and every amount must be a positive integer. A mismatch returns `400 VALIDATION_ERROR`. A payment has between 1 and 50 line items.

## Service fees

GroGov calculates the service fee from the portal's configuration and adds it to `amountCents`. You cannot override the agency's service fee configuration.

A portal is an agency's payment configuration, selected with `portalId`. The principal is the payment amount before the service fee.

### Quote the fee before charging

`GET /fees/quote?portalId=<your-portal-id>&amountCents=<amount>` returns the service fee for the specified portal and payment amount. The quote uses the same calculation as the payment.

```bash theme={null}
curl "https://apistagepc.grogov.us/api/partner/v1/fees/quote?portalId=<your-portal-id>&amountCents=4000" \
  -H "Authorization: ApiKey pc_<your-key>"
```

```json theme={null}
{
  "success": true,
  "data": { "portalId": "<your-portal-id>", "amountCents": 4000, "serviceFeeCents": 100, "totalAmountCents": 4100, "currency": "USD" }
}
```

A missing or invalid `portalId` or `amountCents` returns `400 VALIDATION_ERROR`; a portal your account may not use returns `403 PORTAL_ACCESS_DENIED`. The quote is not a reservation: if the portal's fee configuration changes before you charge, the charge uses the new fee.

The payment response includes these amounts:

| Field | Meaning |
| - | - |
| `amountCents` | Principal in cents, excluding the service fee |
| `serviceFeeCents` | Fee added by the portal's fee configuration |
| `totalChargedCents` | `amountCents + serviceFeeCents`, the total charged to the card |
| `refundedAmountCents` | Total refunded so far (principal and fee) |
| `remainingRefundableAmountCents` | What can still be refunded (principal and fee) |

Each line item carries its pro-rated share of the fee in `serviceFeeCents`; the shares add up to the payment's `serviceFeeCents`.

## Listing payments

`GET /payments` returns payments associated with your API account, newest first.

### Query parameters

| Parameter | Type | Description |
| - | - | - |
| `limit` | integer | Page size: how many payments to return per page (default 25, max 100) |
| `cursor` | string | The `nextCursor` from the previous page, to get the next one |
| `status` | string | Only payments with this `status`: `succeeded`, `failed`, `voided`, `refunded`, `partially_refunded` or `unknown` |
| `portalId` | UUID | Only payments on this portal |
| `from` | ISO 8601 with timezone | Only payments created at or after this time |
| `to` | ISO 8601 with timezone | Only payments created at or before this time |

### Paging

Each response carries `nextCursor`. While it is not `null`, pass it back as `cursor`, **with the same filters**, to get the next page. On the last page `nextCursor` is `null`. Treat the cursor as opaque: an invalid cursor returns `400 VALIDATION_ERROR`, as does an unknown `status`.

There is no `referenceId` filter; filter on `lineItems[].referenceId` in your own code.

### Response

```json theme={null}
{
  "success": true,
  "data": {
    "payments": [
      { "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "status": "succeeded", "amountCents": 10000, "serviceFeeCents": 300, "...": "..." }
    ],
    "nextCursor": "eyJjIjoi..."
  }
}
```

### Example

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://apistagepc.grogov.us/api/partner/v1/payments?limit=25&portalId=<your-portal-id>&from=2026-10-01T00:00:00Z" \
    -H "Authorization: ApiKey pc_<your-key>"
  ```

  ```js Node.js theme={null}
  const base =
    "https://apistagepc.grogov.us/api/partner/v1/payments" +
    "?limit=100&portalId=<your-portal-id>&from=2026-10-01T00:00:00Z";

  // Walk every page: repeat the same filters with each nextCursor until it is null.
  let cursor = null;
  do {
    const url = cursor ? `${base}&cursor=${encodeURIComponent(cursor)}` : base;
    const res = await fetch(url, { headers: { Authorization: "ApiKey pc_<your-key>" } });
    const { data } = await res.json();
    for (const payment of data.payments) {
      console.log(payment.id, payment.status);
    }
    cursor = data.nextCursor;
  } while (cursor);
  ```
</CodeGroup>


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