feat: show Payment Not Required when Stripe is disabled (CPL-191)#252
feat: show Payment Not Required when Stripe is disabled (CPL-191)#252
Conversation
…stripe-integration-is-disabled-show-in-dashboard # Conflicts: # lit-api-server/blockchain/lit_node_express/contracts/AccountConfigFacets/AppStorage.sol # lit-api-server/blockchain/lit_node_express/contracts/AccountConfigFacets/SecurityLib.sol
When the /billing/stripe_config endpoint indicates Stripe is not configured, hide the "Add Funds" button and balance display. Show a "Payment Not Required" badge in the topbar and an explanatory banner in the dashboard body advising users to migrate to production. Includes review fixes: TTL-based retry on transient config failures, cache reset on logout, dark-mode CSS variable, and guard on openAddFundsModal. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the Lit Express dashboard UI to gracefully handle environments where Stripe billing is not configured, hiding funding-related controls and surfacing a “Payment Not Required” indicator and explanatory messaging.
Changes:
- Add a billing availability check (via
/billing/stripe_config) and conditionally show/hide balance + “Add Funds”. - Introduce a “Payment Not Required” topbar badge and an in-dashboard informational banner.
- Add CSS support for the new badge/banner, including
--bg-mutedfor light/dark themes.
Reviewed changes
Copilot reviewed 4 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| lit-static/dapps/dashboard/styles.css | Adds --bg-muted and styles for the new badge + banner. |
| lit-static/dapps/dashboard/index.html | Adds the hidden-by-default badge and billing-disabled banner containers. |
| lit-static/dapps/dashboard/app.js | Implements billing availability caching and UI toggling based on Stripe configuration. |
| lit-api-server/blockchain/lit_node_express/contracts/AccountConfigFacets/SecurityLib.sol | Import formatting normalization. |
| lit-api-server/blockchain/lit_node_express/contracts/AccountConfigFacets/AppStorage.sol | Clarifies configOperator comment. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…lure Address PR review feedback: - Guard the async billing check callback against logout/account switch by comparing the captured API key before mutating the DOM. - Schedule a setTimeout retry after transient billing check failures so the UI recovers without requiring a page reload. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…stripe-integration-is-disabled-show-in-dashboard # Conflicts: # lit-api-server/blockchain/lit_node_express/contracts/AccountConfigFacets/AppStorage.sol
| if (notRequiredEl) notRequiredEl.style.display = ''; | ||
| if (billingBanner) billingBanner.style.display = ''; | ||
| // Schedule a retry so transient failures recover without a reload | ||
| setTimeout(() => updateAuthUI(), BILLING_RETRY_MS); |
There was a problem hiding this comment.
Infinite retry loop causing unnecessary API calls. When billing is unavailable and the user remains logged in, this creates a perpetual 30-second retry cycle that never stops. Each retry schedules another updateAuthUI() call, which checks billing, fails, and schedules another retry indefinitely.
This contradicts the PR description which states "permanent 'not configured' responses cache indefinitely" - but all failures are treated identically and retry forever.
Impact: Continuous background API calls every 30s for all logged-in users on environments without Stripe, causing unnecessary server load and potential rate limiting.
Fix: Only retry for actual transient errors, not permanent configuration issues. Either:
// Option 1: Distinguish transient vs permanent failures
try {
const client = await getClient();
const config = await client.getStripeConfig();
_billingAvailable = true;
_isPermanentFailure = false;
} catch (err) {
_billingAvailable = false;
_isPermanentFailure = err.status === 404 || err.code === 'NOT_CONFIGURED';
}
// Then on line 83, only retry if not permanent:
if (!_isPermanentFailure) {
setTimeout(() => updateAuthUI(), BILLING_RETRY_MS);
}Or remove the setTimeout entirely and rely on manual user refresh/re-login to detect when Stripe becomes available.
| setTimeout(() => updateAuthUI(), BILLING_RETRY_MS); | |
| if (!_isPermanentFailure) { | |
| setTimeout(() => updateAuthUI(), BILLING_RETRY_MS); | |
| } |
Spotted by Graphite
Is this helpful? React 👍 or 👎 to let us know.
Summary
When the Stripe integration is disabled (missing keys or misconfigured), the dashboard now:
The check calls
/billing/stripe_configon login and caches the result. Transient failures retry after 30s; permanent "not configured" responses cache indefinitely. Cache resets on logout.Review fixes included: dark-mode CSS variable (
--bg-muted), guard onopenAddFundsModal,.catch()on promise chain.Pre-Landing Review
5 informational issues found and fixed during /review:
.catch()on billing promise chainopenAddFundsModalcallable when billing disabled--bg-mutedCSS var undefined for dark modeScope Drift
Test plan
🤖 Generated with Claude Code