From nothing to a credited user.
Two pieces: an iframe that shows the offers, and a server-to-server postback that tells your backend to credit the user. This page walks through both, in order.
1 · Apply
An approved application is required before the tools work. Fill in the form with the real site or app you plan to put the wall on — applications are read by a person, not auto-approved.
2 · Get your keys
Once approved, log in and open Monetize, then Setup on the placement you want. That page holds everything you need:
| On the Setup page | What it is for |
|---|---|
| Public key | Goes in the iframe URL and in the Offers API. |
| Secret key | Stays on your server. It is what signs the postback. |
| Tracking link | The ready-made wall URL for this placement. |
| Postback URL | Where we should call you. Set it before you send traffic. |
Each gets its own keys, its own postback URL and its own reporting. Do not share one pair across products.
3 · Paste the wall
Replace YOUR_KEY with your public key and USER_ID with the id you
already use for that user on your side. That same value comes back in the postback as
subId, which is how you know who to credit.
<iframe src="https://newwall.178.105.95.44.nip.io/offer/YOUR_KEY/USER_ID" width="100%" height="700" frameborder="0" allow="clipboard-write" ></iframe>
Prefer to build your own interface? Pull the same catalogue as JSON from the Offers API — the postback works exactly the same either way.
How the postback arrives
Whenever a user completes an offer we make an HTTP GET to your postback URL with
everything needed to credit them. It is server to server: nothing depends on the user's
browser still being open.
Parameters
| Parameter | Description |
|---|---|
| subId | Unique id of the user who completed the action on your platform. |
| transId | Unique id of the transaction. This is your deduplication key. |
| reward | Exact amount of your virtual currency to credit. |
| round_reward | The same amount in the decimals configured for the placement. |
| payout | Offer payout in USD. |
| signature | MD5 hash to verify the call came from our servers. |
| status | 1 add the currency · 2 subtract it (advertiser cancellation, fraud or mistake). |
| userIp | The user's IP address. |
| offer_id | Id of the completed offer. |
| offer_name | Name of the completed offer. |
| country | ISO 2-letter country the lead came from. |
| uuid | Unique id of the click the user made. |
| event_id | Id of the event credited. Empty on non-event conversions. |
| event_name | Name of the event credited. Empty on non-event conversions. |
A cancellation is not a negative number — it is the same call with status=2. Branch on the status.
Signature
Verify it on every call. The signature must equal the MD5 of
subId + transId + reward + secret. Your secret key is on the Setup page.
<?php $secret = ''; // your secret key from the Setup page $subId = $_REQUEST['subId'] ?? null; $transId = $_REQUEST['transId'] ?? null; $reward = $_REQUEST['reward'] ?? null; $status = (int) ($_REQUEST['status'] ?? 1); $signature = $_REQUEST['signature'] ?? null; // 1 — did it really come from us? if (!hash_equals(md5($subId . $transId . $reward . $secret), (string) $signature)) { exit('INVALID SIGNATURE'); } // 2 — seen before? say DUP and the retries stop if (Credit::where('trans_id', $transId)->exists()) { exit('DUP'); } // 3 — credit, or take it back if status is 2 $user->addCoins($status === 2 ? -(float) $reward : (float) $reward); Credit::create(['trans_id' => $transId]); exit('OK');
What to reply
Plain text, one of two:
| Reply | When | What we do |
|---|---|---|
| OK | New transaction, credited. | Done, nothing more sent. |
| DUP | You had already credited this transId. | We stop retrying that transaction. |
Retries
We wait up to 60 seconds for your answer. On timeout the same transaction is retried
up to 5 times over the next few hours. That is precisely why you must deduplicate on
transId — otherwise a slow response turns into paying the same user twice.
Testing tool
On the same Setup page there is a tool that fires a test postback at your endpoint, signed the same way as a real one. Use it before sending any traffic.
- Confirm you answer
OKand the balance moves. - Send the same
transIdagain: you must answerDUPand credit nothing. - Send one with
status=2: it must subtract.
If it is not crediting
| Symptom | Usual cause |
|---|---|
| Signature never matches | The secret is from a different placement, or the values are concatenated in the wrong order. It is subId + transId + reward + secret. |
| Same user credited twice | No transId check, and a slow reply triggered a retry. |
| Nothing arrives at all | Postback URL not saved on the Setup page, or your endpoint is behind auth and returns 401/403. |
| Balance goes up on a cancellation | You are ignoring status and treating every call as an add. |
Open a ticket from your panel with the transId and we can trace the exact call in our log.