curl -X POST \
"https://api.telzino.com/v1/organizations/123e4567-e89b-12d3-a456-426614174000/payments/onboarding" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
// Keep your Telzino access token server-side. Expose a tiny endpoint your
// front-end can call to fetch a fresh session for a given merchant org.
app.post('/onboarding/:orgId', async (req, res) => {
const r = await fetch(
`https://api.telzino.com/v1/organizations/${req.params.orgId}/payments/onboarding`,
{ method: 'POST', headers: { Authorization: `Bearer ${process.env.TELZINO_TOKEN}` } }
);
const { client_secret, publishable_key } = await r.json();
res.json({ client_secret, publishable_key });
});
import { useState } from 'react';
import { loadConnectAndInitialize } from '@stripe/connect-js';
import { ConnectComponentsProvider, ConnectAccountOnboarding } from '@stripe/react-connect-js';
export function Onboarding({ orgId }) {
const [instance, setInstance] = useState(null);
const begin = async () => {
// Fetch publishable_key + a fresh client_secret from YOUR server (above).
const first = await fetch(`/onboarding/${orgId}`, { method: 'POST' }).then((r) => r.json());
const conn = loadConnectAndInitialize({
publishableKey: first.publishable_key,
// Stripe calls this to (re)fetch a session secret on demand.
fetchClientSecret: async () =>
(await fetch(`/onboarding/${orgId}`, { method: 'POST' }).then((r) => r.json())).client_secret,
});
setInstance(conn);
};
if (!instance) return <button onClick={begin}>Set up payments</button>;
return (
<ConnectComponentsProvider connectInstance={instance}>
<ConnectAccountOnboarding onExit={() => {/* re-check status via /payments/status */}} />
</ConnectComponentsProvider>
);
}
import os, requests
def create_onboarding_session(org_id: str) -> dict:
r = requests.post(
f'https://api.telzino.com/v1/organizations/{org_id}/payments/onboarding',
headers={'Authorization': f"Bearer {os.environ['TELZINO_TOKEN']}"},
)
data = r.json()
# Return both to your front-end, which renders Stripe's embedded component.
return {'client_secret': data['client_secret'], 'publishable_key': data['publishable_key']}
{
"organization_id": "123e4567-e89b-12d3-a456-426614174000",
"client_secret": "accs_secret_1a2b3c...",
"publishable_key": "pk_live_51Ab..."
}
{
"error": "Invalid organization_id"
}
{
"error": "unauthorized",
"error_description": "User payload not found"
}
{
"error": "Forbidden",
"error_description": "You do not have access to this organization"
}
{
"error": "forbidden",
"error_description": "Card payments are not available for this organization"
}
{
"error": "Organization not found"
}
Payments
Start Merchant Onboarding
Create (or resume) a merchant’s Stripe Connect account and return an embedded onboarding session
POST
/
v1
/
organizations
/
{organization_id}
/
payments
/
onboarding
curl -X POST \
"https://api.telzino.com/v1/organizations/123e4567-e89b-12d3-a456-426614174000/payments/onboarding" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
// Keep your Telzino access token server-side. Expose a tiny endpoint your
// front-end can call to fetch a fresh session for a given merchant org.
app.post('/onboarding/:orgId', async (req, res) => {
const r = await fetch(
`https://api.telzino.com/v1/organizations/${req.params.orgId}/payments/onboarding`,
{ method: 'POST', headers: { Authorization: `Bearer ${process.env.TELZINO_TOKEN}` } }
);
const { client_secret, publishable_key } = await r.json();
res.json({ client_secret, publishable_key });
});
import { useState } from 'react';
import { loadConnectAndInitialize } from '@stripe/connect-js';
import { ConnectComponentsProvider, ConnectAccountOnboarding } from '@stripe/react-connect-js';
export function Onboarding({ orgId }) {
const [instance, setInstance] = useState(null);
const begin = async () => {
// Fetch publishable_key + a fresh client_secret from YOUR server (above).
const first = await fetch(`/onboarding/${orgId}`, { method: 'POST' }).then((r) => r.json());
const conn = loadConnectAndInitialize({
publishableKey: first.publishable_key,
// Stripe calls this to (re)fetch a session secret on demand.
fetchClientSecret: async () =>
(await fetch(`/onboarding/${orgId}`, { method: 'POST' }).then((r) => r.json())).client_secret,
});
setInstance(conn);
};
if (!instance) return <button onClick={begin}>Set up payments</button>;
return (
<ConnectComponentsProvider connectInstance={instance}>
<ConnectAccountOnboarding onExit={() => {/* re-check status via /payments/status */}} />
</ConnectComponentsProvider>
);
}
import os, requests
def create_onboarding_session(org_id: str) -> dict:
r = requests.post(
f'https://api.telzino.com/v1/organizations/{org_id}/payments/onboarding',
headers={'Authorization': f"Bearer {os.environ['TELZINO_TOKEN']}"},
)
data = r.json()
# Return both to your front-end, which renders Stripe's embedded component.
return {'client_secret': data['client_secret'], 'publishable_key': data['publishable_key']}
{
"organization_id": "123e4567-e89b-12d3-a456-426614174000",
"client_secret": "accs_secret_1a2b3c...",
"publishable_key": "pk_live_51Ab..."
}
{
"error": "Invalid organization_id"
}
{
"error": "unauthorized",
"error_description": "User payload not found"
}
{
"error": "Forbidden",
"error_description": "You do not have access to this organization"
}
{
"error": "forbidden",
"error_description": "Card payments are not available for this organization"
}
{
"error": "Organization not found"
}
Ensures the organization has a Stripe connected account — creating one on the platform if it doesn’t exist yet — and returns everything you need to run Stripe’s embedded onboarding: a Connect Account Session
You do not need a Stripe account or any Stripe key of your own — the connected account lives on Telzino’s platform.
client_secret and the platform publishable_key. The merchant submits their own banking and identity details directly to Stripe. The platform never receives or stores merchant API keys.
The call is safe to repeat: account creation is idempotent per organization, and each call mints a fresh, short-lived session secret. Use it both to start onboarding and to resume it (e.g. the merchant closed the tab before finishing).
Onboarding requires a browser front-end — unlike the other Payments endpoints, you can’t complete it from a backend alone. Stripe collects the merchant’s identity, tax, and bank details inside an iframe rendered by Stripe’s embedded Connect components. Your server calls this endpoint to mint the session; your front-end renders the component with the returned values. The full flow is shown below.
This endpoint prepares onboarding; it does not by itself make a merchant charge-ready. Poll
GET /v1/organizations/{organization_id}/payments/status after the merchant completes Stripe’s flow to confirm can_accept_payments is true.What you need
| Piece | Where it comes from |
|---|---|
client_secret | This endpoint (short-lived, mint one per attempt) |
publishable_key | This endpoint — Telzino’s platform key (pk_…). Public by design; safe in browser JS |
@stripe/connect-js + @stripe/react-connect-js | Stripe’s npm packages, installed in your front-end |
Path Parameters
string
required
UUID of the organization (merchant) to onboard. Must belong to your account.Example:
123e4567-e89b-12d3-a456-426614174000curl -X POST \
"https://api.telzino.com/v1/organizations/123e4567-e89b-12d3-a456-426614174000/payments/onboarding" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
// Keep your Telzino access token server-side. Expose a tiny endpoint your
// front-end can call to fetch a fresh session for a given merchant org.
app.post('/onboarding/:orgId', async (req, res) => {
const r = await fetch(
`https://api.telzino.com/v1/organizations/${req.params.orgId}/payments/onboarding`,
{ method: 'POST', headers: { Authorization: `Bearer ${process.env.TELZINO_TOKEN}` } }
);
const { client_secret, publishable_key } = await r.json();
res.json({ client_secret, publishable_key });
});
import { useState } from 'react';
import { loadConnectAndInitialize } from '@stripe/connect-js';
import { ConnectComponentsProvider, ConnectAccountOnboarding } from '@stripe/react-connect-js';
export function Onboarding({ orgId }) {
const [instance, setInstance] = useState(null);
const begin = async () => {
// Fetch publishable_key + a fresh client_secret from YOUR server (above).
const first = await fetch(`/onboarding/${orgId}`, { method: 'POST' }).then((r) => r.json());
const conn = loadConnectAndInitialize({
publishableKey: first.publishable_key,
// Stripe calls this to (re)fetch a session secret on demand.
fetchClientSecret: async () =>
(await fetch(`/onboarding/${orgId}`, { method: 'POST' }).then((r) => r.json())).client_secret,
});
setInstance(conn);
};
if (!instance) return <button onClick={begin}>Set up payments</button>;
return (
<ConnectComponentsProvider connectInstance={instance}>
<ConnectAccountOnboarding onExit={() => {/* re-check status via /payments/status */}} />
</ConnectComponentsProvider>
);
}
import os, requests
def create_onboarding_session(org_id: str) -> dict:
r = requests.post(
f'https://api.telzino.com/v1/organizations/{org_id}/payments/onboarding',
headers={'Authorization': f"Bearer {os.environ['TELZINO_TOKEN']}"},
)
data = r.json()
# Return both to your front-end, which renders Stripe's embedded component.
return {'client_secret': data['client_secret'], 'publishable_key': data['publishable_key']}
{
"organization_id": "123e4567-e89b-12d3-a456-426614174000",
"client_secret": "accs_secret_1a2b3c...",
"publishable_key": "pk_live_51Ab..."
}
{
"error": "Invalid organization_id"
}
{
"error": "unauthorized",
"error_description": "User payload not found"
}
{
"error": "Forbidden",
"error_description": "You do not have access to this organization"
}
{
"error": "forbidden",
"error_description": "Card payments are not available for this organization"
}
{
"error": "Organization not found"
}
Response Fields
| Field | Type | Description |
|---|---|---|
organization_id | string | UUID of the merchant the session is for |
client_secret | string | Short-lived Stripe Account Session secret for the embedded onboarding component |
publishable_key | string | null | Telzino’s platform Stripe publishable key (pk_…) for loadConnectAndInitialize. Public by design; null only if the platform hasn’t configured one |
The
client_secret is short-lived and single-purpose. Fetch it server-side per onboarding attempt and hand it straight to the Stripe component — don’t cache or log it. The publishable_key, by contrast, is not secret — it is meant to be embedded in browser JavaScript, so caching it client-side is fine.Feature Administration gating
When Feature Administration is enabled and Card Payments (Stripe) is locked for the organization — directly or inherited from its reseller or partner — this endpoint returns403 forbidden and no onboarding session is created.
Only the entry point is gated. A merchant that already completed onboarding keeps its connected account and continues to settle, payment status stays readable, and in-flight charges always complete.