---
title: "Create a testing order checkout link"
method: POST
path: "/testing/checkout"
tags: ["Testing orders"]
---

# Create a testing order checkout link

`POST /testing/checkout`

## Request

- Base URL: `https://www.laboratory.love/api/v1`
- URL: `https://www.laboratory.love/api/v1/testing/checkout`
- Auth: none required

Write — starts a purchase; treat as sensitive and confirm the package, total price, and product links with the person first. Saves a pending order with the submitted product links and creates a secure Stripe-hosted checkout page for it. This call charges nothing and takes no card details: the person must open `checkout_url` and pay; an unpaid order is never processed. Use an Idempotency-Key when retrying.

## Headers

- `Idempotency-Key` string

## Request body

- TestingCheckoutRequest: Testing order request.
  - `tier` 'single' | 'kitchen' | 'pantry', required: Tier id from GET /testing/tiers.
  - `products` object[], required: Between 1 and the package’s product count.
    - `url` string, uri, required: Public http(s) product page.
    - `notes` string: Optional size/variant hint.

## Response `201`

Checkout created; awaiting the person’s payment.

- TestingCheckout: A created testing checkout.
  - `checkout_id` string, required: Checkout id for GET /checkouts/{checkout_id}.
  - `checkout_url` string, uri, required: Secure Stripe-hosted payment page for the person to open.
  - `status` 'awaiting_user_payment', required: Always awaiting_user_payment on creation.
  - `requires_user_completion` boolean, required: Always true.
  - `amount` number, required: USD.
  - `currency` 'USD', required: Currency.
  - `expires_at` string, date-time, nullable, required: When checkout_url stops working.
  - `tier` TestingTier, required: A direct testing package.
    - `id` 'single' | 'kitchen' | 'pantry', required: Tier id.
    - `name` string, required: Name.
    - `price` number, required: Total price, USD.
    - `currency` 'USD', required: Currency.
    - `products_included` integer, required: Products you may submit.
    - `samples_per_product` integer, required: Retail samples tested per product.
    - `lab_tests_total` integer, required: Total lab tests.
    - `panels` string[], required: Chemical panels.
    - `best_for` string, nullable, required: Who it suits.
  - `products_submitted` object[], required: Products saved with the order.
    - `url` string, required: URL.
    - `notes` string, required: Notes (may be empty).
  - `terms` TestingTerms, required: Terms to show before a person orders testing.
    - `seller` string, required: Merchant of record.
    - `turnaround` string, required: Expected timing.
    - `refund_policy` string, required: Refund rules.
    - `publication` string, required: Whether results are published.
    - `terms_url` string, uri, required: Full terms.
  - `next_step` string, required: What to do next.

## Other responses

- `400`: Invalid input. `error.code` says which rule failed.
- `413`: Request body too large.
- `415`: Body is not JSON.
- `429`: Rate limited. Wait `Retry-After` seconds.
- `502`: The payment provider failed. Nothing was charged.
- `503`: Data source temporarily unavailable. Retry shortly.

---

[API](https://skmtc.dev/laboratory/apis/laboratory-love-api.md) · [All operations](https://skmtc.dev/laboratory/apis/laboratory-love-api/llms.txt) · [OpenAPI document](https://skmtc.dev/laboratory/apis/laboratory-love-api/revisions/ca2b4c069ad5?raw)
