By default the wall is a soft prompt: the customer can dismiss it and keep using your product, and the overlay reappears after a short cooldown while the payment is still outstanding. You can optionally enable hard lock, which removes the close button after a delay you choose, so the product stays blocked until the payment is fixed.
How it works
- Your app loads
wall.jsand callsAirdun.identify()with the logged-in customer. - The script asks Airdun whether that customer has an active recovery case.
- If they do — and the wall is on for that case’s use case, and a message in the customer’s language is ready — it injects a full-screen overlay with the recovery copy and a CTA to the Stripe hosted invoice (opened in a new tab).
- Everything fails silently. A wall error never breaks your app; if anything is missing, nothing is shown.
Get your key
The wall authenticates with your workspace publishable key — an identifier that starts withawall_pk_live_. It is safe to ship in client-side code.
In your Airdun dashboard, go to Channels configuration → In-app wall (app.airdun.com/channels/wall). It shows your key and a copy-ready snippet. The key is created on first view and does not change. One install serves every use case (Renewals and Free trials).
Install
1. Add the script
Add this to your app’s HTML, replacing the key with your own. The first inline script queues anyidentify() calls made before wall.js finishes loading.
2. Identify the logged-in customer
Once you know who is logged in, callidentify(). This is how the wall knows which customer to check.
wall.js has loaded is fine — the call is queued and replayed on init.
identify() parameters
What you configure
Everything else is set in the dashboard: nothing beyond the key andidentify() is configured in code. The wall is set per use case, under Autopilot → Renewals or Free trials → In-app wall. New customers has no wall.
- Turn it on — the wall only shows for a use case whose wall is on. Turning it on is a recommended step of that use case’s checklist.
- Messages — two messages per use case: one before the hard lock and one during it. Each has a title and a description; the button label is set by Airdun, in the customer’s language. Until you edit one, Airdun shows its default wording, already written in every supported language. You can use
{{FAILED_AT}},{{CLOSES_AT}}, and{{DAYS_UNTIL_CLOSE}}, the same names as in the emails. The message shown before the hard lock can also use{{HARD_LOCK_AT}}and{{DAYS_UNTIL_HARD_LOCK}}; their line is removed when the hard lock is off. - Language — you write in any language; Airdun translates per customer based on the
localeyou pass (then the use case’s language detection and fallback, see Use Case Settings). While your wording is not yet translated into a customer’s language, the wall is not shown to that customer. - Hard lock — optionally remove the close button after a delay you choose, in days counted from the payment failure (empty: as soon as the payment fails). Before the delay the wall stays dismissible; after it, the wall blocks the product until the payment is fixed.
- Appearance — custom CSS to restyle the wall to match your product (see below). Without it, the wall uses a fixed, neutral style so it reads as a system prompt.
Custom CSS
The wall renders inside a closed shadow DOM on your page, so your site’s stylesheets never affect it — and it never affects your site. To restyle it, add CSS in the dashboard (the use case’s In-app wall → Appearance tab): your CSS is injected inside the wall, after the base stylesheet, so your rules win at equal specificity without!important.
The editable surface is a small set of stable classes:
The editor shows a live preview as you type, and the Copy doc for LLM button copies a self-contained brief (the full base stylesheet, the markup, and the rules) that you can paste into a coding assistant such as Claude Code or Cursor and ask it to write the CSS matching your design system.
Constraints: 20,000 characters maximum,
@import is not allowed, and @font-face does not work inside a shadow DOM — but any font your app already loads can be referenced by font-family.
Test it on your site
Once the script is installed, you can render the wall on your own site without a real failed payment and without affecting any data.- Preview link — open any page of your app with
#airdun-wall-previewappended to the URL. The Test it on your site section of Channels configuration → In-app wall builds this link for you. - Browser console — run
AirdunWall.preview()on any page where the script is loaded. - Preview a real case — pass a case ID to see exactly what that customer sees, in their language and with their pay link:
#airdun-wall-preview=<caseId>orAirdunWall.preview('<caseId>'). The case ID is on the case page in your dashboard.
Behavior details
- When it shows — automatically, whenever the identified customer has an open recovery case in a use case whose wall is on (the most recent one is used) and its message is available in the customer’s language. There is no trigger to configure. It is never shown on a suspected fraud, nor after its use case was turned off with Stop everything now (except on escalated cases). If the Stripe pay link cannot be loaded, the wall shows without its button.
- Dismissal — closing takes two steps (a confirm), and a dismissed wall reappears after a short cooldown if the payment is still outstanding.
- The CTA — opens the customer’s Stripe hosted invoice in a new tab, where they update their card and pay.
- No customer data required beyond identify — the wall reads the case from Airdun; you don’t send payment or case data from the browser.
