diff --git a/package.json b/package.json
index 96739c5..65d2b15 100644
--- a/package.json
+++ b/package.json
@@ -24,6 +24,7 @@
     "sate24": "git+http://gitlab.kodesumber.com/reload97/node-sate24.git",
     "sate24-expresso": "git+http://gitlab.kodesumber.com/reload97/sate24-expresso.git",
     "strftime": "^0.9.2",
-    "winston": "^2.2.0"
+    "winston": "^2.2.0",
+    "xml2js": "^0.4.16"
   }
 }
diff --git a/partner-trustlink.js b/partner-trustlink.js
new file mode 100644
index 0000000..75eb3a0
--- /dev/null
+++ b/partner-trustlink.js
@@ -0,0 +1,164 @@
+var winston = require('winston');
+var request = require('request');
+var strftime = require('strftime');
+var url = require('url');
+var xor = require('base64-xor');
+var http = require('http');
+var xml2js = require('xml2js').parseString;
+
+var max_retry = 3;
+var sleep_before_retry = 2000;
+
+var config;
+var callbackReport;
+var aaa;
+var logger;
+var options;
+
+function start(_config, _callbackReport, options) {
+    config = _config;
+    callbackReport = _callbackReport
+    
+    if (options && options.aaa) {
+            aaa = options.aaa;
+    }
+    
+    if (options && options.logger) {
+        logger = options.logger;
+    } else {
+        logger = new winston.Logger({
+            transports: [
+              new (winston.transports.Console)()
+            ]
+        });
+    }
+    
+    createReverseReportServer();
+}
+
+function createReverseReportServer() {
+    var httpServer = http.createServer(onReverseReport).listen(config.h2h_out.listen_port, function() {
+        logger.info('HTTP Reverse/Report server listen on port ' + config.h2h_out.listen_port);
+    });
+}
+
+function onReverseReport(req, res) {
+    res.end('OK');
+        
+    var qs = url.parse(req.url, true).query;
+    logger.info('Reverse Report', {qs: qs});
+}
+
+function calculateSignature(ts, destination, password) {
+    var a = ts + destination.substr(destination.length - 4);
+    var b = destination.substr(destination.length - 4).split('').reverse().join('') + password;
+    
+    return xor.encode(a,b);
+}
+
+function createXmlPayload(task, userid, password) {
+    var ts = strftime('%H%M%S', new Date());
+    
+    var signature = calculateSignature(ts, task.destination, password);
+    
+    var payload = {
+        evoucher: [
+            {command: 'TOPUP'},
+            {product: task.remoteProduct},
+            {userid: userid},
+            {time: ts},
+            {msisdn: task.destination},
+            {partner_trxid: task.requestId},
+            {signature: signature},
+            {trxke: 1},
+        ]
+    };
+    
+    if (logger) {
+        logger.verbose('Generate xml payload', {payload: payload});
+    }
+    
+    return "<?xml version=\"1.0\" ?>\n" + xml(payload);
+}
+
+function topupRequest(task, retry) {
+    if (retry === undefined) {
+        retry = max_retry;
+    }
+    
+    var payload = createXmlPayload(task, config.globals.userid, config.globals.password);
+    
+    var partner = url.parse(config.h2h_out.partner);
+    
+    var request_options = {
+        host: partner.hostname,
+        path: partner.path,
+        port: partner.port,
+        method: "POST",
+        headers: {
+            'Content-Type': 'text/xml',
+            'Content-Length': Buffer.byteLength(payload)
+        }
+    };
+    
+    var buffer = "";
+    
+    logger.info('Requesting to partner', {request_options: request_options});
+    
+    var req = http.request(request_options, function( res )    {
+
+        logger.info('Status code: ' + res.statusCode );
+        var buffer = "";
+        res.on( "data", function( data ) { buffer = buffer + data; } );
+        res.on( "end", function( data ) {             
+            //directResponseHandler(buffer, task);
+            logger.info('Got direct response from partner', {resp: buffer});
+        });
+
+    });
+
+    req.on('error', function(e) {
+        logger.warn('problem with request: ' + e.message);
+        callbackReport(task.requestId, '68', e.message);
+        return;
+    });
+
+    logger.verbose('Sending payload to partner', {payload: payload});
+    req.write( payload );
+    req.end();
+}
+
+function directResponseHandler(body, task) {
+
+    logger.info('Got direct response');
+
+    xml2js(body, function (err, result) {
+        if (err) {
+            logger.warn('Error parsing xml', {body: body});
+            callbackReport(request_id, '68', buffer);
+            return;
+        }
+        
+        logger.info('Direct response parsed', {result: result});
+        
+        var response_code = '68';
+        
+        var request_id = result.evoucher.partner_trxid[0].trim();
+        var message = result.evoucher.message[0].trim();
+        var status = result.evoucher.result[0].trim();
+        
+        if (status === 'failed') {
+            response_code = '40';
+            
+            var new_response_code = responseCodeFromMessage(message);
+            if (new_response_code) {
+                response_code = new_response_code;
+            }
+
+        }
+        
+        callbackReport(request_id, response_code, message);
+    });
+}
+
+export.start = start;