Commit 4acfa7529325b3040e4247cdef9f01df4d3ed850

Authored by Adhidarma Hadiwinoto
1 parent 7e92010a8b
Exists in master

ready to test

Showing 4 changed files with 281 additions and 1 deletions Side-by-side Diff

... ... @@ -4,7 +4,7 @@ var aaa = require('sate24/aaa.js');
4 4 var expresso = require('sate24-expresso');
5 5 var logger = require('sate24/logger.js').start();
6 6 var HttpServer = require('sate24/httpserver.js');
7   -var partner = require('./partner-simplepay.js');
  7 +var partner = require('./partner-bnisp.js');
8 8  
9 9 var fs = require('fs');
10 10 var ini = require('ini');
... ... @@ -20,7 +20,12 @@
20 20 "author": "Adhidarma Hadiwinoto <me@adhisimon.org>",
21 21 "license": "ISC",
22 22 "dependencies": {
  23 + "request": "^2.81.0",
23 24 "sate24": "git+http://gitlab.kodesumber.com/reload97/node-sate24.git",
24 25 "sate24-expresso": "git+http://gitlab.kodesumber.com/reload97/sate24-expresso.git"
  26 + },
  27 + "devDependencies": {
  28 + "mocha": "^3.4.2",
  29 + "should": "^11.2.1"
25 30 }
26 31 }
... ... @@ -0,0 +1,218 @@
  1 +"use strict";
  2 +
  3 +const http = require('http');
  4 +http.globalAgent.maxSockets = Infinity;
  5 +
  6 +const request = require('request');
  7 +
  8 +var config;
  9 +var aaa;
  10 +var logger;
  11 +
  12 +function start(options) {
  13 + if (!options) {
  14 + console.log('Undefined options, terminating....');
  15 + process.exit(1);
  16 + }
  17 +
  18 + if (options.config) {
  19 + config = options.config;
  20 + } else {
  21 + console.log('Undefined options.config, terminating....')
  22 + process.exit(1);
  23 + }
  24 +
  25 + if (options.aaa) {
  26 + aaa = options.aaa;
  27 + } else {
  28 + console.log('Undefined options.aaa, terminating....')
  29 + process.exit(1);
  30 + }
  31 +
  32 + if (options && options.logger) {
  33 + logger = options.logger;
  34 + } else {
  35 + console.log('Undefined options.logger, terminating....')
  36 + process.exit(1);
  37 + }
  38 +}
  39 +
  40 +function callbackReport(requestId, rc, message, options) {
  41 + aaa.callbackReportWithPushToMongoDb(requestId, rc, message);
  42 +}
  43 +
  44 +function topupRequest(task) {
  45 + aaa.insertTaskToMongoDb(task);
  46 + _hitTopup(task);
  47 +}
  48 +
  49 +function _hitTopup(task, isCheckStatus) {
  50 +
  51 + const remoteProduct = task.remoteProduct.split('/');
  52 + if (remoteProduct.length < 4) {
  53 + callbackReport(task.requestId, '40', 'INTERNAL_MSG: Invalid remoteProduct', task)
  54 + return;
  55 + }
  56 +
  57 + let pathParams = {
  58 + request_type: "purchase",
  59 + noid: config.h2h_out.noid,
  60 + token: config.h2h_out.token,
  61 + product: task.remoteProduct[0],
  62 + product_type: task.remoteProduct[1],
  63 + id_pel: task.destination,
  64 + nominal: task.remoteProduct[2],
  65 + admin: task.remoteProduct[3],
  66 + trace_id: task.requestId
  67 + }
  68 +
  69 + const requestOptions = {
  70 + url: config.h2h_out.partner + createUrlPath(pathParams)
  71 + }
  72 +
  73 + logger.verbose('Requeting to partner', {requestOptions: requestOptions});
  74 + request(requestOptions, function(error, response, body) {
  75 + if (error) {
  76 + let rc = '68';
  77 +
  78 + if (!isCheckStatus && (error.syscall == 'connect')) {
  79 + rc = '91';
  80 + }
  81 +
  82 + logger.warn('Error requesting to partner', {task: task, rc: rc, error: error});
  83 + callbackReport(task.requestId, rc, 'INTERNAL_MSG: Error requesting to partner. ' + error, {task: task});
  84 + return;
  85 + }
  86 +
  87 + if (response.statusCode != 200) {
  88 + let rc = '68';
  89 +
  90 + logger.warn('HTTP status code is not 200', {task: task, http_status_code: response.statusCode});
  91 + callbackReport(task.requestId, rc, 'INTERNAL_MSG: HTTP status code ' + response.statusCode, {task: task});
  92 + return;
  93 + }
  94 +
  95 + if (!body) {
  96 + let rc = '68';
  97 +
  98 + logger.warn('Error processing response body', {task: task, responseBody: body});
  99 + callbackReport(task.requestId, rc, 'INTERNAL_MSG: Error processing response body', {task: task});
  100 + return;
  101 + }
  102 +
  103 + const responseData = parseResponseBody(body);
  104 + const data = responseDataProcessor(responseData);
  105 +
  106 + callbackReport(task.requestId, data.rc, data.combinedMessage, {task: task});
  107 + })
  108 +
  109 +}
  110 +
  111 +function createUrlPath(options) {
  112 + let urlPath = [
  113 + "get",
  114 + options.request_type || "purchase",
  115 + "json",
  116 + options.noid,
  117 + options.token,
  118 + options.product,
  119 + options.product_type,
  120 + options.id_pel,
  121 + options.nominal || 0,
  122 + options.admin || 0,
  123 + options.trace_id
  124 + ].join('/');
  125 +
  126 + return '/' + urlPath;
  127 +}
  128 +
  129 +function parseResponseBody(body) {
  130 + let data;
  131 +
  132 + try {
  133 + data = JSON.parse(body);
  134 + }
  135 + catch(e) {
  136 + if (logger) {
  137 + logger.warn('Exception on parsing result body: ' + e);
  138 + return;
  139 + }
  140 + }
  141 +
  142 + return data;
  143 +}
  144 +
  145 +function responseDataProcessor(responseData) {
  146 + let retval = {
  147 + rc: '68',
  148 + sn: '',
  149 + responseMessage: '',
  150 + amount: 0,
  151 + balance: 0,
  152 + ts: '',
  153 + product: '',
  154 + productType: ''
  155 + }
  156 +
  157 + let combinedMessage = [];
  158 +
  159 + if (responseData.response_code == '0000') {
  160 + retval.rc = '00';
  161 + }
  162 + else if (['9990','0099','0068','0063','0005','9997','9999','9998','9990','0600','1003'].indexOf(responseData.response_code) >= 0) {
  163 + retval.rc = '68';
  164 + }
  165 + else {
  166 + retval.rc = '40';
  167 + }
  168 +
  169 + if (responseData.response_code) {
  170 + combinedMessage.push(responseData.response_code);
  171 + }
  172 +
  173 + if (responseData.product) {
  174 + combinedMessage.push(responseData.product)
  175 + }
  176 +
  177 + if (responseData.produk_tipe) {
  178 + combinedMessage.push(responseData.produk_tipe)
  179 + }
  180 +
  181 + if (responseData.idpel) {
  182 + combinedMessage.push(responseData.idpel)
  183 + }
  184 +
  185 + retval.responseMessage = responseData.response_message || '';
  186 + if (retval.responseMessage) {
  187 + combinedMessage.push(retval.responseMessage);
  188 + }
  189 +
  190 + if (responseData.detail) {
  191 + retval.sn = responseData.detail.voucherSerialNumber || '';
  192 + }
  193 +
  194 + retval.amount = responseData.amount || 0;
  195 + combinedMessage.push('amount: ' + retval.amount);
  196 +
  197 + retval.balance = responseData.saldo || 0;
  198 + combinedMessage.push('balance: ' + retval.balance);
  199 +
  200 + retval.ts = responseData.waktu || '';
  201 + combinedMessage.push(retval.ts);
  202 +
  203 + retval.loadTime = responseData.loadTime || '';
  204 + combinedMessage.push('load time: ' + retval.loadTime);
  205 +
  206 + retval.combinedMessage = combinedMessage.join(' ');
  207 +
  208 + if (retval.sn) {
  209 + retval.combinedMessage = 'SN=' + retval.sn + '; ' + retval.combinedMessage;
  210 + }
  211 +
  212 + return retval;
  213 +}
  214 +
  215 +exports.createUrlPath = createUrlPath;
  216 +exports.parseResponseBody = parseResponseBody;
  217 +exports.responseDataProcessor = responseDataProcessor;
  218 +exports.topupRequest = topupRequest;
... ... @@ -0,0 +1,57 @@
  1 +"use strict";
  2 +
  3 +const should = require("should");
  4 +const partner = require("./partner-bnisp");
  5 +
  6 +describe("#partner", function() {
  7 + describe("#createUrlPath", function() {
  8 +
  9 + it('should return correct url path based on example', function() {
  10 + let options = {
  11 + noid: 1002003,
  12 + token: 'CIPY6t6ruy5UuGG0PCqu',
  13 + product: 'PULSA',
  14 + product_type: 'THREE5000',
  15 + id_pel: '0895385381299',
  16 + trace_id: 16
  17 + }
  18 +
  19 + partner.createUrlPath(options).should.equal('/get/purchase/json/1002003/CIPY6t6ruy5UuGG0PCqu/PULSA/THREE5000/0895385381299/0/0/16')
  20 + })
  21 +
  22 + })
  23 +
  24 + const responseBody = '{"trxId":"064024","response_code":"0000","response_message":"SUKSES","detail":{"jmlTagihan":"1","kodeThree":"012001","nilaiPulsa":"000000005000","noHp":"0895385381299","transactionId":"0612143023138365102 ","voucherSerialNumber":"20170612143620980249"},"reff":"20170612143620980249","loadTime":"0.0107","tipe_request":"purchase","prv":"hpay","userID":"1002003","idpel":"0895385381299","product":"PULSA","produk":"PULSA","product_detail":"THREE5000","produk_tipe":"THREE5000","traceId":16,"tagihan":5050,"total_tagihan":5050,"amount":5050,"saldo":94950,"waktu":"2017-07-17 18:43:32"}';
  25 + const responseData = partner.parseResponseBody(responseBody);
  26 +
  27 + describe('#parseResponseBody', function() {
  28 +
  29 + it('should return correct response code', function() {
  30 + responseData.response_code.should.equal('0000');
  31 + })
  32 +
  33 + it('should return correct voucher serial number', function() {
  34 + responseData.detail.voucherSerialNumber.should.equal('20170612143620980249');
  35 + })
  36 + })
  37 +
  38 + describe('#responseDataProcessor', function() {
  39 + const processed = partner.responseDataProcessor(responseData);
  40 +
  41 + it('should return correct rc', function() {
  42 + processed.rc.should.equal('00');
  43 + })
  44 +
  45 + it('should return correct sn', function() {
  46 + processed.sn.should.equal('20170612143620980249');
  47 + })
  48 +
  49 + it('should return correct amount', function() {
  50 + processed.amount.should.equal(5050);
  51 + })
  52 +
  53 + it('should return correct balance', function() {
  54 + processed.balance.should.equal(94950);
  55 + })
  56 + })
  57 +})