#!/usr/bin/env bash
# Create a tokenization session for Elements. Pass session_id/session_secret/
# pubkey_jws to the browser unchanged — never re-serialize pubkey_jws.
set -euo pipefail
API_BASE="${RADIUMONE_API_BASE:-https://api-sandbox.radiumone.io/gateway}"
: "${RADIUMONE_ACCESS_TOKEN:?set RADIUMONE_ACCESS_TOKEN to a Bearer access token}"
curl -sS -X POST "$API_BASE/v1/sessions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $RADIUMONE_ACCESS_TOKEN" \
-d @request.json#!/usr/bin/env python3
"""Create a tokenization/checkout session for Elements. Python 3.10+, requests."""
import json
import os
from pathlib import Path
import requests
API_BASE = os.environ.get("RADIUMONE_API_BASE", "https://api-sandbox.radiumone.io/gateway")
def create_payment_session() -> dict:
body = json.loads((Path(__file__).parent / "request.json").read_text())
resp = requests.post(
f"{API_BASE}/v1/sessions",
json=body,
headers={"Authorization": f"Bearer {os.environ.get('RADIUMONE_ACCESS_TOKEN', '')}"},
timeout=30,
)
payload = resp.json()
if not resp.ok:
raise RuntimeError(f"sessions create failed: {payload.get('type') or payload.get('code')} ({resp.status_code})")
# Pass session_id, session_secret and pubkey_jws to the browser byte-for-byte.
return payload
if __name__ == "__main__":
print(json.dumps(create_payment_session(), indent=2))
{
"status": "ok",
"request_id": "req_c3d4e5f6a1b2",
"data": {
"session_id": "sess_5f8a1c2e10",
"session_secret": "<opaque, pass byte-for-byte to Elements>",
"pubkey_jws": "<opaque JWS, pass byte-for-byte to Elements>",
"expires_at": "2026-09-14T10:30:00.000Z",
"status": "open",
"currency": "SGD",
"outlet_id": null,
"payment_methods": [
{
"type": "card",
"display_name": "Card",
"priority_rank": 10
}
],
"allowed_currencies": [
"SGD"
],
"three_ds_requirement": {
"status": "possible",
"mandatory": false,
"channel": "ECOMMERCE"
}
}
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>",
"request_id": "<string>",
"code": "<string>",
"retry_allowed": true,
"errors": [
{
"pointer": "<string>",
"parameter": "<string>",
"code": "<string>",
"detail": "<string>"
}
]
}{
"detail": "Missing or invalid Bearer token.",
"status": 401,
"title": "Authentication Required",
"type": "urn:radiumone:gateway:authentication-required"
}{
"detail": "Insufficient permissions for this operation.",
"status": 403,
"title": "Permission Denied",
"type": "urn:radiumone:gateway:permission-denied"
}{
"detail": "The requested resource does not exist.",
"status": 404,
"title": "Not Found",
"type": "urn:radiumone:gateway:not-found"
}{
"detail": "Your merchant account is not yet set up for card tokenization and could not be set up automatically. Retry later; contact support if the problem continues.",
"status": 409,
"title": "Merchant Not Provisioned",
"type": "urn:radiumone:gateway:merchant-not-provisioned"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>",
"request_id": "<string>",
"code": "<string>",
"retry_allowed": true,
"errors": [
{
"pointer": "<string>",
"parameter": "<string>",
"code": "<string>",
"detail": "<string>"
}
]
}{
"detail": "Too many bind attempts for this session; the session is temporarily locked. This is a lockout, not a transient error -- do not auto-retry.",
"status": 429,
"title": "Bind Rate Limit",
"type": "urn:radiumone:gateway:bind-rate-limit"
}{
"detail": "An unexpected error occurred.",
"status": 500,
"title": "Internal Server Error",
"type": "urn:radiumone:gateway:internal-server-error"
}{
"detail": "A downstream dependency is unavailable or did not respond in time.",
"status": 503,
"title": "Service Unavailable",
"type": "urn:radiumone:gateway:service-unavailable"
}Create tokenization session - Payments API
Create a tokenization session so the Elements SDK can collect card details in the browser and return a card token to your server.
#!/usr/bin/env bash
# Create a tokenization session for Elements. Pass session_id/session_secret/
# pubkey_jws to the browser unchanged — never re-serialize pubkey_jws.
set -euo pipefail
API_BASE="${RADIUMONE_API_BASE:-https://api-sandbox.radiumone.io/gateway}"
: "${RADIUMONE_ACCESS_TOKEN:?set RADIUMONE_ACCESS_TOKEN to a Bearer access token}"
curl -sS -X POST "$API_BASE/v1/sessions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $RADIUMONE_ACCESS_TOKEN" \
-d @request.json#!/usr/bin/env python3
"""Create a tokenization/checkout session for Elements. Python 3.10+, requests."""
import json
import os
from pathlib import Path
import requests
API_BASE = os.environ.get("RADIUMONE_API_BASE", "https://api-sandbox.radiumone.io/gateway")
def create_payment_session() -> dict:
body = json.loads((Path(__file__).parent / "request.json").read_text())
resp = requests.post(
f"{API_BASE}/v1/sessions",
json=body,
headers={"Authorization": f"Bearer {os.environ.get('RADIUMONE_ACCESS_TOKEN', '')}"},
timeout=30,
)
payload = resp.json()
if not resp.ok:
raise RuntimeError(f"sessions create failed: {payload.get('type') or payload.get('code')} ({resp.status_code})")
# Pass session_id, session_secret and pubkey_jws to the browser byte-for-byte.
return payload
if __name__ == "__main__":
print(json.dumps(create_payment_session(), indent=2))
{
"status": "ok",
"request_id": "req_c3d4e5f6a1b2",
"data": {
"session_id": "sess_5f8a1c2e10",
"session_secret": "<opaque, pass byte-for-byte to Elements>",
"pubkey_jws": "<opaque JWS, pass byte-for-byte to Elements>",
"expires_at": "2026-09-14T10:30:00.000Z",
"status": "open",
"currency": "SGD",
"outlet_id": null,
"payment_methods": [
{
"type": "card",
"display_name": "Card",
"priority_rank": 10
}
],
"allowed_currencies": [
"SGD"
],
"three_ds_requirement": {
"status": "possible",
"mandatory": false,
"channel": "ECOMMERCE"
}
}
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>",
"request_id": "<string>",
"code": "<string>",
"retry_allowed": true,
"errors": [
{
"pointer": "<string>",
"parameter": "<string>",
"code": "<string>",
"detail": "<string>"
}
]
}{
"detail": "Missing or invalid Bearer token.",
"status": 401,
"title": "Authentication Required",
"type": "urn:radiumone:gateway:authentication-required"
}{
"detail": "Insufficient permissions for this operation.",
"status": 403,
"title": "Permission Denied",
"type": "urn:radiumone:gateway:permission-denied"
}{
"detail": "The requested resource does not exist.",
"status": 404,
"title": "Not Found",
"type": "urn:radiumone:gateway:not-found"
}{
"detail": "Your merchant account is not yet set up for card tokenization and could not be set up automatically. Retry later; contact support if the problem continues.",
"status": 409,
"title": "Merchant Not Provisioned",
"type": "urn:radiumone:gateway:merchant-not-provisioned"
}{
"type": "<string>",
"title": "<string>",
"status": 123,
"detail": "<string>",
"instance": "<string>",
"request_id": "<string>",
"code": "<string>",
"retry_allowed": true,
"errors": [
{
"pointer": "<string>",
"parameter": "<string>",
"code": "<string>",
"detail": "<string>"
}
]
}{
"detail": "Too many bind attempts for this session; the session is temporarily locked. This is a lockout, not a transient error -- do not auto-retry.",
"status": 429,
"title": "Bind Rate Limit",
"type": "urn:radiumone:gateway:bind-rate-limit"
}{
"detail": "An unexpected error occurred.",
"status": 500,
"title": "Internal Server Error",
"type": "urn:radiumone:gateway:internal-server-error"
}{
"detail": "A downstream dependency is unavailable or did not respond in time.",
"status": 503,
"title": "Service Unavailable",
"type": "urn:radiumone:gateway:service-unavailable"
}Authorizations
Bearer access token from POST /v1/auth/token. Treat it as an opaque string — do not depend on its internal encoding, which has changed before and isn't part of the contract.
Body
Optional body for creating a checkout session.
Every field is optional. You don't send your merchant ID -- it is taken from your access token.
Amount in smallest currency unit (optional; enables amount-conditioned discovery).
x >= 0Payment-cancel redirect URL. Validated against the merchant's allowed_domains (422 on mismatch).
2048ISO 4217 currency code. When set, response includes supported payment_methods.
3^[A-Za-z]{3}$Your customer's IP address, used as a fraud signal (optional).
45Outlet UUID for discovery. Defaults to the merchant's DEFAULT outlet.
Post-payment redirect URL. Validated against the merchant's allowed_domains (422 on mismatch).
2048How long the session stays valid, in minutes (5–60). Defaults to 30.
5 <= x <= 60Your customer's browser User-Agent, used as a fraud signal (optional).
512Response
Successful Response
Standard success envelope. Every successful response has this shape, with the operation's own payload under data.
The operation's result. Its shape is documented per operation; omitted on responses that carry no payload.
Show child attributes
Show child attributes
Optional human-readable note. Omitted from the response when not set, which is the case for every payment operation today. Never parse it.
Correlation ID for this HTTP request, for logs and support. Send your own in the X-Request-Id header (letters, digits and hyphens, up to 36 characters -- other characters are stripped) or the gateway generates one. This is NOT the request_id idempotency key you send in a transaction body; the two are unrelated.
Always ok on a successful (2xx) response. Errors use a different body shape entirely (RFC 9457 problem details), so branch on the HTTP status code, not on this field.