Checkout Sessions

A Checkout Session is a hosted (or embedded) payment page for one purchase. You create it server-side with line items and redirect URLs, send the customer to url (or mount embed_url with hlhunt-checkout.js), and HL Hunt collects the card. Lifecycle: status open → complete (payment_status unpaid → paid) when the customer pays, or open → expired when expires_at passes (checked every five minutes). Three failed card attempts also end the session. In mode payment the completed session always has a customer_id (found by email or created), the card is stored on that customer, payment_method.saved is emitted, and payment_instrument_id is a saved payment method you can charge again off-session with POST /v1/charges (source = payment_instrument_id). mode subscription additionally creates the Subscription and charges its first cycle.

POST
/v1/checkout/sessions

Create a Checkout Session

Create a session and get back its hosted url. Secret key. Limited to 20 creations per minute per key (429 rate_limit_exceeded).

Request body

FieldTypeRequiredDescription
success_urlstringrequiredWhere the customer lands after paying. {CHECKOUT_SESSION_ID} in the URL is replaced by the session_key.
cancel_urlstringoptionalWhere the Cancel link points.
line_itemsarrayrequired1–50 items of { description, amount (cents, ≥ 0), quantity, product_id, price_id, image_url }. In mode subscription every item needs a price_id of a recurring Price.
modestringoptional"payment" (default) or "subscription".
currencystringoptionalDefault USD.
customer_emailstringoptionalPre-fills the email and is used to find or create the Customer on completion.
collect_address / collect_phonebooleanoptionalAsk for a billing address / phone on the page.
expires_in_minutesintegeroptionalDefault 30, maximum 1440 (24 h).
metadataobjectoptionalYour keys. Returned on the session, carried on checkout.session.* webhooks and copied onto the resulting charge's metadata (values stringified). Keys starting with _ are reserved and stripped from public views.
brandingobjectoptional{ brand_color, logo_url, header_text, button_text, success_message, thank_you_title, bg_style, font_style } overrides for this session.
allow_custom_amountbooleanoptionalLet the customer edit the amount on the page.
minimum_amount_centsintegeroptionalFloor for an editable amount. Default 50.

Response

FieldTypeDescription
idstringSession id (c… record id).
objectstring"checkout.session".
session_keystringcs_… key; also accepted by GET /v1/checkout/sessions/{id}.
urlstringHosted checkout page: https://payments.hlhunt.org/checkout/{session_key}.
embed_urlstringEmbedded checkout page for an iframe or hlhunt-checkout.js: https://payments.hlhunt.org/embed/checkout/{session_key}.
statusstringopen, complete or expired.
payment_statusstringunpaid or paid.
mode / currency / amount_total / amount_subtotalAs created; amount_total reflects a customer-edited amount after completion.
success_url / cancel_urlstring | nullAs created (placeholder resolved).
customer_idstring | nullSet on completion.
customer_email / customer_name / customer_phonestring | nullWhat the customer entered.
collect_address / collect_phone / allow_custom_amount / minimum_amount_centsAs created.
transaction_idstring | nullThe charge id once paid. Use it with GET /v1/charges/{id} and POST /v1/refunds.
payment_instrument_idstring | nullThe saved payment method once paid: a valid source for POST /v1/charges.
completed_at / expires_at / created_atstring | nullISO 8601.
metadataobject | nullYour metadata.
brandingobjectEffective branding fields.
line_itemsobject{ object: "list", data: [{ id, object: "line_item", description, amount, quantity, product_id, price_id, image_url }] }.
  • HTTP 201. 400 missing_required_param (success_url, line_items, line_items.price_id in subscription mode) · 400 invalid_param (mode) · 400 missing_line_items / too_many_line_items / other validation codes from the service · 429 rate_limit_exceeded.
  • Webhooks: checkout.session.completed (carries transaction_id, customer_id, payment_instrument_id, payment_method, metadata) and checkout.session.expired. The charge itself also emits charge.succeeded.
curl -X POST https://api.hlhunt.org/v1/checkout/sessions \
  -H "Authorization: Bearer sk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "success_url": "https://example.com/success?session={CHECKOUT_SESSION_ID}",
    "cancel_url": "https://example.com/cancel",
    "line_items": [
      { "description": "Pro Plan", "amount": 5000, "quantity": 1 }
    ],
    "customer_email": "jenny@example.com",
    "metadata": { "order_id": "1234" }
  }'
GET
/v1/checkout/sessions/{session_id}

Retrieve a Checkout Session

Fetch a session by id or by session_key (cs_…). Poll this after the customer returns to success_url, or rely on checkout.session.completed.

Parameters

FieldTypeRequiredDescription
session_idstring (path)requiredSession id or cs_… session key.

Response

FieldTypeDescription
(session object)Same shape as the create response, with status, payment_status, customer_id, transaction_id and payment_instrument_id filled in once paid.
  • 404 not_found when unknown or owned by another business.
curl -X GET https://api.hlhunt.org/v1/checkout/sessions/cs_xxxxxxxxxxxx \
  -H "Authorization: Bearer sk_live_your_api_key"
GET
/v1/checkout/sessions

List Checkout Sessions

Paginated list of sessions for the key's business.

Parameters

FieldTypeRequiredDescription
statusstring (query)optionalopen, complete or expired (case-insensitive).
limitinteger (query)optionalDefault 25.
offsetinteger (query)optionalDefault 0.

Response

FieldTypeDescription
object / data / total / has_moredata holds full session objects.
curl -X GET "https://api.hlhunt.org/v1/checkout/sessions?limit=20&status=open" \
  -H "Authorization: Bearer sk_live_your_api_key"