A postback is a server-to-server request EdgeCash sends to your endpoint the moment a transaction fires on your traffic — a conversion, a milestone completion, a reversal. It is the reliable way to credit your users: no pixels, no client-side tracking, just your server hearing from ours.
Scopes: which postback fires
You can configure postbacks at three levels — Global (the whole account), per Offer Wall (one placement) and per Offer. The most specific rule wins: per-Offer beats per-OfferWall beats Global.
Delivery methods
- GET — your URL template is taken verbatim, the macros in it are replaced with transaction values, and the resulting URL is requested. Supports signing.
- POST (JSON) — your URL is requested as-is, and the request body is a JSON object with the full fixed field set.
- POST (Form) — same as POST (JSON) but the fields arrive as form data.
Example GET postback
https://api.example.com/postback
?offerid=[OID]
&rate=[PAY]
&sub1=[SB1]
&ip=[IP]
&status=[STS]
&hash=[HSH=MyPrivateKey]offerid=[OID]&rate=[PAY]&sub1=[SB1]&ip=[IP][/HSH]
The parameter names on your side (offerid, rate, …) are
yours to choose — only the bracketed macros are ours. [SB1] echoes back
the subid1 user identifier you passed on the wall URL or API request.
Signing and verification
Wrap any part of a GET postback URL in [HSH=KEY]...[/HSH] and EdgeCash
replaces the whole block with a signature of the enclosed content — an HMAC-MD5 with
your key, computed after all other macros are expanded. Recompute the same hash on
your server and reject requests that don't match — that is how you know a postback
really came from EdgeCash:
$key = 'MyPrivateKey';
$content = 'offerid=' . $_GET['offerid']
. '&rate=' . $_GET['rate']
. '&sub1=' . $_GET['sub1']
. '&ip=' . $_GET['ip'];
$expected = hash_hmac('md5', $content, $key);
if (! hash_equals($expected, $_GET['hash'] ?? '')) {
http_response_code(403);
exit('Invalid signature');
}
// signature OK — credit the user
import hmac, hashlib
from flask import request, abort
KEY = b'MyPrivateKey'
content = (
f"offerid={request.args['offerid']}"
f"&rate={request.args['rate']}"
f"&sub1={request.args['sub1']}"
f"&ip={request.args['ip']}"
).encode()
expected = hmac.new(KEY, content, hashlib.md5).hexdigest()
if not hmac.compare_digest(expected, request.args.get('hash', '')):
abort(403, 'Invalid signature')
# signature OK — credit the user
import crypto from 'node:crypto';
const KEY = 'MyPrivateKey';
export function verify(req, res, next) {
const { offerid, rate, sub1, ip, hash } = req.query;
const content = `offerid=${offerid}&rate=${rate}&sub1=${sub1}&ip=${ip}`;
const expected = crypto
.createHmac('md5', KEY)
.update(content)
.digest('hex');
const ok =
expected.length === (hash ?? '').length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(hash ?? ''));
if (! ok) return res.status(403).send('Invalid signature');
next();
}
package main
import (
"crypto/hmac"
"crypto/md5"
"encoding/hex"
"net/http"
)
const key = "MyPrivateKey"
func verify(w http.ResponseWriter, r *http.Request) {
q := r.URL.Query()
content := "offerid=" + q.Get("offerid") +
"&rate=" + q.Get("rate") +
"&sub1=" + q.Get("sub1") +
"&ip=" + q.Get("ip")
mac := hmac.New(md5.New, []byte(key))
mac.Write([]byte(content))
expected := hex.EncodeToString(mac.Sum(nil))
if !hmac.Equal([]byte(expected), []byte(q.Get("hash"))) {
http.Error(w, "Invalid signature", http.StatusForbidden)
return
}
// signature OK — credit the user
}
Delivery and retries
- Respond with HTTP 200 once you have accepted the postback.
- Responses of 500 and above are retried: 3 attempts with 10 / 30 / 60 second backoff. 4xx responses are not retried.
- Reversals arrive as regular postbacks with a reversal status and negative amounts — handle them by debiting the user.
Every postback URL in the portal has a test send button and a full delivery history — you can verify your endpoint before any real traffic arrives.
Ready to start earning?
Tell us about your app, site or traffic — and start monetizing with EdgeCash.