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 Inline Diff

1 "use strict"; 1 "use strict";
2 2
3 var aaa = require('sate24/aaa.js'); 3 var aaa = require('sate24/aaa.js');
4 var expresso = require('sate24-expresso'); 4 var expresso = require('sate24-expresso');
5 var logger = require('sate24/logger.js').start(); 5 var logger = require('sate24/logger.js').start();
6 var HttpServer = require('sate24/httpserver.js'); 6 var HttpServer = require('sate24/httpserver.js');
7 var partner = require('./partner-simplepay.js'); 7 var partner = require('./partner-bnisp.js');
8 8
9 var fs = require('fs'); 9 var fs = require('fs');
10 var ini = require('ini'); 10 var ini = require('ini');
11 var config = ini.parse(fs.readFileSync(__dirname + '/config.ini', 'utf-8')); 11 var config = ini.parse(fs.readFileSync(__dirname + '/config.ini', 'utf-8'));
12 12
13 process.chdir(__dirname); 13 process.chdir(__dirname);
14 14
15 var logDirectory = __dirname + '/logs'; 15 var logDirectory = __dirname + '/logs';
16 fs.existsSync(logDirectory) || fs.mkdirSync(logDirectory); 16 fs.existsSync(logDirectory) || fs.mkdirSync(logDirectory);
17 17
18 var matrix = aaa.prepareMatrix(); 18 var matrix = aaa.prepareMatrix();
19 19
20 var options = { 20 var options = {
21 'aaa': aaa, 21 'aaa': aaa,
22 'logger': logger, 22 'logger': logger,
23 'config': config, 23 'config': config,
24 'matrix': matrix, 24 'matrix': matrix,
25 } 25 }
26 26
27 var httpServer = HttpServer.start(config, options); 27 var httpServer = HttpServer.start(config, options);
28 28
29 partner.start(options); 29 partner.start(options);
30 aaa.start(config, partner, options); 30 aaa.start(config, partner, options);
31 expresso.start(options); 31 expresso.start(options);
32 32
1 { 1 {
2 "name": "sate24-to-bnisyariah-prosesor", 2 "name": "sate24-to-bnisyariah-prosesor",
3 "version": "1.0.0", 3 "version": "1.0.0",
4 "description": "ST24 to BNI Syariah Prosesor", 4 "description": "ST24 to BNI Syariah Prosesor",
5 "main": "index.js", 5 "main": "index.js",
6 "scripts": { 6 "scripts": {
7 "test": "mocha" 7 "test": "mocha"
8 }, 8 },
9 "repository": { 9 "repository": {
10 "type": "git", 10 "type": "git",
11 "url": "git@gitlab.kodesumber.com:reload97/sate24-to-bnisyariah-prosesor.git" 11 "url": "git@gitlab.kodesumber.com:reload97/sate24-to-bnisyariah-prosesor.git"
12 }, 12 },
13 "keywords": [ 13 "keywords": [
14 "st24", 14 "st24",
15 "ppob", 15 "ppob",
16 "reload97", 16 "reload97",
17 "r97", 17 "r97",
18 "h2h" 18 "h2h"
19 ], 19 ],
20 "author": "Adhidarma Hadiwinoto <me@adhisimon.org>", 20 "author": "Adhidarma Hadiwinoto <me@adhisimon.org>",
21 "license": "ISC", 21 "license": "ISC",
22 "dependencies": { 22 "dependencies": {
23 "request": "^2.81.0",
23 "sate24": "git+http://gitlab.kodesumber.com/reload97/node-sate24.git", 24 "sate24": "git+http://gitlab.kodesumber.com/reload97/node-sate24.git",
24 "sate24-expresso": "git+http://gitlab.kodesumber.com/reload97/sate24-expresso.git" 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 }
27 32
File was created 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;
219
File was created 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 })
58