Dynamic Hosted Checkout
Dynamic Hosted Checkout lets you send shoppers to a fully hosted Altruon checkout page with cart and customer data defined at runtime via the Create Session API. Use this when each checkout is unique (plan, customer, coupons) and created from your backend — for example when replacing Stripe Billing Hosted Pages with Altruon + your billing platform.
Prerequisite: Complete steps 1–4 of the Quick Start: connected payment gateway routing and a billing platform. Configure checkout appearance once under Settings → Checkout (same as Hosted Pages).
/checkout/p/ vs /checkout/s/
Static hosted page (/checkout/p/{id}) | Dynamic hosted checkout (/checkout/s/{sessionId}) | |
|---|---|---|
| Setup | Created in backoffice (Settings → Hosted Pages) | Created via Create Session API from your backend |
| Cart & customer | Fixed per link (editable in backoffice) | Passed in each API call |
| URL | Opaque config UUID | Session UUID from API response |
| Conversion analytics | Per-link stats in backoffice | Not tracked in Hosted Pages (no static config) |
| Session expiry | Shopper can restart from the same link | Merchant must create a new session |
| Branding | Site checkout config (Classic/Neo skin) | Same site checkout config |
| Customer pre-fill | No — shopper enters all details | Yes — from customerData in Create Session |
Use /checkout/p/ for marketing links, campaigns, and backoffice-managed carts with analytics.
Use /checkout/s/ when your server already knows the plan, customer, and context (CRM, game launcher, subscription upgrade flow, etc.).
Flow
- Your backend calls
POST /api/session/v1/createwithhostedCheckout: true, billing line items, optional customer data, andredirectUrl. - Altruon returns
session_id,checkout_url, andexpires_at. - Redirect the shopper to
checkout_url(or buildhttps://{tenant}.sandbox.altruon.io/checkout/s/{sessionId}). - Altruon renders your branded hosted checkout with fields pre-filled from the session.
- On success, the shopper is redirected to
redirectUrl(or your site checkout redirect URL).
Sessions expire after 15 minutes. Expired dynamic sessions cannot be restarted from the checkout page — create a new session from your backend.
Create Session example
{
"hostedCheckout": true,
"paymentData": {
"currency": "BRL"
},
"billingData": {
"billingPlatformId": "3287b8c7-ce43-41fd-9d58-f510e610b8f3",
"lineItems": [
{
"type": "plan",
"id": "price_1SMtJj4hYau76GhIakR22BKu",
"quantity": 1
}
],
"couponCodes": ["LAUNCH10"],
"metadata": {
"field_1": "value_123",
"user_id": "user_456"
}
},
"customerData": {
"firstName": "João",
"lastName": "Silva",
"email": "joao@example.com",
"phone": "+5511999999999",
"billingAddress": {
"street": "Av. Paulista",
"number": "1000",
"city": "São Paulo",
"state": "SP",
"zipCode": "01310-100",
"country": "BR"
}
},
"document": "12345678909",
"locale": "pt_br",
"redirectUrl": "https://your-site.com/subscription/success"
}
Notes:
- Omit
paymentMethodinpaymentDatafor discovery mode — the shopper picks from all routed methods for the currency (e.g. PIX + card for BRL). Pass"paymentMethod": "card"(or"pix", etc.) to show only that method. - Include
customerDatato pre-fill name, email, phone, and billing address when the shopper lands on/checkout/s/{sessionId}. See Pre-filling customer data below. - Set top-level
documentfor PagBrasil CPF/CNPJ pre-fill on PIX and card forms. - Set
localeto control checkout UI language (enorpt_br). Also acceptspt-BR,pt, anden-US. Unsupported values fall back to English. When omitted, the hosted page auto-selects from currency (BRL → Portuguese, others → English). - Pass
billingData.metadatato attach merchant key/value pairs to the subscription in your billing platform (Stripe subscription metadata, Chargebeemeta_data, etc.). Equivalent to Stripe Hosted Pagessubscription_data.metadata. - To override trial length at checkout, set
billingData.forceTrialPeriodDays. See Override trial length per checkout. hostedCheckoutmust not be combined withhostedPageConfigId.
Response
{
"session_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"expires_at": "2026-06-21T12:15:00Z",
"checkout_url": "https://your-tenant.sandbox.altruon.io/checkout/s/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"locale": "pt_br",
"payment_method_pinned_at_create": false,
"available_payment_methods": [
{
"payment_method": "pix",
"gateway": "PAGBRASIL",
"gateway_connection_id": "..."
},
{
"payment_method": "card",
"gateway": "CHECKOUTCOM",
"gateway_connection_id": "..."
}
]
}
payment_method_pinned_at_create is false in this example because no paymentMethod was sent — discovery mode. The shopper can pick any routed method, and all methods stay available if a payment fails. If you pass "paymentMethod": "card" at create, this field is true and only card is shown for the whole session. See Payment method pinning in the Session API reference.
Redirect the shopper to checkout_url to start checkout.
Checkout URL
https://{your-tenant}.altruon.io/checkout/s/{sessionId} (production)
https://{your-tenant}.sandbox.altruon.io/checkout/s/{sessionId} (sandbox)
The session UUID is the access token for that checkout. Always create sessions server-side with your secret key; never expose the secret key in the browser.
Pre-filling customer data
When you open /checkout/s/{sessionId}, Altruon loads the session created by your backend and pre-populates the checkout form with any customerData (and top-level document) you included in the Create Session call. You do not need a separate update call before redirecting the shopper.
This applies only to dynamic hosted checkout (/checkout/s/). Static hosted page links (/checkout/p/) always start with empty customer fields.
What gets pre-filled
| Create Session field | Hosted checkout field |
|---|---|
customerData.firstName | First name (main customer block) |
customerData.lastName | Last name (main customer block) |
customerData.email | |
customerData.phone | Phone |
customerData.billingAddress.street | Billing address line 1 |
customerData.billingAddress.number | Billing address line 2 |
customerData.billingAddress.city | City |
customerData.billingAddress.state | State / province |
customerData.billingAddress.zipCode | Zip / postal code |
customerData.billingAddress.country | Country |
customerData.shippingAddress.* | Shipping fields (if enabled in backoffice) |
document (top-level) | PagBrasil CPF/CNPJ on PIX and card forms |
billingData.couponCodes | Pre-applied coupons in order summary |
billingData.lineItems | Plan, addons, and pricing in order summary |
Field visibility
Only fields enabled under Settings → Checkout → Fields are shown on the page. Data for hidden fields is still stored on the session and used at payment time, but the shopper will not see those inputs.
Email and the main first/last name fields are always collected. Billing and shipping address blocks depend on your field configuration.
Tips
- Pass addresses early — include as much of
billingAddressas you already know (especiallycountryfor tax and routing). IP-based country guessing is skipped when the session already provides a country. - Billing-address names — if your checkout skin shows first/last name inside the billing address section, set
billingAddress.firstNameandbillingAddress.lastNamein the API payload (in addition to top-levelcustomerData.firstName/lastNameif needed). - Shopper can edit — pre-filled values are starting points, not locked. The shopper may change them before subscribing.
- Failed payment retry — after a 3DS or card decline, the shopper returns to the same session URL and the form is restored from the saved session data.
Minimal vs full example
Minimal (name + email only):
{
"hostedCheckout": true,
"paymentData": { "currency": "BRL" },
"billingData": {
"billingPlatformId": "3287b8c7-ce43-41fd-9d58-f510e610b8f3",
"lineItems": [{ "type": "plan", "id": "price_xxx", "quantity": 1 }]
},
"customerData": {
"firstName": "João",
"lastName": "Silva",
"email": "joao@example.com"
},
"redirectUrl": "https://your-site.com/success"
}
Full (address + document for Brazil):
{
"customerData": {
"firstName": "João",
"lastName": "Silva",
"email": "joao@example.com",
"phone": "+5511999999999",
"billingAddress": {
"street": "Av. Paulista",
"number": "1000",
"city": "São Paulo",
"state": "SP",
"zipCode": "01310-100",
"country": "BR"
}
},
"document": "12345678909"
}
Appearance and branding
Appearance (logo, colors, Classic/Neo skin, post-payment redirect URL) comes from Settings → Checkout, not from per-session styleCustomization (that is for embedded Altruon JS iframe checkout).
Failed payments (3DS / card decline)
If a card payment fails after a gateway redirect, the shopper returns to the same /checkout/s/{sessionId} URL with form data restored so they can retry within the session TTL.
Security
- Create sessions only from your backend using
x-secret-key. - Sessions are scoped to your tenant subdomain — a session created for
tenant-acannot be loaded ontenant-b. - Treat the session UUID like a single-use checkout token; share it only with the intended shopper.
Related docs
- Session API Reference — full Create Session parameters, including
customerData - Hosted Pages — static backoffice links with per-link analytics
- Altruon JS — embedded checkout on your own site