var winston = require('winston'); var soap = require('soap'); var crypto = require('crypto'); var strftime = require('strftime'); var fs = require("fs"); var whiskers = require("whiskers"); var http = require("http"); var url = require("url"); process.chdir(__dirname); var soapTemplate = fs.readFileSync("message.xml"); var max_retry = 10; var sleep_before_retry = 5000; 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)() ] }); } } function topupRequest(task, retry) { if (retry === undefined) { retry = max_retry; } var remoteProduct = task.remoteProduct.split(','); var params = { userName: config.h2h_out.userid, productCode: remoteProduct[0] , terminal: 'H2HIPN10', transactionType: '50', billNumber: createBillNumber(task.destination), amount: remoteProduct[1], bit61: createBillNumber(task.destination), reff: task.requestId, timeStamp: strftime('%Y-%m-%d %H:%M:%S', new Date()) } var signature = createSignature(params, config.h2h_out.password); params.signature = signature; //topupRequestSoapDIY(task, params, retry); topupRequestSoap(task, params, retry); } function topupRequestSoap(task, params, retry) { soap.createClient(config.h2h_out.partner, function(err, soapClient) { var _params = { userName: params.userName, signature: params.signature, productCode: params.productCode, terminal: params.terminal, transactionType: params.transactionType, billNumber: params.billNumber, amount: params.amount, bit61: params.bit61, reff: params.reff, timeStamp: params.timeStamp } logger.info('Requesting to service', {url: config.h2h_out.partner, params: _params}); soapClient.apih2h.apih2hPort.billpayment({ inputCheck: _params }, function(err, result) { logger.verbose( 'Got response', { lastEndpoint: soapClient.lastEndpoint, lastRequest: soapClient.lastRequest, lastMessage: soapClient.lastMessage, lastResponse: soapClient.lastResponse, } ); if (err) { logger.warn('Error requesting service', {err: err}); callbackReport(task.requestId, '68', 'something wrong'); return; } topupResponseHandler(task, result); }); }); } function topupResponseHandler(task, response) { var st24rc = '68'; var st24message = response.outputParameter.resultDesc.$value; if ( response.outputParameter.resultCode.$value == '001' ) { // product disabled st24rc = '13'; } else if ( response.outputParameter.resultCode.$value == '002' ) { // prodcode disable st24rc = '13'; } else if ( response.outputParameter.resultCode.$value == '003' ) { // duplicate reff st24rc = '55'; } else if ( response.outputParameter.resultCode.$value == '004' ) { // not enough balance st24rc = '40'; } else if ( response.outputParameter.resultCode.$value == '005' ) { // username blocked st24rc = '40'; } else if ( response.outputParameter.resultCode.$value == '006' ) { // not exists username st24rc = '40'; } else if ( response.outputParameter.resultCode.$value == '011' ) { // invalid request st24rc = '40' } else if ( response.outputParameter.resultCode.$value == '012' ) { // no route to host st24rc = '40' } else if ( response.outputParameter.resultCode.$value == '013' ) { // invalid signature st24rc = '40' } else if ( response.outputParameter.bit39.$value == '06' ) { st24rc = '40'; st24message = 'Error Transaksi ditolak karena terjadi error di H2H dengan response code diluar daftar ini. Silahkan hubungi H2H'; } else if ( response.outputParameter.bit39.$value == '12' ) { st24rc = '40'; st24message = 'Invalid Transaction Transaksi ditolak karena flow transaksi tidak valid'; } else if ( response.outputParameter.bit39.$value == '13' ) { st24rc = '13'; st24message = 'Invalid voucher nominal'; } else if ( response.outputParameter.bit39.$value == '14' ) { st24rc = '14'; st24message = 'MSISDN tidak ditemukan'; } else if ( response.outputParameter.bit39.$value == '30' ) { st24rc = '40'; st24message = 'Format Error'; } else if ( response.outputParameter.bit39.$value == '31' ) { st24rc = '40'; st24message = 'Kode bank tidak terdaftar'; } else if ( response.outputParameter.bit39.$value == '63' ) { st24rc = '40'; st24message = 'Reversal denied'; } else if ( response.outputParameter.bit39.$value == '68' ) { st24rc = '68'; st24message = 'Transaksi sedang dalam proses'; } else if ( response.outputParameter.bit39.$value == '69' ) { st24rc = '68'; st24message = 'Respon Ok lebih dari 24 detik'; } else if ( response.outputParameter.bit39.$value == '70' ) { st24rc = '13'; st24message = 'Voucher out of stock'; } else if ( response.outputParameter.bit39.$value == '79' ) { st24rc = '14'; st24message = 'Phone number is blocked by Telkomsel'; } else if ( response.outputParameter.bit39.$value == '81' ) { st24rc = '14'; st24message = 'Phone number is expired'; } else if ( response.outputParameter.bit39.$value == '89' ) { st24rc = '40'; st24message = 'Link to billing provider is down'; } else if ( response.outputParameter.bit39.$value == '91' ) { st24rc = '40'; st24message = 'Database problem'; } else if ( response.outputParameter.bit39.$value == '92' ) { st24rc = '40'; st24message = 'Unable to route transaction'; } else if ( response.outputParameter.bit39.$value == '94' ) { st24rc = '40'; st24message = 'Duplicate reversal request'; } var message = response.outputParameter.resultCode.$value + " " + response.outputParameter.resultDesc.$value + "; " + response.outputParameter.bit39.$value ; if (response.outputParameter.resultDesc.$value != st24message) { var message = message + " " + st24message; } logger.info('Got result: ' + message, {result: result}); callbackReport(task.requestId, st24rc, st24message); } function topupRequestRetry(task) { task.retry--; if (task.retry > 0) { logger.info('Retrying in ' + sleepBeforeRetry + 's'); setTimeout(topupRequest, sleepBeforeRetry * 1000, task, task.retry); } else { logger.warn('Maximum retry for pending status exceeded', {task: task}); } } function createSignature(params, password) { var passwordHash = crypto.createHash('sha256').update(password).digest().toString('hex'); var plain = params.userName + passwordHash + params.productCode + params.terminal + params.transactionType + params.billNumber + params.amount + params.reff + params.timeStamp; return crypto.createHash('sha1').update(plain).digest().toString('hex'); } function createBillNumber(destination) { return ("0000000000000" + destination).slice(-13); } exports.start = start; exports.topupRequest = topupRequest; exports.createSignature = createSignature; exports.createBillNumber = createBillNumber;