A delivery selection records one chosen option for every required choice group in a quote. The selected price, tax treatment, window, origin, and execution legs are immutable evidence used when Flint commits checkout to the order.
Create a selection with the quote ID and each chosen option ID. Include a window ID only when the option offers windows. Replacing or clearing a selection requires the current selection ID, which prevents an older browser tab from overwriting a newer buyer choice.
The buyer can pay with a selection until its expires_at, and limiting_deadline_reason names the deadline that set it. Every selection ends by the checkout's calculation_expires_at and lasts at most 24 hours. Before that:
- A
fixed,tiered, orrate_tableprice holds for as long as the calculation does. When the cart has tracked inventory, it holds only until the quote's 5-minute stock check ends. - A
calculatedprice holds until the option'sexpires_at. Acallbackorcaller_suppliedprice holds until theselection_guarantee_expires_atyour server returned. - A method's
selection_guarantee_secondsextends a shorter hold to that many seconds after the quote was evaluated. - A chosen window ends the selection at that window's
expires_at, which for aschedule_windowmethod is the preparation lead time before the window starts.
A selection holds the cart's tracked inventory at the Locations its chosen options leave from, until it expires. To keep holding the stock after that, quote and select again.
A selection stays current while the order keeps what its delivery was priced from: the line items and their quantities, their prices and discounts, and the order's customer. A tip or a tax location set with the checkout credential, the buyer's contact, and a declined payment leave those unchanged, so the selection keeps its ID, option, price, window, and expires_at, and its quote stays active. When a tip or a tax location changes the order's tax, the tax on the delivery charge changes with it: each choice's tax_money and total_money and the selection's amount_money follow the order. With the checkout credential, applying or removing a promotion code or changing a line item's modifiers releases the selection the next time the order or checkout is read, and the order drops the delivery charge. Quote and select again before payment. A financial change to the order made with an API key, such as a new quantity, invalidates the checkout session instead, which ends its selection.
Recipient details#
Each option lists the recipient fields it asks for in recipient_requirements, such as a phone for local delivery. Send them in recipient. A selection can leave out a required field, because Apple Pay and Google Pay reveal the buyer's name and phone only after the buyer approves the payment sheet. The selection's input_requirements lists each required field it is still missing, with the same delivery_input_requirement_id the quote gave that option. It is empty when nothing is missing.
Paying the order with POST /v1/orders/{order_id}/pay fails with DELIVERY_RECIPIENT_REQUIRED while a required field is missing, before any payment is attempted. The error's remediation.missing_or_invalid_fields names every missing field, such as delivery_selection.recipient.phone. To add them, create a selection on the same quote with the same choices and the full recipient, and send the current selection's ID as expected_delivery_selection_id. On the same quote the price does not change. A value you do send is still checked when you select: a malformed email or phone returns DELIVERY_REQUEST_INVALID.
After the buyer confirms a code in the checkout, only the checkout credential that confirmation returned reads the selection's recipient, destination_address, buyer_location, and instructions. Every other checkout credential for the session gets the selection without them, because they may come from the customer's saved addresses. An API key always gets them. When a later code confirmation binds a different customer, Flint releases the selection and removes these details from the checkout's earlier quotes and selections for every caller.
The checkout route returns the effective selection while it is provisional and after it is committed. The order route exposes the committed selection for merchant reconciliation.
Routes#
For example, select a local delivery option and one of its offered_windows from a current quote, before the buyer's phone is known:
{
"delivery_quote_id": "dqt_123",
"expected_delivery_selection_id": null,
"choices": [
{
"delivery_choice_group_id": "dcgrp_123",
"delivery_option_id": "dopt_123",
"input": { "delivery_window_id": "fwin_123" }
}
],
"recipient": { "name": "Alex Kim" }
}
input accepts delivery_window_id and instructions. Send instructions only when the option's buyer_instructions.enabled is true, and always when its buyer_instructions.required is true. Omit input when the option needs neither.
The option requires a phone, so the selection reports it:
{
"delivery_selection_id": "dsel_123",
"status": "selected",
"recipient": { "name": "Alex Kim" },
"input_requirements": [
{
"delivery_input_requirement_id": "req_dc2e269c6bf08230ce8a13f7",
"purpose": "selection",
"field_path": "recipient.phone",
"delivery_choice_group_ids": ["dcgrp_123"],
"delivery_option_ids": ["dopt_123"],
"constraint": { "type": "phone", "format": "e164", "minimum_length": 8, "maximum_length": 16 }
}
]
}
Once the buyer approves and the wallet returns the phone, select again with "expected_delivery_selection_id": "dsel_123" and "recipient": { "name": "Alex Kim", "phone": "+12125550123" }, then pay.
