Server to Server Tracking
From Wiki
Contents |
Server to Server Tracking
Server to Server Tracking is a mandatory component of tracking.
The requirement is that conversion data is sent (via HTTP response) directly from your server to Awin’s servers.
To build the Server to Server request, use the same parameters as the Fall-back Conversion pixel, however:
- Add the additional cks parameter (this will capture the “awc” value)
- Replace “tt=ns” with “tt=ss” so Awin processes the conversion as a S2S request
Postback Format:
<!--S2S Tracking--> https://www.awin1.com/sread.php?tt=ss&tv=2&merchant={{merchantId}}&amount={{totalAmount}}&ch=aw&parts={{commission_group}}:{{totalAmount}}&vc={{voucherCode}}&cr={{currencyCode}}&ref={{orderReference}}&testmode={{isTest}}&cks={{awc}}
Capturing the “awc”
The “awc” value is a parameter that is appended to the landing page URL by Awin to identify the source of the click.
You must configure your site to record the awc value in a cookie with both ‘Secure’ and ‘HTTPOnly’ flags when the user lands on your site. The value within this cookie should then be used to populate the “cks” parameter on conversion.
Example of cookie logic (PHP):
<!--Capture ‘awc’--> function setAwc() { if (!empty($_GET['awc'])) { setcookie("awc",$_GET['awc'],time()+ 60 * 60 * 24 * 365,"/", "example.com", true, true); } }
S2S Conversion Tracking
Once a conversion has occurred, this will set a trigger on your Server to send conversion data to Awin.
Example (cURL/PHP):
<!--S2S Tracking--> <?php $url = "https://www.awin1.com/sread.php?tt=ss&tv=2"; $url .= "&merchant=" . $merchantId; $url .= "&amount=" . $totalAmount; $url .= "&ch=aw"; $url .= "&cr=" . $currencyCode; $url .= "&ref=" . $orderReference; $url .= "&parts=" . $commission_group . ":" . $totalAmount; $url .= "&testmode=0&vc=" . $voucherCode; if (isset($awc)) { $url .= "&cks=" . $awc; // Populate the Awin click checksum if one is associated with the conversion } $c = curl_init(); curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($c, CURLOPT_RETURNTRANSFER, true); curl_setopt($c, CURLOPT_URL, $url); curl_exec($c); curl_close($c); ?>
Tracking Values | Description |
{{merchantId}} | Advertiser ID |
{{totalAmount}} | The total transaction amount set to two decimal places. Example: 10.99 or 10.00 / If the transaction is lead based, this value must be pre-set as 1.00 |
{{currencyCode}} | To be populated with the ISO currency code of the currency that was used in the transaction e.g. GBP |
{{orderReference}} | A unique booking/order reference ID per order |
{{commission_group}}:{{totalAmount}} | The commission group and corresponding amount based on the product being purchased, separated by the character ‘:’ / If a single commission group is used, the commission code will be DEFAULT e.g. DEFAULT:10.00. An example is given in the next topic of this guide |
{{voucherCode}} | The voucher code used in the transaction e.g. 10%_OFF |
{{awc}} | The awc is an Awin click ID we reference back to data on the advertiser, the publisher, the creative and timestamp of the click |
{{isTest}} | An Awin test flag, which when populated with "0" implies tracking is in live mode or alternatively "1" if in test mode. When set to the latter, the incoming tracking requests will not be processed by Awin for publisher commissions |
Multiple Commission Groups
The &parts= parameter should receive a variable that returns the Commission Group Code and the total amount to be used in the calculation of the commission. If you only use a single commission structure, use the commission group code "DEFAULT", followed by the total paid by the user, the same variable used in the "amount" parameter, excluding shipping and any other extra fees.
...&parts=DEFAULT:{totalAmount}.....
In case you use multiple commission group structures in the Awin platform, for example, different commissions based on product category, you will need to separate the values that feed the "parts" parameter with a pipe separator |, for example:
If a user made a purchase with two products, one product costs $25.00 in the "Shoes" category, and another product costing $30.00 in the "Shirts" category, the "parts" parameter should receive the following values:
...&amount=55.00&parts=SHOES:25.00|SHIRTS:30.00...
And in this case, the "amount" parameter, should receive "55.00". Because the sum of the values in the commission groups, should be the same as the value in the "amount" parameter.
Other S2S Code Examples
Below are example of S2S implementations in languages other than PHP (above)
ASP .NET (C#) Implementation example
Landing Page
private void writeAwcCookie() { // Check if awc query parameter is present in the url. if (Request.QueryString["awc"]) { // Create a cookie. HttpCookie cookie = new HttpCookie("_awin_awc"); // Set cookie value to the value of awc query parameter. cookie.Value = Request.QueryString["awc"]; // Set cookie to expire in ... cookie.Expires = DateTime.Now.AddDays(30d); // Set httponly cookie.HttpOnly = true; // Set secure cookie.Secure = true; // Insert the cookie in the current HttpResponse. Response.Cookies.Add(cookie); } }
Checkout Page
private void awinRequest() { var awCookie = Request.Cookies.Get("_awin_awc"); // Check if _awin_awc cookie is present. //Build the s2s request URL. //If advertiser uses deduplication (last click), complete request generation must be embedded in If statement, if (awCookie) {var url .... response.Close();} var url = "https://www.awin1.com/sread.php?tt=ss&tv=2&merchant=ADVERTISER_ID_HERE" + "&amount=" + {amount} + "&ch=aw" + "&cr=" + {currencyCode} + "&ref=" + {orderId} + "&parts=DEFAULT:" + {amount} + "&vc=" + {voucherCode} + "&cks=" + awCookie; // Create a request for the URL. WebRequest request = WebRequest.Create(url); // Add referer request.Referer = "https://www.mydomain.com"; // Get the response. WebResponse response = request.GetResponse(); using (Stream dataStream = response.GetResponseStream()) { StreamReader reader = new StreamReader(dataStream); string responseFromServer = reader.ReadToEnd(); } response.Close(); }
Ruby on Rails Implementation example
Landing Page
# check if awc query parameter is present in the url if params[:awc] # create a cookie cookies[:_awin_awc] = { value: params[:awc], expires: 1.year.from_now, domain: 'domain.com', secure: true, httponly: true } end
Checkout Page
require 'net/https' # Build the s2s request URL url = URI.parse('https://www.awin1.com/sread.php?tt=ss&tv=2&merchant=8771&amount=' + 'totalAmount' + '&ch=aw&cr=EUR&parts=' + 'CommissionGroup' + ':' + 'totalAmount' + '&ref=' + 'orderReference' + '&vc=' + 'voucherCode' + '&cks=' + cookies[:awc]) req = Net::HTTP::Get.new(url.to_s) req['Referer'] = "https://www.mydomain.com"; res = Net::HTTP.start(url.host, url.port, :use_ssl => true) {|http| http.request(req) }
Java Implementation example
Landing Page
//get awc and write a cookie on the landing page if (request.getParameter("awc") != null) { // Create a cookie Cookie cookie = new Cookie("_awin_awc", request.getParameter("awc")); // setDomain() method cookie.setDomain(".yourdomain.com"); // setMaxAge() method cookie.setMaxAge(60*60*24*365); // setSecure() method cookie.setSecure(true); // setHttPonly() method cookie.setHttpOnly(true); // add the cookie to the response response.addCookie(cookie); }
Checkout Page
//get all cookies Cookie[] cookies = request.getCookies(); String awc = ""; if (cookies != null) { for (Cookie cookie : cookies) { if (cookie.getName().equals("_awin_awc")) { awc = cookie.getValue(); } } } //build the request url URL obj = new URL("https://www.awin1.com/sread.php?tt=ss&tv=2&merchant=8771&amount=1&ch=aw&cr=EUR&parts=CG:1&ref=11111&vc=&cks=" + awc); //generate request HttpURLConnection con = (HttpURLConnection) obj.openConnection(); con.setRequestProperty ("Referer", "https://www.mydomain.com"); con.setRequestMethod("GET"); int responseCode = con.getResponseCode(); System.out.println("GET Response Code :: " + responseCode);
Python Implementation example
Landing Page
from urlparse import urlparse from http import cookies def setcookie(name, value, expiresDays, domain): morsel = Morsel() name, value = safestr(name), safestr(value) morsel.set(name, value, quote(value)) morsel['max-age'] = expiresDays * 86400 #86400 sec is 1 day morsel['domain'] = "topleveldomain" morsel['secure'] = True value = morsel.OutputString() value += '; httponly' header('Set-Cookie', value) # get awc and write a cookie on the landing page url = urlparse('requestUrl') for i in url.query.split('&'): # if awc is present in the url if "awc" in i: awc = i.split("=") # drop a cookie setcookie("awcCookie", awc[1],30, "topleveldomain") break
Checkout Page
import urllib2 from os import environ import cgi, cgitb # retrieve cookies and find awc if environ.has_key('HTTP_COOKIE'): for cookie in map(strip, split(environ['HTTP_COOKIE'], ';')): (key, value ) = split(cookie, '='); if key == "awc": awc = value else: awc = "" # build the request url and generate request request = urllib2.Request("https://www.awin1.com/sread.php?tt=ss&tv=2&merchant="+"{merchantId}"+"&amount="+"{amount}"+"&ch=aw&cr="+"{currency}"+"&parts="+"{commissionBreakdown}"+"&ref="+"{orerReference}"+"&vc="+"{voucherCode}"+"&cks="+awc) request.add_header('Referer', 'https://www.mydomain.com') r = urllib2.urlopen(request)