Key takeaways

  • A postback macro is a placeholder in your postback URL that the sending platform replaces with a real value, such as a user ID or reward, each time it calls your server.
  • You choose the parameter names in your URL, but the macro names must match the platform's list exactly, or the value arrives empty or as literal text.
  • Always include the transaction ID, status, and hash macros, so you can credit once, handle reversals, and reject calls that did not come from the platform.

What is a postback macro?

A postback macro is a placeholder in a postback URL, such as {transaction_id} or {user_id}, that the sending platform replaces with a real value every time it calls your server. You save the URL once with the macros in it. When a conversion is credited or reversed, the network fills in each macro and sends the request, so your server receives the actual user ID, reward, status, and signature as ordinary URL parameters.

Macros are the vocabulary of a postback. The postback URL itself, and why it is a server call and not a browser pixel, is covered in What is a postback URL? and server-to-server tracking. This page is about the placeholders.

How postback macros work

A postback URL has two halves in every parameter: a name you pick, and a macro the platform defines.

https://yoursite.com/postback?user={user_id}&tx={transaction_id}&status={status}&reward={reward}&hash={hash}
  1. You save the template. The left side of each pair (user, tx) is your own parameter name. The right side ({user_id}) is the macro.
  2. A conversion happens. A user completes an offer, or a credited offer is reversed later.
  3. The platform substitutes. It swaps each macro for the value of that transaction and URL-encodes it.
  4. It calls your URL. Your server reads the parameters by your names, checks the signature, and acts on the status.

Filled in, the call above could look like this (illustrative values):

https://yoursite.com/postback?user=4821&tx=9f3a71c2&status=1&reward=250&hash=ba660f3c...

In “postback URL parameters”, the parameter is the name your server reads and the macro is where the value comes from. A macro that is misspelled is usually not replaced, so your server receives the literal text {userid} or an empty value.

The Moonetix postback macro list

These are all the macros Moonetix fills in, taken from the Moonetix postback reference. Use the ones you need, in any order and with any parameter names. Values are URL-encoded.

MacroWhat it contains
{user_id}The user ID you put in the offerwall link.
{transaction_id}Stays the same for the whole life of a transaction: the credit and a later reversal carry the same value.
{event_id}Unique for every event sent. Useful for logging.
{status}What happened, as a number: 1 or 2.
{state}The same as {status} in words: credited or reversed.
{reward}The reward in your currency, after your conversion rate, user split, bonus, and rounding. Never negative.
{currency}The name of your currency, for example Coins.
{payout}What you earn for the transaction, in US dollars. Never negative.
{offer_id}The ID of the offer.
{offer_name}The name of the offer as your user saw it.
{country}Two-letter country code of the user.
{device}desktop, android, or ios.
{ip}The IP address the user started the offer from.
{sub1} to {sub5}The sub IDs you added to the offerwall link, the Offers API request, or the SDK session, or empty.
{integration}How the user reached the offer: offerwall (link, iframe, or floating button), api (Offers API), or sdk (the mobile SDKs).
{hash}Signature to check that the postback comes from Moonetix.

Sub IDs are the way to carry your own tracking values, such as a traffic source or placement, through to the postback. Click IDs and sub IDs explains how to use them, and the offerwall link builder adds them to a link for you.

Status values

{status}{state}What to do
1creditedAdd {reward} to the user, once per transaction_id.
2reversedTake {reward} back, if you credited this transaction before. Otherwise ignore it.

Amounts are never negative: the status tells you whether to add or subtract. The same event can arrive twice after a retry, so store each transaction_id with the last status you processed. How to prevent duplicate reward credits shows the pattern.

The hash macro

{hash} is the HMAC-SHA256, as lowercase hex, of transaction_id:user_id:reward:status (the four values joined with colons), signed with your postback secret key from the app’s Integration tab. HMAC itself is defined in RFC 2104, a keyed hash that proves the sender knew the shared secret. Recompute it on your server from the values exactly as they arrived, and reject the call if it does not match. The postback secret key is different from the link hash salt. What is HMAC? explains the idea, and the postback hash checker lets you test one by hand.

Worked example: one offer, two postbacks

All values here are illustrative. A user with ID 4821 completes an offer. Your app pays 250 Coins for it, and your secret key is example-secret-key.

The credit. Moonetix calls:

https://yoursite.com/postback?user=4821&tx=9f3a71c2&status=1&reward=250&hash=ba660f3c483ffd15b84ce6f386a8296a293e9f6725c7796dc4715964644ce62b

Your server builds the string 9f3a71c2:4821:250:1, computes its HMAC-SHA256 with the key, gets the same hex string, sees no earlier status for 9f3a71c2, adds 250 Coins, and saves status 1.

The reversal. Weeks later the advertiser rejects the conversion. The next call has the same tx=9f3a71c2 and reward=250, but status=2 and a new hash. Your server checks the hash, finds status 1 stored, subtracts 250 Coins, and saves status 2. If the same reversal arrives again, the stored status 2 tells you to skip it.

Without the {transaction_id} macro in your URL, step two is impossible: you would not know which credit to undo.

Macro syntax on other platforms

Placeholders that a platform fills in are common across ad tech, but the syntax and names differ, so copy them from each platform’s own docs. Two official examples, both for click URLs rather than postbacks:

PlatformSyntaxExampleUsed in
MoonetixCurly braces{transaction_id}Postback URL to your server
Google Ads (ValueTrack)Curly braces{lpurl}?matchtype={matchtype}Tracking templates and final URLs
TikTok Ads ManagerDouble underscores, uppercase__CAMPAIGN_ID__, __CID__URL parameters on ad clicks

Google documents ValueTrack parameters such as {lpurl} and {gclid} in Set up tracking with ValueTrack parameters. TikTok lists __CAMPAIGN_ID__ (campaign ID) and __CID__ (creative ID) in About UTM Parameters. For how click-side parameters relate to UTM tags, see UTM parameters explained. The lesson for postbacks: a macro from one platform means nothing to another.

Common postback macro mistakes

Mistakes that cost credits or money

Leaving out {transaction_id}, so reversals and retries cannot be matched. Leaving out {hash}, so anyone who guesses the URL can credit themselves. Misspelling a macro, such as {userid}, so the literal text arrives. Crediting {payout} (your US dollar earnings) instead of {reward} (the user’s amount). Converting {reward} again with your own rate, which double counts.

  • Reformatting values before hashing. If your code turns 250 into 250.00 before building the hash string, the signature never matches. Use the values exactly as received.
  • Treating status 2 as an error. A reversal is a normal event. Answer it with a 2xx and subtract the reward.
  • Logging nothing. Store {event_id} with each call, so support questions can be traced to one request.
  • Relying on IP alone. An IP allowlist is a useful extra layer, as postback IP allowlists explains, but always verify the hash too.

A safe minimum

Include {user_id}, {transaction_id}, {status}, {reward}, and {hash}. Add {event_id}, {offer_name}, and {sub1} to {sub5} when you want logs and reports by source.

Where an offerwall fits

On an offerwall, macros are how the reward reaches your user. Moonetix is a pay-per-result affiliate network: your users complete offers on the Moonetix offerwall, and every credit and reversal arrives at your server as a signed server-to-server postback with these macros filled in. Your server is the only place that should add currency. Ready-made handlers exist for Node.js and Python, and webhook vs postback covers how this differs from JSON webhooks. What {reward} means depends on your virtual currency settings.

Moonetix postbacks in practice

Each Moonetix app has one postback URL with the macros you choose. Credits arrive with status 1 and reversals with status 2 and the same transaction ID, signed with HMAC-SHA256. Before going live, use “Send a test postback” on the Integration tab: tests have a transaction_id that starts with test_ and offer_id 0. Read the postback reference, see how the wall works, or get in touch.

Frequently asked questions

What is the difference between a postback macro and a parameter?

The parameter is the name your server reads, such as user. The macro is the placeholder the platform replaces, such as {user_id}. You choose the parameter names; the platform defines the macro names.

Do I have to use every macro?

No. Use only the ones you need, in any order. For safe crediting you need at least the user ID, transaction ID, status, reward, and hash.

Why does my postback show {user_id} as text?

The macro was not recognized, usually because of a typo, a different case, or a macro from another platform. Copy the exact name from the platform’s list.

What is the {hash} macro in a Moonetix postback?

The lowercase hex HMAC-SHA256 of transaction_id:user_id:reward:status, signed with your postback secret key. Recompute it and compare before you credit anything.

Can a reward macro be negative?

No. A reversal sends the same positive {reward} with status 2, and the status tells you to take it back.

How do I test my macros before launch?

Use “Send a test postback” on the app’s Integration tab and check your logs. Test your app before launch walks through the full check.