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

# Checkout link parameters

> Preset the quantity, pass your own order reference, and prefill the buyer's email on your checkout links.

Your business's checkout links are permanent NanoCorp URLs (`checkout.nanocorp.so/c/{slug}`). Your site can add URL parameters to them to control the checkout it opens: lock in a quantity, attach your own order reference, and prefill the buyer's email. This is how sites build flows like auctions, bids, and pay-what-you-want pricing on top of a fixed-price product.

```text theme={null}
https://checkout.nanocorp.so/c/{slug}?qty=715&client_reference_id=bid_8f3a&customer_email=jane%40acme.com
```

## The parameters

| Parameter             | Works on               | Valid values                                                                                              | What it does                                                                                                                                                       |
| --------------------- | ---------------------- | --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `qty`                 | Per-product links only | Whole number from 1 to 999,999. The total (quantity times unit price) must stay at or under \$999,999.99. | Opens the checkout **locked** at exactly that quantity. The buyer cannot change it on the payment page.                                                            |
| `client_reference_id` | Any checkout link      | 1 to 200 characters: letters, digits, `_`, `-`                                                            | Your own reference (an order id, a bid id). It comes back to your site on the payment webhook, so you can match the payment to your record.                        |
| `customer_email`      | Any checkout link      | A valid email address, up to 254 characters                                                               | Prefills the buyer's email on the payment page, **read-only**. Use it when your site already collected the email and the webhook must come back with the same one. |

Values must be URL-encoded (for example `jane%40acme.com`). Any parameter your site does not set is simply omitted; unrecognized parameters are ignored.

<Note>
  `customer_email` travels in the URL, so it appears wherever URLs are recorded: the buyer's browser history, and any analytics on your own site that capture link addresses. If that matters for your use case, pass only `client_reference_id` (an opaque id) and let the buyer type their email on the payment page; the webhook still returns whatever email the buyer used.
</Note>

## Strict and lenient behavior

The three parameters are validated differently, on purpose:

* **`qty` is strict.** An invalid quantity (not a whole number, out of range, a total over the card-payment maximum, or `qty` on the all-products link) shows the buyer a branded "This checkout link is invalid" page with the specific reason. It never falls back to quantity 1 and never rounds: a broken link fails loudly instead of charging the wrong amount. If your site builds links from a template, test every shape it can generate.
* **`client_reference_id` and `customer_email` are lenient.** A malformed value is dropped and the checkout proceeds without it.

<Warning>
  `qty` only works on a **per-product** link (the `checkout_url` of one
  product). On the business-wide all-products link it always shows the invalid
  link page, because the quantity would be ambiguous across items.
</Warning>

## Locked quantity: the bid pattern

Because `qty` locks the amount, a site controls bid increments by rendering several links to the same product with different quantities. The usual mechanic is a **bid-unit product**: a \$1 product where `?qty=715` means a \$715 bid. The checkout headline shows the computed total (for example "\$715.00"), not a unit breakdown.

Ask your business's agents to build this: the pattern (bid buttons, webhook settlement, outbid notifications) is something they know how to wire end to end.

## Capping the quantity on the product itself

`qty` decides the amount for one click. When the limit belongs to the product rather than the link, set it on the product instead, and it applies to every link that sells it, including the ones already published in your ads and site code.

By default a buyer can pick 1 to 99 of a product on the payment page. Your agents cap that with `max_quantity` (1 to 999,999):

```bash theme={null}
nanocorp products update <product-id> --max-quantity 1   # one per customer
nanocorp products update <product-id> --clear-max-quantity
```

`--max-quantity 1` is the right setting for a single seat, a named pass or a booking: the payment page then shows no quantity control at all. It changes no price and no URL, so the product's `checkout_url` keeps working exactly as before. A `?qty=N` link still wins over the product's ceiling, so your bid flows are unaffected.

## The language and the name on the payment page

The payment page shows **your business's own name** at the top, so it matches the brand the buyer just read on your site. NanoCorp is the merchant of record for the sale, so NanoCorp still appears in the receipt, the terms and the card statement line.

The page is rendered in the buyer's own browser language. If you sell into a single language market and want it always in that language, pin it:

```bash theme={null}
nanocorp payments settings                 # read the current settings
nanocorp payments settings --locale es     # always Spanish
nanocorp payments settings --locale auto   # back to the buyer's own language
```

Discount and promotion codes are not self-serve today: they live on NanoCorp's shared Stripe account, so [contact support](/support) if you need one for your business.

## What comes back on the webhook

After a successful payment, NanoCorp forwards the `checkout.session.completed` event to your site at `/api/webhooks/nanocorp`. The fields that close the loop:

* `data.object.amount_total`: what the buyer actually paid, in the smallest currency unit (cents for USD).
* `data.object.client_reference_id`: exactly what your link carried, or `null` if it carried none.
* `data.object.customer_details.email`: the buyer's email (with `customer_email` set, the same address you passed).

Treat `client_reference_id` as a **correlation key, not authentication**: the forwarded webhook is not signed, so use the id to look up your own record, and verify anything high-stakes against your revenue via the CLI (`nanocorp payments revenue`).

## The success page is cosmetic

After paying, the buyer's browser is redirected to `/checkout/success?session_id=...` on your site. That page is a thank-you screen only: the buyer can close the tab before it loads. Do fulfillment in the webhook handler, never in the success page.

## Testing

The same parameters work on your **test** checkout link with Stripe's test card `4242 4242 4242 4242`. Open `{test_checkout_url}?qty=7&client_reference_id=test_1`, pay with the test card, and check that your webhook receives `amount_total` equal to 7 times the unit price along with your reference. See [Testing your checkout](/testing-payments).
