Unity offerwall SDK. Players earn your in-game currency.

Let players earn your in-game currency by completing offers, with no banner ads in your game. One Unity package covers Android and iOS, and every reward reaches your game server as a signed postback.

  • 2022.3+Unity LTS or Unity 6
  • 2.0.0Current version
  • 2Platforms, one package
Unity SDKVersion 2.0.0
EarnButton.cs
using MoonetixOfferwall;
 
void Awake()
{
    Moonetix.Init("YOUR_APP_ID");
}
 
public void ShowOfferwall(string token)
{
    Moonetix.Open(token);
}

Go live in four steps.

Copy the code, replace the placeholders with the values from your dashboard under Apps, your app, Integration, and test before you launch.

  1. Install the package

    Add the Moonetix scoped registry and the package to Packages/manifest.json, or add the registry in Project Settings and install Moonetix Offerwall from the Package Manager. The Android and iOS SDKs come with it.

    Packages/manifest.json
    {
      "scopedRegistries": [
        {
          "name": "Moonetix",
          "url": "https://moonetix.com/upm",
          "scopes": ["com.moonetix"]
        }
      ],
      "dependencies": {
        "com.moonetix.offerwall": "2.0.0"
      }
    }
  2. Add a token endpoint to your server

    Your app never holds the API key. When a user taps Earn, your app asks your server for a session, and your server asks Moonetix for a single-use token for that signed-in user. A token works once, for 10 minutes.

    session.php
    <?php
    // POST /api/moonetix/session: a fresh token for the signed-in user
    $user = current_user();
    if (!$user) {
        http_response_code(401);
        exit;
    }
     
    $key = getenv('MOONETIX_API_KEY');
    $ch  = curl_init('https://api.moonetix.com/v1/session');
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => http_build_query(['user_id' => (string)$user->id]),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 10,
        CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $key],
    ]);
    $data = json_decode((string)curl_exec($ch), true);
    $code = (int)curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
     
    header('Content-Type: application/json');
    if ($code === 201 && !empty($data['token'])) {
        echo json_encode(['token' => $data['token']]);
        exit;
    }
    http_response_code($code === 403 ? 403 : 503);
    echo json_encode(['error' => 'offerwall_unavailable']);
  3. Open the offerwall

    Call Init once with the App ID from your dashboard, then Open with a fresh token. All events arrive on the Unity main thread, so you can update your UI directly. The package also has an Offerwall demo sample.

    EarnButton.cs
    using MoonetixOfferwall;
    using UnityEngine;
     
    public class EarnButton : MonoBehaviour
    {
        void Awake() => Moonetix.Init("YOUR_APP_ID");
     
        void OnEnable()
        {
            Moonetix.OnClosed += RefreshBalance;
            Moonetix.OnError += HandleError;
        }
     
        void OnDisable()
        {
            Moonetix.OnClosed -= RefreshBalance;
            Moonetix.OnError -= HandleError;
        }
     
        public void ShowOfferwall(string token) => Moonetix.Open(token);
     
        void HandleError(MoonetixError error)
        {
            Debug.LogWarning(error.CodeName + ": " + error.Message);
        }
     
        void RefreshBalance() { }
    }
  4. Credit rewards with the postback

    Every reward reaches your server as a signed postback. Check the hash, add the reward once per transaction ID, and take it back if a later postback reverses it. Failed postbacks are retried up to 5 times.

    Postback macros and retries

    Dashboard, Postback tab
    https://yoursite.com/postback?user={user_id}&tx={transaction_id}&status={status}&reward={reward}&hash={hash}
9:41
Earn gems12,450 Gems
EarnMy offers
  • Castle MergeReach level 10+1,500
  • FitTrackStart a free trial+2,000
  • Word RushPlay 3 days in a row+450
  • Budget PalSet up your first budget+800
Reward creditedCastle Merge · +1,500 Gems
Native screen
Postback 200 OK

What your users see

A native screen over your app, with your title and colors, your currency, and every reward confirmed by a postback.

What the package handles for you

  • Android and iOS builds

    On Android it adds the Maven repository, SDK, and R8 rule to your Gradle project. On iOS it links and embeds the iOS SDK in Xcode.

  • Offers open in the right place

    Offers that lead to Google Play or the App Store open in the store app, so installs are tracked correctly.

  • No key inside your game

    Your game holds only the App ID. Sessions come from your server and work once.

  • Main thread events

    OnOpened, OnClosed, and OnError are raised on the Unity main thread, ready for your UI.

  • Your in-game currency

    Rewards are shown and credited in your own currency, with your exchange rate and user split.

  • No advertising ID

    The SDK does not use the advertising identifier and does not track players across apps.

Test it, then launch.

Everything you need to check before real users see your offerwall, with the tools built into your dashboard.

  1. Open as a test user

    In Integration status on the Integration tab, open your offerwall as the user owner-test. Test visits are not counted as users.

  2. Run it on a real device

    Build for Android or iOS and open the offerwall from your Earn button with a fresh token each time.

  3. Send a test postback

    Choose the user, status, and payout, and see exactly what your server answered, with the response code and time. Test transaction IDs start with test_.

  4. Test from a normal connection

    VPNs, proxies, Tor, and cloud networks are blocked, so test on home Wi-Fi or mobile data, in a country where offers run.

Launch checklist

0 of 11 ready

Common errors, fixed fast.

What you might see while you integrate the Unity SDK, what causes it, and the fix.

  • InvalidAppId

    The value passed to init is not the App ID. Passing the API key here is the most common mistake.

    FixCopy the 24-character App ID again from the Integration tab.

  • InvalidToken

    The app passed something other than the token, or a token created with the API key of another app.

    FixPass only the token field, which starts with sst_, and use the App ID and API key of the same app.

  • TokenExpiredOrUsed

    The token is older than 10 minutes or was already used, for example kept from an earlier tap.

    FixCreate a new token for every open, right when the user taps Earn.

  • NotInitialized

    open was called before init.

    FixCall Moonetix.Init in Awake of your first scene.

  • Unsupported

    The game runs in the Unity Editor, on desktop, or in WebGL.

    FixBuild for Android or iOS, and check Moonetix.IsSupported before you show the button.

  • iOS build stops on the iOS version

    Target minimum iOS Version in Player Settings is below 13.0.

    FixSet it to 13.0 or higher.

  • 403 from /v1/session

    app_not_live means the app is paused or your account is not active. user_blocked means we blocked this user.

    FixDo not show the offerwall. For app_not_live, check your notifications.

  • VPN or Proxy detected

    The device is on a VPN, a proxy, or a cloud network, where offers cannot be tracked.

    FixTest on a normal home or mobile connection, in a country where offers run.

  • Postback log shows 403 or 404

    Your script rejected the postback, or the URL is wrong.

    FixOpen the URL from the log in a browser and check your hash code.

  • Postback log shows a timeout

    Your script takes longer than 6 seconds to answer.

    FixAnswer with 200 first, and run slow work in the background.

  • Postback log shows 301 or 302

    Your URL redirects, for example from http to https.

    FixUse the final URL. Postbacks do not follow redirects.

At a glance

Unity version
Unity 2022.3 LTS, or Unity 6 (6000.0) or newer
Platforms
Android, and iOS 13 or newer
Package
com.moonetix.offerwall 2.0.0 from moonetix.com/upm
Language
C#
Sample
Offerwall demo with an Earn button, in the Package Manager
Price
Free for approved publishers

Other integrations

Unity questions

What developers ask before they add the Unity SDK.

Stuck on something? Contact us

Which Unity versions are supported?

Unity 2022.3 LTS, or Unity 6 (6000.0) or newer. On iOS, set the minimum iOS version to 13.0 or higher in Player Settings.

Does it work for Android and iOS builds?

Yes. One package covers both. Unity adds the Android SDK to the Gradle project and the iOS SDK to the Xcode project by itself, including exported projects and custom Gradle templates.

How do I install the Moonetix Unity package?

Add the Moonetix scoped registry and com.moonetix.offerwall to Packages/manifest.json, or install it from My Registries in the Package Manager. You can also install it from a tarball.

Is an offerwall pay-to-win?

No. Players earn the same currency they would earn by playing, by trying apps and games from advertisers. It gives non-paying players a way to progress without banner ads in your game.

How do I credit players safely?

Credit rewards on your game server from the signed postback, never from client events, because players can fake them. When OnClosed fires, load the player’s balance from your server.

Can I test it in the Unity Editor?

You can test your flow. In the Editor, on desktop, and in WebGL, Open checks the App ID and the token and then reports Unsupported, and Moonetix.IsSupported is false. To see the offerwall itself, build for Android or iOS and test on a phone or the iOS Simulator.

Turn your traffic into earnings.

Create a free publisher account and earn from every offer your users complete on your website, app, game, or community.

Worldwide targeting
More
Log in