# Report payments and refunds

```http
POST https://secure.yoprint.com/v1/api/store/{team_slug}/report/payment
```

- API version: v1
- Operation ID: `v1_public_report_payment`
- Section: Reports › [Reports](https://developer.yoprint.com/reference/reports.md)
- Web page: https://developer.yoprint.com/reference/reports/v1-report-payment/
- Authentication: `Authorization: Bearer YOUR_API_KEY`

Returns every payment and refund recorded in the period on a sales order or quote that still exists, with its order, and every payment customers made in the Customer Portal. Use it to reconcile what you received.

Each row is a payment record (the shape of an order's payment list) plus six order fields: `amount` is in thousandths, an older encoding (`339750` is 339.75; refunds are negative), `date` is ISO 8601, `order_id` is the order's hash id while `order_scoped_id` is its number, and `invoices` is a list of the order's invoice numbers. (The CSV export from the web app formats these differently.)

A Customer Portal payment produces one row however many orders it paid. On all Customer Portal rows, `warehouse`, `order_scoped_id`, `order_name`, and `created_by` are null; `invoices` lists the invoices it was applied to, and `orders` lists the orders. Later provider changes (such as refunds) add an adjustment row signed like the change.

| Kind of payment row | `subtype` / `action` | Has `order_id` | Fields that are `null` |
| --- | --- | --- | --- |
| Standard order payment | `subtype: PAYMENT` | Yes | None (order fields populated) |
| Customer Portal (single order) | `subtype: PAYMENT`<br>`action: CUSTOMER_CHECKOUT` | Yes | `warehouse`, `order_scoped_id`, `order_name`, `created_by` |
| Customer Portal (multi-order funding) | `subtype: CUSTOMER_CHECKOUT_FUNDING` | No (`null`) | `warehouse`, `order_scoped_id`, `order_name`, `created_by` |
| Customer Portal funding adjustment | `subtype: CUSTOMER_CHECKOUT_FUNDING_ADJUSTMENT` | No (`null`) | `warehouse`, `order_scoped_id`, `order_name`, `created_by` |

## Permission

Needs the View Reports permission. Otherwise 403 with a bare `{ "message": "Insufficient Permission" }` (no `success` or `error` envelope).

## Business rules

- A payment or refund is in the period when it was recorded (created) between `start_date` and `end_date`, inclusive.
- Payments on a quote that became a sales order stay in the report. Payments on deleted orders are left out, except `CUSTOMER_CHECKOUT_FUNDING` rows and their adjustments, which are listed whatever happened to the orders.
- Only gateway, manual and Customer Portal payments and refunds are listed (lost disputes count as refunds): payments from customer credit, refunds to customer credit, and the moves that apply a Customer Portal payment to its orders are left out. Rows come newest first.

## Path parameters

- `team_slug` (string, required): Your team slug, shown as Team ID next to your API key in Profile. Example `your-team`.

## Request body

Content type `application/json`, required.

Fields:

- `end_date` (string (date-time), required): End of the period (ISO 8601), inclusive: send `23:59:59` to include the whole last day. In UTC, like `start_date` (an offset is dropped, not applied).
- `start_date` (string (date-time), required): Start of the period (ISO 8601), inclusive, to the second: send the start of the day. Send it in UTC (`Z`): the date and time are compared with UTC as written and any offset is dropped, so `2026-10-01T00:00:00-05:00` means midnight UTC.

### Example request

```bash
curl -X POST 'https://secure.yoprint.com/v1/api/store/your-team/report/payment' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Accept: application/json' \
  -H 'X-Yoprint-Decimal-Format: exact-v1' \
  -H 'Content-Type: application/json' \
  -d '{
    "end_date": "2026-11-30T23:59:59Z",
    "start_date": "2026-11-01T00:00:00Z"
  }'
```

## Response

`200` Successful response.

Fields:

- `data` (array of objects, required)
  - Each item:
    - `action` (string | null, optional): How it was made, for example a gateway name.
    - `amount` (integer | number | string | null, optional): The amount. Refunds are negative. Thousandths, an older encoding: `12500` is 12.50. Usually a whole number; an amount finer than a thousandth comes back as a number with a fraction (`1234.5` is 1.2345), or as a string (`"1234.5"`) when you send `X-Yoprint-Decimal-Format: exact-v1`. See [Money and quantities](/concepts/money-and-quantities/).
    - `created_by` (string | null, optional): Name of who created the order.
    - `customer_id` (string | null, optional): The customer.
    - `customer_name` (string | null, optional)
    - `customer_payment_funding_id` (string | null, optional): Customer Portal payment rows only: the customer payment.
    - `date` (string (date-time), optional): When it was recorded. ISO 8601 with offset.
    - `direction` (string, optional): `INCREASE` for a payment, `DECREASE` for a refund; a Customer Portal adjustment carries its own direction. One of: `"INCREASE"`, `"DECREASE"`.
    - `has_open_hold` (boolean, optional): Card and Customer Portal payments: true while a dispute (or review) is open.
    - `id` (string, optional): The payment record.
    - `invoices` (array of strings, optional): The order's invoice numbers (all of them, not only those this payment paid). On Customer Portal payment rows: the invoices the payment was applied to.
    - `is_deletable` (boolean, optional)
    - `is_editable` (boolean, optional)
    - `is_external_cash_movement` (boolean, optional): Customer Portal payment rows only: true for the customer's payment and its later changes.
    - `order_id` (string | null, optional): The order's hash id (not its number: that is `order_scoped_id`).
    - `order_name` (string | null, optional): The order name.
    - `order_scoped_id` (string | null, optional): The order number.
    - `orders` (array of objects, optional): Customer Portal payment rows only: the orders the payment was applied to (empty when they can't be found).
      - Each item:
        - `invoice_applications` (array of objects, optional)
          - Each item:
            - `invoice_id` (string | null, optional): The invoice's unique key.
            - `invoice_reference` (string | null, optional): The invoice number.
            - `original_applied_amount` (string | null, optional): What was first applied to this invoice, in currency units. A decimal string, such as `"100.0000"`; parse it as a decimal.
        - `order_id` (string, optional): The order's unique key (`ord_…`), not its hash id.
        - `order_reference` (string | null, optional): The order number when it was paid.
        - `original_applied_amount` (string | null, optional): What the payment first applied to this order, in currency units (not thousandths). A decimal string, such as `"100.0000"`; parse it as a decimal.
    - `payment_freeze_reason` (string | null, optional): `STRIPE`, `PAYPAL` and `SQUARE_V2` card payments and direct Customer Portal payments: `chargeback_open` or `payment_under_review` while a dispute or review freezes it, otherwise null.
    - `payment_gateway` (string | null, optional): The gateway, for a gateway payment or refund; null otherwise.
    - `payment_gateway_source` (string | null, optional): Only on gateway payments and refunds: the card source the gateway reported (Square), or null.
    - `payment_method_id` (string | null, optional): The payment method.
    - `payment_notices` (array of objects, optional): Card and Customer Portal payments: one notice per open dispute, as on an order's payment list.
    - `reference_description` (string | null, optional)
    - `reference_id` (string | null, optional)
    - `refundable_amount` (integer | number | string | null, optional): For a payment, what can still be refunded (0 when the method doesn't support refunds); 0 for a refund. Thousandths, an older encoding: `12500` is 12.50. Usually a whole number; an amount finer than a thousandth comes back as a number with a fraction (`1234.5` is 1.2345), or as a string (`"1234.5"`) when you send `X-Yoprint-Decimal-Format: exact-v1`. See [Money and quantities](/concepts/money-and-quantities/).
    - `related_transaction` (string | null, optional): For a refund, the `id` of the payment it refunds; null otherwise.
    - `subtype` (string, optional): `CUSTOMER_CHECKOUT_FUNDING` is a Customer Portal payment that paid several orders; `CUSTOMER_CHECKOUT_FUNDING_ADJUSTMENT` a later change to one (its `action` names the kind, for example `CUSTOMER_CHECKOUT_REFUND`). One of: `"PAYMENT"`, `"REFUND"`, `"CUSTOMER_CHECKOUT_FUNDING"`, `"CUSTOMER_CHECKOUT_FUNDING_ADJUSTMENT"`.
    - `token` (string | null, optional): A gateway reference, on some gateway payments; null otherwise.
    - `type` (string, optional): `MANUAL` (recorded by hand) or `SYSTEM` (recorded by a payment gateway).
    - `user_id` (string | null, optional): Who recorded it.
    - `voided` (boolean, optional)
    - `warehouse` (string | null, optional): The order's warehouse label.
- `status` (integer, required)
- `success` (boolean, required)

Example response:

```json
{
  "data": [
    {
      "action": "ORDER_PAYMENT",
      "amount": 100000,
      "created_by": "Alex Rivera",
      "customer_id": "ifAHmADekGZ6id",
      "customer_name": "Northwind Apparel",
      "date": "2026-11-03T14:30:00+00:00",
      "direction": "INCREASE",
      "id": "hAwWd7vPrqjuHD",
      "invoices": [
        "1001"
      ],
      "is_deletable": true,
      "is_editable": true,
      "order_id": "sFbALVSYD55eXe",
      "order_name": "Team shirts",
      "order_scoped_id": "SO1001",
      "payment_gateway": null,
      "payment_method_id": "Kst6z3ULXLBrmN",
      "reference_description": null,
      "reference_id": "CHK-1001",
      "refundable_amount": 100000,
      "related_transaction": null,
      "subtype": "PAYMENT",
      "token": null,
      "type": "MANUAL",
      "user_id": "4mdDkMg3dgQOa3",
      "voided": false,
      "warehouse": null
    }
  ],
  "status": 200,
  "success": true
}
```

## Errors

- `401` The API key is missing or wrong (`unauthenticated`).
- `403` You are not allowed to do this. `api_access_not_in_plan`: your team's plan doesn't include API access (Pro and above, with an active subscription or trial), so every request answers this until the team upgrades. When your role lacks the permission the operation needs, the body is only `{"message": "Insufficient Permission"}`. Other refusals use the error envelope, with `unauthorized` or `user_is_not_authorized`.
  - When: Your role lacks View Reports. Fix: Ask the team owner to turn on View Reports for your permission group.
- `404` Not found. `page_not_found`: the team slug is unknown, you are not a member of the team, or an id in the path is not one of this team's. `code: null`, with a message that starts "No query results for": there is no record with that id.
- `422` The request was refused and changed nothing. `validation_failed` lists what to fix in `error.fields`; other codes name a business rule, explained in `error.message`. A few checks answer with only `{"message": "..."}`. An operation that calls another service (a payment provider, a carrier, an accounting app) can answer `connect_timeout` ("Please retry again") when that service does not answer in time: the change may or may not have happened there, so read the record back before you retry.
  - When: `start_date` or `end_date` is missing or not ISO 8601. Fix: Send both as ISO 8601 date-times.

## Notes

- There is no paging: the whole period comes back in one response. Ask for a month or less at a time.

## Related

- [Report invoices of orders paid in full](https://developer.yoprint.com/reference/reports/v1-report-tax.md): `POST /v1/api/store/{team_slug}/report/tax`
- [List the payments of a sales order](https://developer.yoprint.com/reference/payments/v2-sales-order-payment-index.md): `GET /v2/api/store/{team_slug}/v2/sales_order/{hash_id}/payment`
