Skip to main content
Beyond the required amount, currency, order_reference, success_url, and cancel_url on create a checkout session, a checkout session accepts several optional fields to shape what the shopper sees and what you get back.
Amounts are always integers in the currency’s minor unit. For example, 5000 for SGD means SGD 50.00.

Line items and adjustments

Add an itemized breakdown with line_items[] (name, quantity, unit_amount) and optional adjustments[] (kind: tax, shipping, discount, or fee; label; signed amount). adjustments requires line_items — an adjustments-only payload is rejected, since there’s no base total for the deltas to apply to. The math is enforced: the sum of line_items amounts plus the sum of adjustments amounts must equal the session’s top-level amount, or the request is rejected with 400 validation:line_items_mismatch. Discount adjustments must be zero or negative; tax, shipping, and fee adjustments must be zero or positive. Each line_items entry must be a JSON object with a string name — a null or non-object entry, or a non-string name, returns 400 validation:invalid_input instead of a generic server error.

Shopper and billing details

Send what you know about the shopper’s billing details with billing_details — cardholder name, email, phone, and billing address. It’s shown to the shopper on the pay page and used for 3-D Secure once the hosted-checkout challenge ships (see 3DS with hosted checkout):
Every field is optional and none of them ever fail the request on their own — an invalid or over-length sub-field is dropped rather than rejected, so omit a field entirely rather than sending an empty string.
Breaking change: customer is no longer accepted. Sending it — any value, including null — returns 400 validation:invalid_input. Send billing_details instead.
If you’re embedding checkout in an iframe and it isn’t rendering after you’ve set these fields, the cause is almost always domain registration or CSP, not these fields — see Fix embedded checkout that won’t load.

Branding profile

Reference a branding profile configured for your account with branding_profile_id (optional, at most 64 characters). If you omit it, or the ID doesn’t match a configured profile, your account’s default branding applies — the request never fails because of a bad branding_profile_id. You can also override individual settings for just this checkout with a branding object. See Brand the payment page for how profiles are set up, how a checkout resolves which branding to use, and the full settings and override reference.

Locale

Set locale to one of the accepted values. Only some of the accepted locales currently render translated copy — everything else falls back to English: An unrecognized locale value is rejected outright — pick one from the accepted list even if it isn’t yet rendered.

Currency and amount

currency is a 3-letter ISO 4217 code, one of: SGD, USD, EUR, GBP, JPY, AUD, HKD, CNY, MYR, THB, IDR, PHP, VND, KRW, INR, TWD, CAD, NZD — and must also be enabled for your merchant account. It’s case-insensitive on input (upper-cased before storage). amount must be an integer in minor units and at least 50 (for example, the minimum for SGD is 50 = SGD 0.50) — smaller amounts are rejected. There’s no enforced maximum on the Checkout API itself; an excessively large amount is instead rejected by the payment gateway with 422 gateway:request_rejected.

Metadata

Attach your own key-value data with metadata. Metadata must be a JSON object. Serialized as compact JSON, it can be at most 4096 UTF-16 code units, limit included. Most characters count as 1 unit, including Chinese and Thai; emoji count as 2. A larger object is rejected with 400 validation:invalid_input — the error’s detail text may still say “under 4096 bytes”, but the limit is measured in UTF-16 code units as described here. Use it for your own order/customer references; it’s echoed back on the session but never interpreted by RadiumOne.

state and outlet_id

  • state: an opaque string (1–512 characters) you choose. It’s echoed back unchanged on your success_url/cancel_url redirects (when present) so you can carry your own request-scoped nonce through the flow. It is not part of the redirect signature — verify it independently if you rely on it.
  • outlet_id: only needed for multi-outlet merchants. Omit it to use your key’s bound outlet (or your account default). It must be a canonical UUID — a malformed value returns 400 validation:invalid_input; a well-formed value that isn’t your outlet, or isn’t bound to your key, returns 422.

Next steps

Redirect to hosted checkout

Put these fields to use in a full integration.

3DS with hosted checkout

How billing_details feeds 3D Secure.

Fix embedded checkout that won't load

Domain registration and CSP for embedded mode.
Last modified on September 15, 2026