# Show payment terms

A rental may sell one car type on more than one payment term, such as "Pay now, non-refundable", "Pay now, refundable" for a little more, or "Pay on arrival". This page shows how to draw that choice on your own site.

A payment term has two parts:

- `refundable`: false keeps what was paid when the customer cancels. True gives the rental's free cancel.
- `confirmationBp`: the share of the total paid at booking, in basis points. 10000 is full payment, 2000 is a 20% confirmation, 0 is pay on arrival. The rest is paid at pickup.

The rental decides what it sells on Settings · Payment methods, and prices each term with price rules. A rental that sells one term gives one term, and your page shows no choice.

## 1. Get the terms

Every quote lists the terms the rental sells, cheapest first:

```
POST /rentals/{slug}/quotes
```

```json
{
  "carTypeId": "…",
  "pickupAt": "2026-12-19T12:00",
  "returnAt": "2026-12-22T12:00",
  "pickupLocationId": "…",
  "returnLocationId": "…",
  "locale": "en"
}
```

```json
{
  "data": {
    "totalMinor": 6946200,
    "payNowMinor": 6946200,
    "refundable": true,
    "confirmationBp": 10000,
    "terms": [
      {
        "refundable": false,
        "confirmationBp": 10000,
        "title": "Pay now · non-refundable",
        "summary": "What you pay is not refunded. Changes until 22 Dec 12:00.",
        "freeCancelUntil": null,
        "changesUntil": "2026-12-22T12:00",
        "totalMinor": 6946200,
        "payNowMinor": 6946200,
        "payOnArrivalMinor": 0,
        "differenceMinor": 0
      },
      {
        "refundable": true,
        "confirmationBp": 10000,
        "title": "Pay now · refundable",
        "summary": "Free cancel until 17 Dec 12:00.",
        "freeCancelUntil": "2026-12-17T12:00",
        "changesUntil": "2026-12-22T12:00",
        "totalMinor": 7123300,
        "payNowMinor": 7123300,
        "payOnArrivalMinor": 0,
        "differenceMinor": 177100
      }
    ]
  }
}
```

`POST /quotes` gives the same `terms` on each quote, so one call fills a list of car types. `locale` sets the language of `title` and `summary`: en, is, de, fr, es or it.

## 2. Draw the choice

One radio for each term. A layout that works:

```
◉ Pay now · non-refundable          Included
  What you pay is not refunded. Changes until 22 Dec 12:00.
○ Pay now · refundable              + 1,771 kr
○ Pay on arrival                    + 3,541 kr
Price for 3 days                    69,462 kr
```

- Show "Included" where `differenceMinor` is 0, and "+ amount" for the others.
- Show the `summary` under the picked term. Or write your own words from `freeCancelUntil`, `changesUntil` and `confirmationBp`.
- Show the picked term's `totalMinor` as the price, and its `payNowMinor` on the Pay button.
- In a car type list, show the first term's total: it is the cheapest.

## 3. Price and book the picked term

Send the picked term's `refundable` and `confirmationBp` on the next quote, the hold and the booking. The answer then prices that term, and the booking keeps it.

```json
{ "carTypeId": "…", "refundable": true, "confirmationBp": 10000 }
```

A term the rental does not sell is refused with `422 term_not_sold`. That is a share under the rental's own, or non-refundable while the rental sells only refundable.

## 4. Pay on arrival

A term with `confirmationBp` 0 has `payNowMinor` 0. There is nothing to pay, so a website books the hold with no payment:

```
POST /rentals/{slug}/holds/{id}/book
```

The answer is the hold, `booked`, with its booking. A hold with money to pay is refused with `409 to_pay`: ask for its payment with `POST /rentals/{slug}/holds/{id}/payments`.

## The booking widget

The widget does all of this. `<mellow-payment-terms>` shows the terms on a car type's details, and the hold takes the pick. See [Elements](/widget/elements).
