diff --git a/index.js b/index.js
index c9ea3a2..82c25cf 100644
--- a/index.js
+++ b/index.js
@@ -21,6 +21,6 @@ var options = {
 
 var httpServer = HttpServer.start(config, options);
 
-partner.start(config, aaa.callbackReport, options);
+partner.start(options);
 aaa.start(config, partner, options);
 expresso.start(options);
diff --git a/partner-sc.js b/partner-sc.js
index 94d2497..1ab9a74 100644
--- a/partner-sc.js
+++ b/partner-sc.js
@@ -27,13 +27,13 @@ var sleep_before_retry = 30000;
 var logTag = __filename.split('/').reverse()[0];
 
 function initMongoClient() {
-    if (!config.mongodb || !config.mongodb.url) {
+    if (!config.mongodbstruk || !config.mongodbstruk.url) {
         return;
     }
-    
+
     try {
-        var url = config.mongodb.url;
-    
+        var url = config.mongodbstruk.url;
+
         mongoClient.connect(url, function(err, db) {
             if (err) {
                 logger.warn('Failed to connect to mongodb', {err: err});
@@ -46,112 +46,112 @@ function initMongoClient() {
     catch(err) {
         logger.warn('Exception when connecting to mongodb', {err: err, url: url});
     }
-    
+
 }
 
 function prepareResultData(result) {
     var task;
-    
+
     var data = {};
     data.gateway = config.globals.gateway_name;
-    
+
     try {
         data.requestId = result.reffid[0].trim();
-        
+
         var key = config.globals.gateway_name + '.rid:' + data.requestId;
         task = tasks.get(key);
     }
     catch(err) { data.requestId = null; }
-    
+
     try {
         data.status = result.ResultCode[0].trim();
     }
     catch(err) { data.status = '68' }
-    
+
     try {
-        data.rcmessage = result.ErrorMsg[0].trim();                        
+        data.rcmessage = result.ErrorMsg[0].trim();
     }
     catch(err) { data.rcmessage = ''; }
-    
+
     try {
-        data.resptext = '';                        
+        data.resptext = '';
     }
     catch(err) { data.resptext = ''; }
-    
+
     try {
         var ts = moment(task.timestamp, 'YYYYMMDDHHmmss').format('YYYY-MM-DD HH:mm:ss')
         data.dt = ts;
     }
-    catch(err) { 
+    catch(err) {
         logger.warn('Exception when getting timestamp data, using current timestamp', {err: err, result: result, task: task});
-        data.dt = strftime('%Y-%m-%d %H:%M:%S', new Date()); 
+        data.dt = strftime('%Y-%m-%d %H:%M:%S', new Date());
     }
-    
+
     try {
         data.namapel = result.nama_pel[0].trim();
     }
     catch(err) { data.namapel = 'UNKNOWN'; }
-    
+
     try {
         data.msn = result.nsm[0].trim();
     }
     catch(err) { data.msn = 'UNKNOWN'; }
-    
+
     try {
         data.idpel = result.idpel[0].trim();
     }
     catch(err) { data.idpel = 'UNKNOWN'; }
-    
+
     try {
         data.tarifdaya = result.tarif[0].trim();
     }
     catch(err) { data.tarifdaya = 'UNKNOWN'; }
-    
+
     try {
         data.admin = parseInt(result.adminfee[0].trim());
     }
     catch(err) { data.admin = 0; }
-    
+
     try {
         data.adm = parseInt(result.admin_fee[0].trim());
     }
     catch(err) { data.adm = 0; }
-    
+
     try {
         data.hargapelanggan = parseInt(result.amount_trx[0].trim());
     }
     catch(err) { data.hargapelanggan = 0; }
-    
+
     try {
         data.jumlahkwh = result.jml_daya[0].trim();
     }
     catch(err) { data.jumlahkwh = 0; }
-    
+
     try {
         data.token = result.token[0].trim();
     }
     catch(err) { data.token = 0; }
-    
+
     try {
         data.ppn = result.ppn_fee[0].trim();
     }
     catch(err) { data.ppn_fee = 0; }
-    
+
     try {
         data.ppj = result.ppj_fee[0].trim();
     }
     catch(err) { data.ppj = 0; }
-    
+
     try {
         data.angsuran = result.angsuran_fee[0].trim();
     }
     catch(err) { data.angsuran = 0; }
-    
+
     try {
         data.meterai = result.materai_fee[0].trim();
     }
     catch(err) { data.materai_fee = 0; }
-    
+
     return data;
 }
 
@@ -159,19 +159,19 @@ function saveTokenToMongoDb(result) {
     if (!mongodb) {
         return;
     }
-    
-    if (!config.mongodb) {
+
+    if (!config.mongodbstruk) {
         return;
     }
-    
-    if (!config.mongodb.collection) {
+
+    if (!config.mongodbstruk.collection) {
         return;
     }
-    
+
     data = prepareResultData(result);
 
     try {
-        mongodb.collection(config.mongodb.collection).insertOne(data);
+        mongodb.collection(config.mongodbstruk.collection).insertOne(data);
     }
     catch(err) {
         logger.warn('Error when inserting data to mongodb', {err: err, data: data});
@@ -180,7 +180,7 @@ function saveTokenToMongoDb(result) {
 
 function putTaskToCache(task) {
     var key = config.globals.gateway_name + '.rid:' + task.requestId;
-    
+
     try {
         tasks.set(key, task);
     }
@@ -190,16 +190,17 @@ function putTaskToCache(task) {
 }
 
 function topupRequest(task) {
+    aaa.insertTaskToMongoDb(task);
     putTaskToCache(task);
-    
+
     var ts = strftime('%Y%m%d%H%M%S', new Date());
-    
-    var data = 
-        config.h2h_out.userid 
-        + '|' + config.h2h_out.password 
-        + '|' + task['remoteProduct'] 
+
+    var data =
+        config.h2h_out.userid
+        + '|' + config.h2h_out.password
+        + '|' + task['remoteProduct']
         + '|' + task['destination'] + '|0';
-    
+
     var options = {
         url: config.h2h_out.partner,
         qs: {
@@ -215,16 +216,16 @@ function topupRequest(task) {
         var responseMessage = 'Gateway Error';
 
         if (error) {
-            
+
             logger.warn('HTTP REQUEST ERROR', error);
             callbackReport(task['requestId'], '89', 'HTTP REQUEST ERROR (' + error + ')');
-            
+
         } else if (response.statusCode != 200) {
-            
+
             var error_message = 'GATEWAY ERROR (HTTP RESPONSE CODE: ' + response.statusCode + ')';
             logger.warn(error_message);
             callbackReport(task['requestId'], '91', error_message);
-            
+
         } else {
 
             logger.info('DIRECT RESPONSE', {body: body});
@@ -235,9 +236,9 @@ function topupRequest(task) {
                 } else {
                     var directResponse = result;
                     logger.info(directResponse);
-                    
+
                     saveTokenToMongoDb(directResponse.Result);
-                    
+
                     try {
                         var result_price;
                         try {
@@ -246,7 +247,7 @@ function topupRequest(task) {
                         catch(err) {
                             result_price = 0;
                         }
-                        
+
                         var result_error_message;
                         try {
                             result_error_message = directResponse.Result.ErrorMsg[0].trim();
@@ -254,10 +255,10 @@ function topupRequest(task) {
                         catch(err) {
                             result_error_message = '';
                         }
-                        
+
                         var resultCode = directResponse.Result.ResultCode[0].trim();
-                        
-                        responseMessage = 
+
+                        responseMessage =
                             'ResultCode: ' + resultCode
                             + ' | ErrorMsg: ' + result_error_message
                             + ' | DateTime: ' + directResponse.Result.DateTime[0].trim()
@@ -272,49 +273,49 @@ function topupRequest(task) {
                             + ' | Price: ' + result_price
                             + ' | EndBalance: ' + directResponse.Result.EndBalance[0].trim()
                             ;
-                            
+
                         logger.info('Response message: ' + responseMessage);
-                        
+
                         if (aaa) {
                             // update balance
                             aaa.updateBalance(directResponse.Result.EndBalance[0]);
                         }
-                        
+
                         if (resultCode == '0000') {
                             var nama_pelanggan = directResponse.Result.nama_pel[0].trim();
                             nama_pelanggan =  nama_pelanggan.replace(/-\/-/g, '-');
                             var sn = directResponse.Result.token[0].trim() + '/' + nama_pelanggan + '/' + directResponse.Result.tarif[0].trim() +  'VA/' + directResponse.Result.jml_daya[0].trim();
                             sn = sn.replace(/\s/g, '-');
-                            
+
                             responseMessage = 'SN=' + sn + '; ' + responseMessage;
                             logger.info('New response message: ' + responseMessage);
                         }
-                        
+
                         var pendingResultCode = ['0005', '0012', '0068', '0090', '0063', '0018', '0096'];
                         if (pendingResultCode.indexOf(resultCode) != -1) {
                             callbackReport(task['requestId'], '68', responseMessage);
-                            
+
                             logger.info('Got pending status, requesting advice from webreport in ' + sleep_before_retry + 'ms');
                             setTimeout(function () {
                                 cekstatus.advice({trxid: directResponse.Result.TransID[0].trim()}, callbackFromWebReport);
                             }, sleep_before_retry);
-                            
+
                             return;
                         }
-                        
+
                         responseCode = resultCode.replace(/^00/, "");
-                        
+
                         if (result_error_message == 'Inq - APLICATION SERVER RESPONSE TIMEOUT') {
                             responseCode = '91';
-                        }                        
-                        
+                        }
+
                     }
                     catch(err) {
                         responseCode = '40';
                         responseMessage = 'Invalid response from gateway';
                     }
                 }
-                
+
                 callbackReport(task['requestId'], responseCode, responseMessage);
             });
         }
@@ -328,181 +329,181 @@ function callbackFromWebReport(status) {
         logger.warn('Advice from webreport return empty status');
         return;
     }
-    
+
     logger.info('Got advice result from webreport', {status: status});
-    
+
     var responseCode = '68';
-    
+
     var result_price = 0;
     try {
         result_price = directResponse.Result.Price[0].trim();
     }
     catch(err) {}
-    
+
     var errorMsg = '';
     try {
         errorMsg = status.response.errormsg[0];
     }
     catch(err) {}
-    
+
     var responseMessage = '';
     try {
-        responseMessage = 
+        responseMessage =
             'Hasil advice dari webreport '
             + 'ResultCode: ' + status.response.resultcode[0]
     }
     catch(err) {
         logger.warn('Error parsing ResultCode from webreport advice.', {err: err});
     }
-    
+
     try {
-        responseMessage = 
+        responseMessage =
             responseMessage
             + ' | ErrorMsg: ' + errorMsg
     }
     catch(err) {
         logger.warn('Error parsing ErrorMsg from webreport advice.', {err: err});
     }
-    
+
     try {
-        responseMessage = 
+        responseMessage =
             responseMessage
             + ' | TrxDate: ' + status.trxDate;
     }
     catch(err) {
         logger.warn('Error parsing TrxDate from webreport advice.', {err: err});
     }
-    
+
     try {
-        responseMessage = 
+        responseMessage =
             responseMessage
             + ' | UpdateDate: ' + status.updateDate;
-    
+
     }
     catch(err) {
         logger.warn('Error parsing UpdateDate from webreport advice.', {err: err});
     }
-    
+
     try {
-        responseMessage = 
+        responseMessage =
             responseMessage
             + ' | nsm: ' + status.response.nsm[0];
     }
     catch(err) {
         logger.warn('Error parsing nsm from webreport advice.', {err: err});
     }
-    
+
     try {
-        responseMessage = 
+        responseMessage =
             responseMessage
             + ' | idpel: ' + status.response.idpel[0];
     }
     catch(err) {
         logger.warn('Error parsing idpel from webreport advice.', {err: err});
     }
-    
+
     try {
-        responseMessage = 
+        responseMessage =
             responseMessage
             + ' | reffid: ' + status.response.reffid[0].trim();
     }
     catch(err) {
         logger.warn('Error parsing reffid from webreport advice.', {err: err});
     }
-    
+
     try {
-        responseMessage = 
+        responseMessage =
             responseMessage
             + ' | TransID: ' + status.response.transid[0].trim();
     }
     catch(err) {
         logger.warn('Error parsing TransID from webreport advice.', {err: err});
     }
-    
+
     try {
-        responseMessage = 
+        responseMessage =
             responseMessage
             + ' | reff_switching: ' + status.response.reff_switching[0];
     }
     catch(err) {
         logger.warn('Error parsing reff_switching from webreport advice.', {err: err});
     }
-    
+
     try {
-        responseMessage = 
+        responseMessage =
             responseMessage
             + ' | amount_trx: ' + status.response.amount_trx[0];
     }
     catch(err) {
         logger.warn('Error parsing amount_trx from webreport advice.', {err: err});
     }
-    
+
     try {
-        responseMessage = 
+        responseMessage =
             responseMessage
             + ' | token: ' + status.response.token[0];
     }
     catch(err) {
         logger.warn('Error parsing token from webreport advice.', {err: err});
     }
-    
+
     try {
-        responseMessage = 
+        responseMessage =
             responseMessage
             + ' | PrevBalance: ' + status.response.prevbalance[0];
     }
     catch(err) {
         logger.warn('Error parsing PrevBalance from webreport advice.', {err: err});
     }
-    
+
     try {
-        responseMessage = 
+        responseMessage =
             responseMessage
             + ' | Price: ' + status.amount;
     }
     catch(err) {
         logger.warn('Error parsing Price from webreport advice.', {err: err});
     }
-    
+
     try {
-        responseMessage = 
+        responseMessage =
             responseMessage
             + ' | EndBalance: ' + status.response.endbalance[0];
     }
     catch(err) {
         logger.warn('Error parsing EndBalance from webreport advice.', {err: err});
     }
-    
-    
+
+
     if ((status.status == 'S') && (status.response.resultcode[0] == '0000')) {
         responseCode = '00';
-        
+
         var nama_pelanggan = status.response.nama_pel[0] ;
         nama_pelanggan =  nama_pelanggan.replace(/-\/-/g, '-');
-        
+
         var sn = status.response.token[0] + '/' + nama_pelanggan + '/' + status.response.tarif[0] + 'VA/' + status.response.jml_daya[0];
         responseMessage = 'SN=' + sn + '; ' + responseMessage;
-    
+
     } else if ((status.status == 'P') || (status.status == 'W')) {
-        
+
         callbackReport(status.response.reffid[0].trim(), '68', responseMessage);
         logger.info('Got pending status, requesting advice from webreport in ' + sleep_before_retry + 'ms');
-        
+
         setTimeout(function () {
-            
+
             cekstatus.advice({trxid: status.trxId,}, callbackFromWebReport);
-            
+
         }, sleep_before_retry);
         return;
-        
+
     } else {
         responseCode = status.response.resultcode[0].replace(/^00/, "");
         if (['00', '05', '12', '68', '90', '63', '18', '96'].indexOf(responseCode) >= 0) {
             responseCode = '40';
         }
     }
-    
-    
+
+
     callbackReport(status.response.reffid[0].trim(), responseCode, responseMessage);
 }
 
@@ -510,37 +511,50 @@ function createHttpReportServer() {
     var httpServer = http.createServer(function(request, response) {
         var qs = url.parse(request.url, true).query;
         var path = url.parse(request.url).pathname;
-        
+
         logger.info('Got reverse report from partner', {path: path, qs: qs});
         response.end('OK');
-        
+
         var  trxid;
         try {
             trxid = qs.transid;
         }
         catch(err) {
         }
-        
+
         if (trxid) {
             logger.info('Requesting advice from webreport', {trxid: trxid})
             cekstatus.advice({trxid: trxid}, callbackFromWebReport);
         }
-        
+
     });
-    
+
     httpServer.listen(config.h2h_out.listen_port, function() {
         logger.info('HTTP Reverse/Report server listen on port ' + config.h2h_out.listen_port);
     });
 }
 
-function start(_config, _callbackReport, options) {
-    config = _config;
-    callbackReport = _callbackReport;
-    
-    if (options && options.aaa) {
-            aaa = options.aaa;
+function start(options) {
+    if (!options) {
+        console.log('Undefined options, terminating....');
+        process.exit(1);
+    }
+
+    if (options.config) {
+        config = options.config;
+    } else {
+        console.log('Undefined options.config, terminating....')
+        process.exit(1);
+    }
+
+    if (options.aaa) {
+        aaa = options.aaa;
+        callbackReport = options.aaa.callbackReportWithPushToMongoDb;
+    } else {
+        console.log('Undefined options.aaa, terminating....')
+        process.exit(1);
     }
-    
+
     if (options && options.logger) {
         logger = options.logger;
     } else {
@@ -550,7 +564,7 @@ function start(_config, _callbackReport, options) {
             ]
         });
     }
-    
+
     createHttpReportServer();
     initMongoClient();
 }