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

# Checkout and refunds

> Itemised checkouts by your own reference, allow-listed redirects, and refunds by line.

## Create an itemised checkout

`POST /v1/checkout`. Partners must send an `Idempotency-Key`.

```json theme={null}
{
  "email": "guest@example.com",
  "amount": 125000,
  "currency": "NGN",
  "partner_reference": "SL-BOOKING-77",
  "line_items": [
    { "name": "Night (Lekki 2-bed)", "quantity": 2, "unit_amount": 55000, "partner_line_reference": "night" },
    { "name": "Cleaning", "quantity": 1, "unit_amount": 15000, "partner_line_reference": "cleaning" }
  ],
  "success_url": "https://book.example.com/paid",
  "cancel_url": "https://book.example.com/cancelled",
  "fee_bearer": "customer"
}
```

**`line_items`** are optional. When you send them, they must follow these rules, or the request is refused with `400` `line_items_invalid`:

* The sum of quantity × `unit_amount` must equal `amount` exactly, to the kobo.
* `quantity` must be between 1 and 10,000.
* Amounts have at most 2 decimals.
* Each line needs a non-empty `partner_line_reference` that is unique within the checkout.
* There can be at most 100 lines.

**`success_url` and `cancel_url`** must be `https` on a host Platnova has registered for you. Subdomains count. Any other URL is refused with `400` `redirect_url_not_allowed`. Send us your hosts to register them.

The answer is the checkout, including `id`, `url` (`https://pay.platnova.com/<id>`), `status`, `partner_reference`, `line_items` and `payment_options`. Send the payer to `url`.

## Read a checkout

* `GET /v1/checkout/{checkout_id}`: public. Includes `partner_reference`, `line_items` and `status`.
* `GET /v1/partner/checkouts/{partner_reference}`: needs your API key. `object_ref` is the checkout id; `status` is `created` or `paid`.

When the payment lands you get the `checkout.paid` webhook. It carries `partner_reference` and `line_items`.

## Refund by line

`POST /v1/checkout/{checkout_id}/refund`. You can pass the checkout id or the payment reference.

```json theme={null}
{
  "reason": "Guest cancelled night 2",
  "idempotency_key": "SL-RF-9",
  "partner_reference": "SL-REFUND-9",
  "lines": [ { "partner_line_reference": "night", "amount": 55000 } ]
}
```

* **The amount is the sum of `lines`.** `amount` is optional; if you send it, it must agree with that sum.
* **Partner refunds must state `amount` or `lines`,** and they count against your refund limits.
* **A line can never be refunded beyond what it was paid,** less earlier refunds that did not fail. The check runs under a lock, so two refunds sent at the same moment cannot overspend a line.

| Refusal | When |
| - | - |
| `422` `line_amount_exceeds_refundable` | The line has less left to refund. `data` has `partner_line_reference` and `refundable`. |
| `422` `refund_line_invalid` | Unknown or repeated `partner_line_reference`. |
| `422` `refund_lines_unavailable` | The checkout was created without lines. |
| `422` `amount_exceeds_refundable` | More than what is left of the whole payment. |

**A refund by bank transfer is a payout, and its fee follows the payout minimum.** Bank transfer, Pay with Bank, USSD and OPay refunds are paid out to a bank account. Their payout fee is charged to your wallet and is never below the transfer's cost: the greater of cost + 3% and cost + ₦50, plus VAT (see [Payouts: fees](/partners/payouts.md#fees-never-below-what-the-transfer-costs)). The refunded amount itself is never more than the payment was.

The refund carries `lines` and `partner_reference`. Its webhooks are `checkout.refunded` and `checkout.refund_failed`, and they also carry `checkout_partner_reference`.


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