# Get store payouts and tax reports

> See how Coritan pays out your store's balance, ask for a payout, follow each one and download the tax charged on your sales.

Source: https://docs.coritan.com/organizations/storefront/commerce-payouts/

A *payout* sends your store's payable balance to your organization, one currency at a time. We create payouts on your store's schedule, you can ask for one at any time, and our staff approve and send each one. The tax report lists the tax the Coritan companies charged on your sales, for your own accounts.

This page covers store payouts. The payouts for your organization's billing are on [Track your payouts](/organizations/billing/payouts/), and neither list shows the other's. The routes are under `https://api.coritan.com/api/v1/orgs/{org_slug}/commerce/`. The API reference lists the payout routes under [Billing & Payouts](/api/reference/organizations/billing-payouts/commerce/), and the tax report under [Commerce](/api/reference/organizations/commerce/commerce/).

## Before you begin

- Reading payouts and tax reports takes an organization API key with the `commerce.finance:read` scope, or a member's token with the Billing role or above.
- Asking for a payout takes an owner's or admin's token. No API key can ask for one.
- We pay out only once we have approved your [merchant profile](/organizations/storefront/commerce-api/#submit-the-merchant-profile), and never while the store is suspended.
- We send the money by the payout method set for your organization: `paypal`, `stripe_connect`, or `manual`, which means we send it by hand. Ask [support](https://www.coritan.com/dashboard/support) to change it.

## How a payout is worked out

A payout pays every row of the [ledger](/organizations/storefront/commerce-api/#read-the-balance-and-the-ledger) in one currency that is `available` and not yet paid: your sales and shipping, less refunds, our commission and [chargebacks](/organizations/storefront/commerce-disputes/). It takes off any reserve that is still held, and pays a reserve back once its release date has passed. The result is the `payable` amount that `GET /commerce/balance` shows. Test orders never count.

Tax is never paid out, because the Coritan company that sold the order owes it. The money for a gift card sold is not paid out either: it becomes yours as part of the sale when a shopper spends the card.

We make no payout in a currency, and the balance carries over, when:

- The payable amount is zero or less, because refunds and chargebacks outweigh sales. Later sales cover the debt first.
- It is below the currency's minimum: 10 in the currency's main unit, such as €10.00, unless we set another.
- A payout in the currency is still open.
- Payouts are held, because the store is suspended or the merchant profile is not approved.

### The amounts on a payout

Amounts are in minor units of the payout's `currency_code`:

| Field | What it is |
| --- | --- |
| `net_amount` | What we send: the sum of the rows the payout pays. |
| `platform_fee` | Our commission within those rows. |
| `amount` | `net_amount` and `platform_fee` together. |
| `by_type` | The rows by `entry_type`, each with its `amount` and `count`. |
| `entry_count` | How many rows the payout pays. |

## Set the payout schedule

We create payouts on the store's `payout_schedule`, which is `daily`, `weekly` or `monthly`. Weekly is the default. The periods follow UTC: a day, a week from Monday, or a calendar month. In each period, we create one payout for each currency as soon as its payable amount reaches the minimum.

```bash
curl -X PATCH "https://api.coritan.com/api/v1/orgs/acme/commerce/store" \
  -H "X-API-Key: $ORG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"settings": {"payout_schedule": "monthly"}}'
```

Changing it takes `commerce.store:write` or the Admin role, and another word answers `422`. A payout you ask for counts as the period's payout for its currency, so the schedule creates the next one in the next period.

## Ask for a payout

`POST /commerce/payouts` asks for the payable balance in one currency now, instead of waiting for the schedule:

```bash
curl -X POST "https://api.coritan.com/api/v1/orgs/acme/commerce/payouts" \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Idempotency-Key: payout-eur-2026-09-26" \
  -H "Content-Type: application/json" \
  -d '{"currency_code": "EUR"}'
```

The answer is `201` with the `payout`, which is `awaiting_approval`. When there is nothing to pay, the answer is `409`, with the reason as its `error`: `nothing_payable`, `below_minimum`, `payout_open` or `held`. It also gives the `currency_code`, the `payable` amount and the `minimum`, and your balance stays as it is.

The organization can ask 10 times an hour, retries included. Beyond that, the answer is `429` with `rate_limited` and a `Retry-After` of 3,600 seconds.

An optional `Idempotency-Key` header of up to 128 characters makes a retry safe. A retry with the same key within 24 hours gets the first answer back and creates nothing, and the same key with another currency answers `409` with `idempotency_key_reused`. A refused request keeps no key, so you can ask again later with the same one.

## Follow your payouts

`GET /commerce/payouts` lists the store's payouts newest first, with `count`, filtered by `status` and `currency_code`. `status=open` finds both open statuses. A page holds up to 200 payouts, and 50 by default.

| Status | What it means |
| --- | --- |
| `awaiting_approval` | We created it and took its rows off your balance. It waits for our staff to send it. |
| `processing` | Our staff are sending it. `outcome_unknown` is `true` when the provider has not said whether it went through. |
| `completed` | We paid it. `completed_at` says when, and `gateway_reference` holds the payment's reference. |
| `declined` | We could not send it, and `failure_reason` says why. Its rows are back in your balance. |
| `canceled` | Our staff cancelled it, and its rows are back in your balance. |

Each payout also has its `payout_method`, the `trigger` that created it (`schedule`, `merchant` for you, or `staff`), and `period_start` and `period_end`, which are the time of its oldest row and the time we created it. `released_at` says when a declined or cancelled payout gave its rows back.

The list's `summary` shows your `schedule`, and in `balances`, what each currency could pay now:

```json
{
  "schedule": "weekly",
  "balances": [
    {"currency_code": "EUR", "payable": 184250, "minimum": 1000, "open_payout_id": null}
  ]
}
```

`open_payout_id` names a payout in the currency that is still open.

### Read the rows in a payout

`GET /commerce/payouts/{payout_id}` answers the `payout` with the ledger `entries` it holds, oldest first, and `entries_count`. A page holds 100 entries by default and up to 200, set with `limit` and `offset`.

The entries are the rows the payout pays, each now `paid_out` with the payout's ID in `payout_id`, and a `payout` row of minus the `net_amount`, described as `Payout #88`. A declined or cancelled payout holds only its two `payout` rows, which cancel out: the second one gave the money back to your balance. `GET /commerce/ledger` shows the same rows.

### Payout webhooks

| Event | When |
| --- | --- |
| `commerce.payout.created` | We create a payout, on the schedule, when you ask, or when our staff make one. |
| `commerce.payout.paid` | A payout is completed. |
| `commerce.payout.failed` | A payout is declined, and its rows return to your balance. |
| `commerce.payout.canceled` | Our staff cancel a payout, and its rows return to your balance. |

`data` holds the payout's `id`, `currency_code`, `amount`, `platform_fee`, `net_amount`, `status`, `payout_method` and `entry_count`. `livemode` is always `true`, because test orders are never paid out. The payouts for your organization's billing send `payout.created` instead, without the `commerce.` prefix.

## Download the tax report

`GET /commerce/tax-reports` totals the tax the Coritan companies charged on your store's sales, from the invoices and credit notes they issued. The company that sold each order accounts for its tax, and the report shows what each one charged, for your own accounts.

| Parameter | Takes |
| --- | --- |
| `from` | The first day, included, as a date such as `2026-07-01` or an ISO date and time. Required. |
| `to` | The first day after the report, excluded, in the same form. Required. |
| `bucket` | `month`, the default, `quarter`, or `period` for one set of rows over the whole report |
| `seller_entity_key` | One Coritan company, by the `seller_entity_key` that orders and the report's rows show |
| `country_code`, `subdivision_code` | A country, such as `US`, and a state or province in it, such as `CA` |
| `format` | `json`, the default, or `csv` |

```bash
curl "https://api.coritan.com/api/v1/orgs/acme/commerce/tax-reports?from=2026-07-01&to=2026-10-01&bucket=quarter&format=csv" \
  -H "X-API-Key: $ORG_API_KEY" \
  -o tax-report.csv
```

Dates are in UTC, and a report covers up to 400 days. Each invoice and credit note counts in the period it was issued in: an invoice adds to the tax charged, and a credit note to the tax credited. Test orders never count.

Each row is one Coritan company, period, place, tax code, rate and currency. The place is where the tax is owed: a country, a state or province, and a postal prefix. Sales that owed no tax appear too, placed at the order's shipping address, or at its billing address when it has none. A line taxed by two places, such as a state and a county, counts under each.

| Column | What it holds |
| --- | --- |
| `period_start`, `period_end` | The month, quarter or whole report, cut to your `from` and `to` |
| `seller_entity_key` | The Coritan company that charged the tax |
| `country_code`, `subdivision_code`, `postal_prefix`, `jurisdiction_name` | Where the tax is owed |
| `tax_code`, `tax_name`, `tax_rate` | The tax, with its rate as a fraction such as `0.19` |
| `currency_code` | The currency of the row's amounts |
| `taxable_base`, `taxable_credited`, `net_taxable_base` | The amount taxed on invoices, the amount credited back, and the difference |
| `tax_charged`, `tax_credited`, `net_tax` | The tax on invoices, the tax credited back, and the difference |
| `order_count`, `invoice_count`, `credit_note_count` | How many orders, invoices and credit notes the row counts |

The JSON answer has the `rows`, their `columns` in order, and `totals` for each Coritan company and currency. A total counts each taxed amount once, however many places taxed it, and its tax is the sum of its rows. Amounts are in minor units, and we never convert them or add them across currencies.

With `format=csv`, the answer is a file named like `tax-report-acme-2026-07-01-2026-10-01.csv`. It has a header line and one line per row, without the totals, and its amounts are in the currency's main unit, such as `19.99`. We put a `'` in front of any text that a spreadsheet would read as a formula.

## Result

Each payout appears in `GET /commerce/payouts`, and the rows it pays in `GET /commerce/payouts/{payout_id}`. Once our staff have sent it, it is `completed`, and `commerce.payout.paid` reaches your webhooks.

## Troubleshooting

`409` with `nothing_payable`
: Refunds and chargebacks have taken the balance to zero or below, or no sale has become available yet. Later sales cover the debt first.

`409` with `below_minimum`
: The payable amount is below the `minimum` for the currency. Ask again once more sales have become available.

`409` with `payout_open`
: A payout in this currency is waiting to be sent. The list's `summary` names it in `open_payout_id`.

`409` with `held`
: The store is suspended, or its merchant profile is not approved. `GET /commerce/store` shows the store's `status` and the profile's status under `merchant`.

`409` with `too_large`
: The payout is larger than one payout can hold, and our staff split it by hand. Ask [support](https://www.coritan.com/dashboard/support).

`403` with `people_only`
: No API key can ask for a payout. Ask with an owner's or admin's token.

`429` with `rate_limited`
: The organization asked for more than 10 payouts in an hour. Wait for the time in `Retry-After`.

`422` from the tax report
: `from` or `to` is missing or is not a date, `to` does not come after `from`, or the report is longer than 400 days. The `message` says which.

A payout stays `processing` with `outcome_unknown`
: The provider did not answer when we sent it. Our staff check with the provider, then complete the payout, or cancel it and return its rows to your balance.

## Related

- [Sell with the Commerce API](/organizations/storefront/commerce-api/)
- [Answer disputes on store orders](/organizations/storefront/commerce-disputes/)
- [Track your payouts](/organizations/billing/payouts/)
- [Receive organization webhooks](/organizations/webhooks/)

## API

- `GET /api/v1/orgs/{org_slug}/commerce/payouts`: List payouts (https://docs.coritan.com/api/reference/organizations/billing-payouts/commerce/#op-get-api-v1-orgs-org-slug-commerce-payouts)
- `POST /api/v1/orgs/{org_slug}/commerce/payouts`: Ask for the payable balance in a currency now (https://docs.coritan.com/api/reference/organizations/billing-payouts/commerce/#op-post-api-v1-orgs-org-slug-commerce-payouts)
- `GET /api/v1/orgs/{org_slug}/commerce/payouts/{payout_id}`: The payout and the ledger rows it holds, oldest first (https://docs.coritan.com/api/reference/organizations/billing-payouts/commerce/#op-get-api-v1-orgs-org-slug-commerce-payouts-payout-id)
- `GET /api/v1/orgs/{org_slug}/commerce/tax-reports`: Tax report (https://docs.coritan.com/api/reference/organizations/commerce/commerce/#op-get-api-v1-orgs-org-slug-commerce-tax-reports)
