Installation
Add the snippet to every authenticated page — typically inside your app shell’s<body>, after the user is confirmed to be logged in:
Attributes
| Attribute | Required | Description |
|---|---|---|
data-tenant-slug | ✓ | Your SteadPay tenant slug, visible in the dashboard |
data-publishable-key | ✓ | Your SteadPay publishable key (pk_live_… or pk_test_…) |
data-customer-id | Stripe customer ID (cus_…) for auto-init. If omitted, call window.Steadpay.check(cid) manually | |
data-api-base | Base URL of your SteadPay API. Defaults to the SteadPay-hosted API | |
data-gate-base | Origin for the gate iframe. Defaults to data-api-base. Must be a SteadPay-controlled origin | |
data-locale | UI locale — en, fr, es, de. Defaults to navigator.language, fallback en |
Manual init (SPAs)
If your app renders the subscriber’s customer ID after the initial page load (e.g. after an auth redirect), omitdata-customer-id and call window.Steadpay.check() manually once the ID is available:
Steadpay.check() again any time the signed-in user changes (e.g. account switcher).
Enforcement behaviour
Active
No UI is shown. The subscriber’s session continues unaffected.Warning (soft decline)
A dismissable amber banner appears fixed at the top of the viewport:- Includes a localized message and an Update card CTA if
card_update_urlis configured in your dashboard - The subscriber can dismiss the banner, but it reappears on the next page load
- Polling continues every 10 minutes so the banner disappears automatically once the issue resolves
Lockout (hard decline or exhausted retries)
A full-screen iframe overlay covers the entire viewport:z-index: 2147483647— rendered above all app contentsandbox="allow-scripts allow-same-origin allow-popups allow-forms"— the gate page cannot access parent DOM or storage- Contains a Stripe Payment Element for immediate card update
- Dismisses automatically once the subscriber completes the card update flow