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-sessionsAuthorization: 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:
Amounts
Section titled “Amounts”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.
Saved payment methods
Section titled “Saved payment methods”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:
| Value | Meaning |
|---|---|
off | Never prompt to save |
on_session | Save for future customer-present payments (wallet) |
off_session | Save for merchant-initiated payments (autopay) |
Redirect URLs
Section titled “Redirect URLs”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.
Response
Section titled “Response”{ "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_urlas-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 inReferer, and is dropped when the page redirects to yoursuccess_url. - Embedding? Hand
session_idandclient_secretto<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.
Updating and expiring
Section titled “Updating and expiring”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.