Key takeaways
- One script tag adds a corner button that opens the offerwall in a pop-up, so users never leave the page they are on.
- Your server signs the link for each signed-in user, and the pop-up only loads on https pages of the website registered for the app and its subdomains.
- The offerwall must open only when a user clicks, never by itself on page load, on a timer, or on scroll.
How do you add a floating Earn button to a website?
A floating Earn button is a small button that stays in a corner of every page of your website and opens your offerwall in a pop-up when a user clicks it. On Moonetix it takes one script tag, embed.js, with the signed offerwall link of the signed-in user. You can change the text, the color, and the side of the screen, and users close the pop-up to return to exactly where they were.
It suits sites where users browse many pages, such as forums, blogs with accounts, browser games, and community sites, because the entry point is always one click away without giving the offerwall a page of its own. The reference for every attribute is the floating button section of the Offerwall link docs.
Who does what
| Part | Who handles it | What it does |
|---|---|---|
| Signed link | Your server | Builds user_id and hash for the signed-in user with your link hash salt |
| Button and pop-up | embed.js from Moonetix | Shows the corner button, opens the offerwall over your page, closes it again |
| Offers | Moonetix | Shows offers for the user’s country and device, tracks starts and completions |
| Rewards | Your server | Credits or takes back your currency when a signed postback arrives |
The button never credits anyone. It is only an entry point, exactly like the offerwall link or the iframe, and the same postback handler serves all three.
What happens when a user clicks it
- The button sits fixed in the bottom corner of the page, above your content.
- A click opens a large pop-up over the page with the offerwall inside. The page behind it stops scrolling while it is open.
- The user browses offers, starts them, and follows them in My offers, all inside the pop-up.
- The user closes it with the close button, the Escape key, or a click outside it, and is back on the same page.
- Rewards reach your server later through postbacks, exactly as with any other integration.
Button visits count as offerwall traffic in your statistics, together with the link and the iframe. To tell them apart, add a sub ID such as &sub1=button to the link in the script. It comes back in the {sub1} postback macro, and the Reporting API can group your earnings by it. Click IDs and sub IDs explained covers naming sub IDs so your reports stay readable.
Step 1: copy the snippet
The floating button is an option of the offerwall, so every Moonetix app can use it, with the same App ID and signed link. As soon as you click Create app, the app is live, and its Integration tab shows the code with your link already in it:
<script src="https://wall.moonetix.com/embed.js" async
data-button-url="https://wall.moonetix.com/{APP_ID}?user_id={USER_ID}&hash={HASH}"
data-button-text="Earn rewards"
data-button-color="#004ABB"
data-button-position="right"></script>
| Attribute | Required | What it does |
|---|---|---|
data-button-url | Yes | The signed offerwall link of the user. It must start with https://wall.moonetix.com/, or no button is shown. |
data-button-text | No | The label, up to 40 characters. Default: Earn rewards. |
data-button-color | No | A six-digit hex color such as #004ABB. The text turns dark or light by itself so it stays readable. |
data-button-position | No | right or left. Default: right. |
The async attribute matters. As MDN’s script element reference explains, an async script is fetched in parallel with the page and does not block HTML parsing, so the button never slows down the content your visitors came for.
Keep the label short and honest. “Earn coins” or “Earn rewards” tells users what they get. “Free money” promises something no offerwall delivers and invites the wrong kind of traffic. Pick a color that stands out from your page background; the text color adjusts itself, but the button still needs to be visible against your design. The WCAG 2.2 contrast guideline asks for at least 4.5:1 for normal text, a good bar for the label. Move the button to the left if a chat widget or a cookie banner already uses the bottom right corner.
Step 2: build the link for each signed-in user
The {USER_ID} and {HASH} in the snippet are placeholders. Your server replaces them for every signed-in user when it renders the page. The user ID is the ID of the account in your system, and the hash is an HMAC-SHA256 of that ID with your app’s link hash salt, in lowercase hex. In PHP, for example:
<?php if ($currentUser): ?>
<?php
$userId = (string) $currentUser->id;
$hash = hash_hmac('sha256', $userId, $linkHashSalt);
$link = 'https://wall.moonetix.com/' . $appId . '?user_id=' . rawurlencode($userId) . '&hash=' . $hash;
?>
<script src="https://wall.moonetix.com/embed.js" async
data-button-url="<?= htmlspecialchars($link) ?>"
data-button-text="Earn coins"></script>
<?php endif; ?>
- Only for signed-in users. Logged-out visitors get no button at all, or your own log-in prompt. Rewards need an account to land in.
- Use a stable ID. The ID your database gives the user, not an email address or a username, which can change and would split the user’s offers and rewards.
- The salt never reaches the browser. The script only needs the finished link. It never asks for your salt or keys, and it only opens links that start with the Moonetix offerwall address.
The Offerwall link docs have the same hash code in Node.js and Python. On WordPress, How to add an offerwall to WordPress adds the button through a small plugin, and Offerwall PHP integration for Laravel shows it in a Blade layout.
Step 3: check your page cache and Content Security Policy
A page with a signed link belongs to one user, so it must not be cached and served to others. MDN’s Cache-Control reference describes the two directives that matter: private keeps a response out of shared caches, and no-store stops any cache from storing it. Many caching plugins and CDNs already skip pages for logged-in users, but confirm that yours does before you go live.
If your site sends a Content Security Policy header, two directives need https://wall.moonetix.com:
| Directive | Why |
|---|---|
script-src | Loads embed.js |
frame-src | The pop-up shows the offerwall in a frame |
Per MDN’s frame-src page, this directive lists the sources an iframe may load, so without it the pop-up opens empty even though the button shows.
Where the pop-up works
For safety, the offerwall only loads inside frames and pop-ups on the website you registered for the app and its subdomains, and only on https pages. An app registered for example.com works on example.com, www.example.com, and forum.example.com. On a staging domain, on plain http, or on a different site, the pop-up opens but the offerwall inside it does not load.
Need the offerwall somewhere else as well, for example in a mobile app or a Discord message? Open the offerwall link of the same app there. Opening the link directly in a tab, a new window, or a mobile WebView works everywhere, and the same keys and postback settings cover every entry point. How to open the offerwall in a WebView covers the app side.
Open it from your own button, link, or JavaScript
You do not have to use the floating button itself. If your menu already has a Rewards item, add data-moonetix-open to it and load the script once on the page:
<a href="https://wall.moonetix.com/{APP_ID}?user_id={USER_ID}&hash={HASH}" data-moonetix-open>Earn rewards</a>
<script src="https://wall.moonetix.com/embed.js" async></script>
A click opens the same pop-up instead of a new page. If the script does not load, for example because an extension blocks it, the link still works and opens the offerwall as a normal page. That fallback is the reason to prefer a real link with an href over a bare button.
From your own JavaScript, call Moonetix.open(link) with the signed link. Call it from a click handler, and keep a fallback for the moment before the script has loaded:
document.getElementById('earn').addEventListener('click', function () {
if (window.Moonetix && window.Moonetix.open) {
window.Moonetix.open(wallLink);
} else {
window.location.href = wallLink;
}
});
Here wallLink is the signed link your server put into the page. Never build it in the browser, because that would need the salt.
When a button beats a dedicated page
| Your site | Better choice | Why |
|---|---|---|
| Forum, blog, or community with accounts | Floating button | Users spend time on many pages, and the entry point follows them |
| Browser game or web app | Floating button or your own menu link | Players earn without leaving the game screen |
| Rewards or GPT site | Dedicated page with the iframe | The offerwall is the main product and deserves the full page |
| Site with a busy corner already | Your own menu link with data-moonetix-open | Same pop-up, no extra element on screen |
| Mobile app or chat community | The offerwall link or an SDK | No website to put a button on |
A dedicated page also gives you room above the offerwall to explain your currency and how long credits take; How to write an earn page that converts covers that copy. If the offerwall is your main product, read How to start a rewards website. For a side-by-side of every method, see Offerwall integration: iframe, link or API?
Placement: what to do and what to avoid
The single most important rule: the offerwall opens only when the user clicks. Moonetix’s terms forbid placing the offerwall in pop-ups or new windows that open without the end user’s click, while opening it in a pop-up after a click, for example with the embed script, is allowed. It is also good for your search traffic: Google Search Central’s guidance on intrusive interstitials warns that overlays which interrupt users can frustrate them and erode their trust in a site (checked on November 4, 2026). A pop-up the user asked for is not that.
| Do | Do not |
|---|---|
| Show the button where users can see what it is | Call Moonetix.open() on page load, on a timer, on scroll, or when the mouse leaves the page |
| Use a clear label such as “Earn coins” | Disguise it as a system alert, a download button, or a prize notification |
| Show it only to signed-in users of the right age | Put it on pages with adult, illegal, or infringing content |
| Keep it clear of your own content and other widgets | Cover close buttons, cookie banners, or your navigation with it |
| Explain on your site what the rewards are worth | Hide it behind a paywall |
Never open the offerwall without a click
An auto-opening offerwall breaks Moonetix’s terms and brings low-quality traffic: people who close it at once, or click offers by accident. Both hurt your results more than they help.
End users must be at least 16 to use an offerwall powered by Moonetix, so do not show the button on sites made for children. Offerwall placement: where to put it to earn more covers timing and entry-point design in depth.
Test and troubleshoot the button
Before launch, open a page as a normal signed-in test user, click the button, and start an offer. Then run the checks in How to test your app before launch. If something does not work:
- No button appears.
data-button-urlis missing or is not a Moonetix offerwall link, and the browser console shows a warning from Moonetix embed. Also check that nothing on your page blocks the script, and that you print it only after you have a signed-in user. - The pop-up opens but stays blank. The page is not on the registered website or a subdomain of it, it is served over http, or your Content Security Policy does not allow
https://wall.moonetix.cominframe-src. - Link not valid inside the pop-up. The hash does not match the user ID. Use Check a link in Integration status on the Integration tab: paste the link from your page source, or compare it with the one from Test a link.
- VPN detected or Network not supported. You are testing from a VPN, a proxy, or a cloud server. Test from a normal home or mobile connection.
- Rewards do not arrive. The button only opens the offerwall. Crediting happens in your postback handler, so check Reports, Postbacks and read Postback security: verify every reward call.
To check the link your server builds, compare it with the one from the offerwall link builder for the same user ID.
A Moonetix floating button in one line
Moonetix is a pay-per-result affiliate network, and the floating button is one way to open its offerwall, next to the iframe, the offerwall link, the Offers API, and the mobile SDKs. It uses your wall’s own colors, currency, and signed link, with nothing extra to host. Start with how to get approved as a publisher, and see how the wall works.
Frequently asked questions
Can the button open the offerwall automatically?
No. The offerwall may only open after the user clicks. Opening it on page load, on a timer, or on scroll breaks the placement rules.
Can I change the button text and color?
Yes. data-button-text takes up to 40 characters, data-button-color takes a six-digit hex color, and data-button-position moves it to the left or right corner.
Why does the pop-up stay blank on my test site?
The offerwall only loads in pop-ups on https pages of the website registered for the app and its subdomains. A staging domain, a plain http page, or a Content Security Policy without https://wall.moonetix.com in frame-src will not load it.
Does the floating button slow down my page?
The script loads with async, so it does not block your page from rendering. The offerwall itself only loads when a user clicks the button.
Can I use the floating button and an embedded offerwall page together?
Yes. Both open the offerwall of the same app, with the same App ID, keys, and postback settings.
Does the floating button work in a mobile app?
It is made for websites. In a native app, open your app’s signed offerwall link in a WebView or the system browser, or use one of the mobile SDKs.


