Entitlements without
identity leakage.
Product plans and access sharing belong to explicit Alex Auth account IDs, not matching email strings.
Plan configuration
Administrators configure plans under Billing & support. Each plan belongs to one product and includes a price in currency minor units, a monthly or yearly interval, and a snapshot of named entitlements. Inactive plans cannot be assigned to new purchases; existing grants retain their recorded entitlement snapshot.
Payment collection is not enabled in this release. Creating a plan does not charge a user or grant access. Subscription records must be created only after payment verification or an explicitly approved entitlement process.
Optional cross-product sharing
Sharing is disabled when the entitlement group is blank. To share, both the purchased plan and an active plan in the receiving product must use the exact same group name, and the receiving plan must explicitly include each shared entitlement key. Matching email addresses or email aliases never qualify. The same canonical Alex Auth account ID is required.
Products should request effective entitlements server-side with their project key and a current Alex Auth user token:
const response = await fetch("https://staging-admin.alexstudiohq.com/v1/billing/entitlements", {
method: "POST",
headers: {
"content-type": "application/json",
"authorization": "Bearer " + process.env.ALEX_STUDIO_HQ_API_KEY,
},
body: JSON.stringify({
clientId: process.env.ALEX_AUTH_CLIENT_ID,
accessToken: userAccessToken,
}),
});
if (!response.ok) throw new Error("Could not verify account entitlements");
const { entitlements } = await response.json();
The returned entitlement list is limited to the currently authenticated account and the project identified by that API key. Products must still enforce authorization on their own data and must not treat a client-supplied account ID as identity proof.
Card security and Paystack
Checkout is disabled by default and is restricted to an explicitly enabled Paystack test secret (sk_test_…). Card entry happens only on Paystack-hosted checkout. The product API creates a one-time transaction without a Paystack plan, then grants a 30-day or 365-day entitlement only after server-side verification confirms the exact reference, amount, currency, account/product/plan metadata, card channel, and an allowlisted debit type (visa debit, mastercard debit, or verve). Unknown, credit, prepaid, or missing card types are rejected.
Test webhook handling at https://staging-admin.alexstudiohq.com/webhooks/paystack verifies the raw request bytes against x-paystack-signature using HMAC-SHA512 and the test secret. Set PAYSTACK_SECRET_KEY as a Worker secret and PAYSTACK_ENABLED=1 as a Worker variable only after configuring Paystack's test webhook URL. A charge.success notification is only a signal to call Paystack's verify endpoint; the webhook body alone never grants access. The alternative timestamped Paystack-Signature/whsec_… format has not been enabled because it could not be verified against Paystack's official documentation.
Only a random transaction reference, plan/account binding, and verification state are retained for settlement and idempotency. Card number, CVV, authorization code, and reusable card tokens are neither received nor stored. Purchases do not auto-renew; users must start another one-time checkout when access expires. Never enable live keys through this test-only integration.
To list plans and start checkout from a product backend, use the SDK with the user's active Alex Auth token. Return the hosted URL to the browser and navigate there; keep the project key on the server:
import { createClient } from "./alex-studio-hq.js";
const hq = createClient({
apiKey: process.env.ALEX_STUDIO_HQ_API_KEY,
baseUrl: "https://staging-admin.alexstudiohq.com",
});
const { plans } = await hq.billing.plans();
const checkout = await hq.billing.checkout({
planId: plans[0].id,
clientId: process.env.ALEX_AUTH_CLIENT_ID,
accessToken: userAccessToken,
});
return { checkoutUrl: checkout.authorizationUrl };
Support diagnostic consent
Administrators can request only two read-only diagnostics: project configuration with active-key counts, or seven-day aggregate usage/error counts. Neither returns records, prompts, email addresses, API keys, or payment data. A request is bound to an environment and canonical Alex Auth account ID. The signed-in account must approve that exact request using the same project's auth client before an administrator can execute it.
Product backends can fetch a consent request by POSTing clientId and accessToken to /v1/support/requests/{id}. Submit decision: "approved" or "rejected" to /v1/support/requests/{id}/decision. Both routes require the product key's support scope and an active user token for the exact canonical account. The application must present the diagnostic type and reason to the user before sending approval.
Support approvals are one-time. Executed requests are retained in the admin audit trail, and their bounded result is visible to administrators. No support action can change user data.