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

# How Delivery Works

> How Join Markt fulfills digital goods after payment settles.

Join Markt separates **payment settlement** from **fulfillment**. Gateways mark an order paid; fulfillment then assigns stock, exposes downloads, or waits for a seller to finish a manual step.

## Delivery method types

Configured per product (and optionally per variant) in the dashboard. Canonical values in `lib/domains/products/delivery.ts`:

| Type                    | Buyer receives                                                |
| ----------------------- | ------------------------------------------------------------- |
| `license_key`           | Keys from the store’s unused `ProductKey` pool                |
| `download_file`         | File URLs configured on the product                           |
| `delivery_instructions` | Text instructions after payment                               |
| `custom_fields`         | Values collected at checkout, returned in delivery payload    |
| `manual_delivery`       | Seller completes fulfillment outside automatic key assignment |

A product can enable **more than one** method. License-key products need unused stock before they can complete automatically.

## Lifecycle

1. Buyer pays through a gateway (or test payment).
2. Webhook / verify path calls `completeOrderFromGateway`.
3. Order status moves to `paid` (and often `completed` once fulfillment finishes).
4. If keys are required and available, `fulfillOrderWithKey` assigns the next unused key and links it to the order.
5. If key assignment fails, the order can remain `paid` without `completed` — buyer still sees a paid invoice; seller restocks and retries.

## Buyer retrieval

| Endpoint                                     | Purpose                                     |
| -------------------------------------------- | ------------------------------------------- |
| `GET /api/orders/{orderId}/delivery`         | Structured delivery payload for checkout UI |
| `GET /api/orders/{orderId}/keys`             | License keys for a completed order          |
| `POST /api/orders/{orderId}/try-assign-keys` | Retry assignment from checkout              |

Access is gated by checkout token, matching customer email, or staff `viewOrders` — not a public anonymous dump.

Legacy storefront path `/receive-items?orderId=` redirects into unified checkout.

## What integrators should know

* Embed and checkout start create **draft / processing** orders; delivery content appears only after settlement.
* Do not scrape keys from dashboard HTML. Use the delivery endpoints with a valid checkout session.
* Manual delivery and custom fields are first-class — do not assume every paid order yields a license key string.

See also: [Order status](/api/order-status), [Create embed checkout](/api/embed-checkout).
