Step 2: Add login and registration to your site
This runs in the browser and uses your publishable key. Drop in the script and a container:
HTMLCopy
<script src="https://vaultix.cc/widgets/vaultix-widget.js"></script>
<div id="vaultix-login"></div>
<script>
new VaultixLoginForm('vaultix-login', {
apiKey: 'ap_web_your_publishable_key', // publishable key — safe in the browser
onLoginSuccess: (result) => {
// result.token -> a 30-day website session token for THIS user
// result.user -> { id, username, email, subscriptions, status }
localStorage.setItem('vaultix_token', result.token);
}
});
</script>
A registration form works the same way with VaultixRegistrationForm. If you enabled CAPTCHA, the widget shows it automatically — no extra code.
Don't like the default look? Override it.
The widgets ship with sensible default styles, but they're just plain elements with vaultix- class names. Add your own CSS after the script and style them however you want.
CSSCopy
/* Your own CSS — overrides the widget defaults */
.vaultix-login-form, .vaultix-register-form { font-family: inherit; }
.vaultix-form-group input { border-radius: 8px; }
.vaultix-submit-btn { background: #4f46e5; }
.vaultix-error { color: #ef4444; }
Hooks include .vaultix-login-form, .vaultix-register-form, .vaultix-form-group, .vaultix-username, .vaultix-password, .vaultix-submit-btn, .vaultix-error and .vaultix-success. Inspect the rendered form to find any others.
Allowed domains
Only requests from these domains are accepted for browser register/login. Add domains without http:// or www. — e.g. example.com. Subdomains of a listed domain are allowed too.
Test mode
Flip on Test mode in Integrations → Website integration to accept any origin, including localhost, so you can build before your domain is live. It ignores the domain list while on. Turn it off for production — not recommended for a live site.
Step 3: Grant a subscription from your server
POST/api/website/subscription
After your payment flow confirms a payment, your backend calls Vaultix with the secret key. Identify the user by userId, email, or username, and send an Idempotency-Key so retries don't double-grant.
Node.jsJavaScriptCopy
// ---- server-side only (e.g. inside your payment webhook) ----
await fetch('https://vaultix.cc/api/website/subscription', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + process.env.VAULTIX_SECRET_KEY, // ap_web_sec_...
'Idempotency-Key': paymentId, // any unique id for this payment
},
body: JSON.stringify({
email: 'customer@example.com', // or userId / username
productId: 'web_xxx_or_real_product_id',
expiresAt: '2025-12-31T23:59:59Z', // or null for a lifetime subscription
}),
});
Or with curl:
curlShellCopy
curl -X POST https://vaultix.cc/api/website/subscription \
-H "Authorization: Bearer $VAULTIX_SECRET_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $PAYMENT_ID" \
-d '{"email":"customer@example.com","productId":"<product>","expiresAt":null}'
The response echoes back the resolved user, including their optional name (a display name you can set on the user — handy in key auth mode, where there's no username). It's null if unset.
ResponseJSONCopy
{
"success": true,
"subscriptionId": "…",
"userId": "…",
"name": "Jane (VIP)", // optional display name, or null
"productId": "…",
"expiresAt": null,
"message": "Subscription created successfully"
}
Never call this from the browser
Do not call this endpoint from the browser, and do not ship the secret key to the client. If you do, anyone can read it and grant themselves free subscriptions. The endpoint rejects the publishable key for exactly this reason.
Step 4: Show subscription status (optional)
POST/api/website/me
From the browser, refresh the logged-in user's status with their session token:
JavaScriptCopy
const res = await fetch('https://vaultix.cc/api/website/me', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': 'ap_web_your_publishable_key' },
body: JSON.stringify({ token: localStorage.getItem('vaultix_token') })
});
const { user } = await res.json(); // user.subscriptions = [...]
The user's key is sensitive, so it's left out by default. If you need it (e.g. to show it for key auth mode), pass includeKey: true — the endpoint only ever returns the key of the user whose session token you sent.
JavaScriptCopy
const res = await fetch('https://vaultix.cc/api/website/me', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': 'ap_web_your_publishable_key' },
body: JSON.stringify({ token: localStorage.getItem('vaultix_token'), includeKey: true })
});
const { user } = await res.json(); // user.key is now included