Skip to content

Create a hosted session

A hosted session is created server-side with your Cognito admin token and represents one payment attempt. It expires (default 30 minutes), can be completed exactly once, and carries everything the checkout UI needs. Identify the payment account with the X-Payment-Account-Uid header.

POST /v1/hosted-sessions
Authorization: Bearer <cognito-access-token>
X-Payment-Account-Uid: {accountUid}
{
"amount": 14227,
"currency": "USD",
"description": "Utility bill — account #4471",
"customer_id": "cus_88420",
"customer_email": "alex@example.com",
"success_url": "https://yoursite.example/receipt?session_id={CHECKOUT_SESSION_ID}",
"cancel_url": "https://yoursite.example/billing",
"layout": "embedded",
"allowed_methods": ["card", "ach", "apple_pay"],
"setup_future_usage": "on_session",
"expires_in_seconds": 1800,
"required_avs_fields": ["cardholder", "zip"],
"metadata": { "invoice": "INV-2026-0611" }
}

The full schema (line items, branding overrides, fraud signals) is in the API reference. Highlights:

amount is in minor units (cents): 14227 = $142.27. Convenience fees are computed server-side by the fee engine and quoted to the customer before they confirm — never add fees to amount yourself.

Pass customer_id and the checkout offers that customer’s saved cards and bank accounts (sanitized — brand and last4 only). Combine with setup_future_usage to offer saving the method being used:

ValueMeaning
offNever prompt to save
on_sessionSave for future customer-present payments (wallet)
off_sessionSave for merchant-initiated payments (autopay)

success_url and cancel_url are required. The literal token {CHECKOUT_SESSION_ID} is replaced with the session id, and the success redirect is signed so your receipt page can validate it wasn’t forged — still confirm fulfillment via webhook, not the redirect.

{
"session_id": "cs_3oNkLp9aBcDeFgHi",
"client_secret": "cs_secret_…",
"expires_at": "2026-06-11T18:30:00Z",
"hosted_url": "https://checkout.govifi.io/cs_3oNkLp9aBcDeFgHi#cs=cs_3oNkLp9aBcDeFgHi_secret_…",
"embed_url": "https://checkout.govifi.io/embed/cs_3oNkLp9aBcDeFgHi"
}

The client_secret is the session credential: there is no publishable key, and the component sends client_secret as Authorization: Bearer … on every call it makes (read config, quote fee, challenge, confirm). It is not single-use — it authenticates the chatty browser reads and the confirm. It expires with the session.

  • Redirecting? Send the customer to hosted_url as-is — the session credential rides in the URL fragment (#cs=…), so the hosted page authenticates without any extra wiring. The fragment isn’t sent to servers or in Referer, and is dropped when the page redirects to your success_url.
  • Embedding? Hand session_id and client_secret to <govifi-payment> — see Embed the component.

Confirm is single-use; retries are idempotent

Section titled “Confirm is single-use; retries are idempotent”

A session completes exactly once. Completion is enforced server-side by the session state machine (an atomic active → completed claim) plus a duplicate-payment guard — not by the credential. Once a confirm succeeds the session is done; a later confirm returns 409 already_confirmed.

To make a confirm retry safe (e.g. after a network blip), send an Idempotency-Key request header on confirm. A retry carrying the same key returns the original result instead of re-charging or erroring. The component does this for you; you only need it for direct API calls.

  • PATCH /v1/hosted-sessions/{id} — adjust the amount or line items before the customer pays (e.g. cart changed).
  • POST /v1/hosted-sessions/{id}/expire — cancel a session early.