Add SSO to your site and manage users
Register as an admin, connect your existing site to OpenBitum for OIDC/OAuth sign-in, and learn the ways to manage the users that result. End-to-end this takes about 15 minutes; the SSO bits are standard OIDC so any framework with a client library will work.
Install OpenBitum and create your admin account
If you already have an OpenBitum instance running, skip to step 2.
-
Run the installer on a Linux/macOS host (Docker 24+ required):
curl -fsSL install.openbitum.pw | bash -
The installer prompts for three things, and silently provisions a fourth:
| What you're asked | Default | Used for | |---|---|---| |
OPENBITUM_DOMAIN| none — required | Public base URL (e.g.openbitum.pw) | |OPENBITUM_ADMIN_EMAIL|admin@<your-domain>| Both the Logto admin user and the Bitcart admin user (same email, separate accounts) | |BITCART_ADMIN_PASSWORD| auto-random 24-hex | Signing into Bitcart admin atpay.<your-domain>| |LOGTO_ADMIN_PASSWORD|devsecret123!(not prompted) | Signing into OpenBitum dashboard + Logto admin console |
- After install, open
https://<your-domain>/setupin a browser. Sign in withadmin@<your-domain>/devsecret123!(or whatever you exported above) and complete the wizard:- Pick an organization name.
- Paste xPubs for the chains you want to accept payment on (optional — you can come back to this).
- Set your store name.
Create an application for your site
For your external site to sign users in via OpenBitum, it needs a Logto
Application record — that gives you a client_id, client_secret, and
the redirect URI whitelist. Use the Management API:
# 1. Mint an M2M token using the bundled openbitum-glue M2M credentials.
# Look these up via Coolify or your .env (LOGTO_M2M_APP_*).
TOKEN=$(curl -s -X POST https://auth.<your-domain>/oidc/token \
-u "$LOGTO_M2M_APP_ID:$LOGTO_M2M_APP_SECRET" \
-d 'grant_type=client_credentials' \
-d 'resource=https://admin.logto.app/api' \
-d 'scope=all' | jq -r .access_token)
# 2. Create the app. Pick a type:
# "Traditional" — server-rendered sites (Next.js, Rails, Django)
# "SPA" — client-only React/Vue/Svelte
# "Native" — iOS / Android / desktop
# "MachineToMachine" — server-to-server with client_credentials grant
curl -X POST https://auth.<your-domain>/api/applications \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "my-site-prod",
"type": "Traditional",
"oidcClientMetadata": {
"redirectUris": [
"https://your-site.com/api/auth/callback",
"http://localhost:3000/api/auth/callback"
],
"postLogoutRedirectUris": [
"https://your-site.com",
"http://localhost:3000"
]
}
}'
The response contains id (your client_id) and secret (your client_secret).
Save them — the secret is shown once and you'll need it in step 3.
Wire your site up to OIDC
You now have everything an OIDC client library needs. The endpoints follow the OpenID Connect Discovery spec at:
https://auth.<your-domain>/oidc/.well-known/openid-configuration
Below is a Next.js (App Router) example using @logto/next. Adapt
the pattern for your framework — the discovery URL + client id/secret are
the only inputs that change.
pnpm add @logto/next
// app/api/logto/[...logto]/route.ts
import { handleAuthRoutes } from "@logto/next/server-actions";
export const dynamic = "force-dynamic";
export const { GET, POST } = handleAuthRoutes({
endpoint: process.env.LOGTO_ENDPOINT!, // https://auth.<your-domain>
appId: process.env.LOGTO_APP_ID!,
appSecret: process.env.LOGTO_APP_SECRET!,
baseUrl: process.env.LOGTO_BASE_URL!, // https://your-site.com
cookieSecret: process.env.LOGTO_COOKIE_SECRET!,
cookieSecure: true,
scopes: ["openid", "profile", "email"],
});
Then anywhere in your app, a sign-in link is just:
<a href="/api/logto/sign-in">Sign in with OpenBitum</a>
For frameworks other than Next.js, the OIDC dance is the same — point your
library at https://auth.<your-domain>/oidc as the issuer and use the
app's id/secret. Tested integrations:
- Next.js —
@logto/next(above) - Express —
@logto/express - Rails —
omniauth-openid-connect - Django —
mozilla-django-oidc - Generic — any RFC 6749 / RFC 8252 compliant client
Test the sign-in flow
- Start your app locally.
- Click your Sign in with OpenBitum link.
- You should be redirected to your OpenBitum's sign-in form
(
auth.<your-domain>/sign-in?...). - Sign in (use your admin user, or first register a new user via the form).
- You should land back at your app's callback URL with a valid session.
Manage your users
Once people are signing in, there are two reliable ways to see and manage them:
a) OpenBitum dashboard customers view —
https://app.<your-domain>/dashboard/customers. Shows the buyers who
came through checkout, with their order count and total spend. Use this when
you care about the commerce angle (who bought what), not the identity angle
(who can sign in).
b) Management API — same M2M token from step 2 gives you full CRUD over users:
# List users (paginated)
curl -H "Authorization: Bearer $LOGTO_MGMT_TOKEN" \
"https://auth.<your-domain>/api/users?page=1&page_size=20"
# Lookup by exact email
curl -H "Authorization: Bearer $LOGTO_MGMT_TOKEN" \
"https://auth.<your-domain>/api/users?search=alice%40example.com&searchProperties=primaryEmail&mode=exact"
# Suspend a user
curl -X PATCH -H "Authorization: Bearer $LOGTO_MGMT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"isSuspended": true}' \
"https://auth.<your-domain>/api/users/<userId>"