Blame view

partner-kospinjasa.js 13.3 KB
1f837fd31   Adhidarma Hadiwinoto   on progress
1
2
  var winston = require('winston');
  var soap = require('soap');
5a947e400   Adhidarma Hadiwinoto   siap coba dapat r...
3
4
  var crypto = require('crypto');
  var strftime = require('strftime');
97991a1dc   Adhidarma Hadiwinoto   pakai whiskers
5
  var fs = require("fs");
97991a1dc   Adhidarma Hadiwinoto   pakai whiskers
6
  var http = require("http");
e7d59da25   Adhidarma Hadiwinoto   require url
7
  var url = require("url");
1caba187c   Adhidarma Hadiwinoto   mongodb
8
9
  var mongoClient = require('mongodb').MongoClient;
  var moment = require('moment');
97991a1dc   Adhidarma Hadiwinoto   pakai whiskers
10
11
  
  process.chdir(__dirname);
1f837fd31   Adhidarma Hadiwinoto   on progress
12
13
14
15
16
17
18
19
20
  
  var max_retry = 10;
  var sleep_before_retry = 5000;
  
  var config;
  var callbackReport;
  var aaa;
  var logger;
  var options;
1caba187c   Adhidarma Hadiwinoto   mongodb
21
  var mongodb;
1f837fd31   Adhidarma Hadiwinoto   on progress
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
  
  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)()
              ]
          });
      }
1caba187c   Adhidarma Hadiwinoto   mongodb
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
  
      initMongoClient();
  }
  
  function initMongoClient() {
      if (!config || !config.mongodb || !config.mongodb.url) {
          return;
      }
  
      try {
          var url = config.mongodb.url;
  
          mongoClient.connect(url, function(err, db) {
              if (err) {
                  logger.warn('Failed to connect to mongodb', {err: err});
                  return;
              }
              mongodb = db;
              logger.info('MongoDB connected');
          });
      }
      catch(err) {
          logger.warn('Exception when connecting to mongodb', {err: err, url: url});
      }
  }
  
  function insertTaskToMongoDb(task) {
      if (!isMongoReady()) { return; }
  
      task.supplier = config.globals.gateway_name;
      task.rc = '68';
  
      try {
          mongodb.collection(config.mongodb.collection).insertOne(task);
      }
      catch(err) {
          //logger.warn('Exception when inserting document to mongodb', {err: err, task: task});
      }
  }
  
  function pushResponseToMongoDb(task, response, rc) {
      if (!isMongoReady()) { return; }
2af28a398   Adhidarma Hadiwinoto   create ts jika ti...
82

1caba187c   Adhidarma Hadiwinoto   mongodb
83
      try {
2af28a398   Adhidarma Hadiwinoto   create ts jika ti...
84
85
86
          if (!response.ts) {
              response.ts = strftime('%Y-%m-%d %H:%M:%S', new Date());
          }
1caba187c   Adhidarma Hadiwinoto   mongodb
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
          mongodb.collection(config.mongodb.collection).updateOne(
              {requestId: task.requestId},
              {
                  $set: {
                      lastResponse: response,
                      supplier: config.globals.gateway_name,
                      rc: rc
                  },
                  $push: {
                      responses: response
                  }
              },
              function(err, result) {
                  if (err) {
                      logger.warn('Error when pushing response to mongodb', {err: err, task: task, response: response});
                      return;
                  }
              }
          );
      }
      catch(err) {
          logger.warn('Exception when pushing response to mongodb', {err: err, task: task, response: response});
      }
  }
  
  function isMongoReady() {
      if (!config.mongodb) { return; }
      if (!config.mongodb.collection) { return; }
      if (!mongodb) { return; }
  
      return true;
1f837fd31   Adhidarma Hadiwinoto   on progress
118
119
120
  }
  
  function topupRequest(task, retry) {
1caba187c   Adhidarma Hadiwinoto   mongodb
121
122
123
124
      task.ts = moment(task.timestamp, 'YYYYMMDDHHmmss').format('YYYY-MM-DD HH:mm:ss');
      task.ts_date = moment(task.timestamp, 'YYYYMMDDHHmmss').format('YYYY-MM-DD');
  
      insertTaskToMongoDb(task);
9e047c122   Adhidarma Hadiwinoto   saldoCheck
125
126
127
128
129
130
131
132
133
134
      saldoCheck(billpayment, task);
  }
  
  function saldoCheck(callback, task) {
  
      var params = {
          userName: config.h2h_out.userid,
          productCode: '00000' ,
          terminal: 'H2HIPN10',
          transactionType: '61',
1c0291c88   Adhidarma Hadiwinoto   perbaikan random ...
135
          reff: Math.ceil( Math.random() * 99999999 ),
9e047c122   Adhidarma Hadiwinoto   saldoCheck
136
          timeStamp: strftime('%Y-%m-%d %H:%M:%S', new Date())
1f837fd31   Adhidarma Hadiwinoto   on progress
137
      }
9e047c122   Adhidarma Hadiwinoto   saldoCheck
138
      params.signature = createSignatureForSaldoCheck(params, config.h2h_out.password);
9b569c12b   Adhidarma Hadiwinoto   create soapclient...
139
      soap.createClient(config.h2h_out.partner, function(err, soapClient) {
9e047c122   Adhidarma Hadiwinoto   saldoCheck
140
141
  
          if (err) {
1caba187c   Adhidarma Hadiwinoto   mongodb
142
143
144
145
146
  
              var errorMessage = 'Error creating soap client for saldoCheck: ' + err;
  
              logger.warn(errorMessage, {err: err});
              callbackReport(task.requestId, '40', errorMessage);
2af28a398   Adhidarma Hadiwinoto   create ts jika ti...
147
              pushResponseToMongoDb(task, {supplier: config.globals.gateway_name, raw: errorMessage}, '40');
1caba187c   Adhidarma Hadiwinoto   mongodb
148

9b569c12b   Adhidarma Hadiwinoto   create soapclient...
149
              return;
9e047c122   Adhidarma Hadiwinoto   saldoCheck
150
          }
9b569c12b   Adhidarma Hadiwinoto   create soapclient...
151
152
153
154
155
156
157
158
159
160
161
162
163
164
          logger.info('Requesting to service', {url: config.h2h_out.partner, params: params});
          soapClient.apih2h.apih2hPort.saldoCheck({ inputSaldo: params }, function(err, result) {
  
              logger.verbose(
                  'Got saldoCheck response',
                  {
                      lastEndpoint: soapClient.lastEndpoint,
                      lastRequest: soapClient.lastRequest,
                      lastMessage: soapClient.lastMessage,
                      lastResponse: soapClient.lastResponse,
                  }
              );
  
              if (err) {
1caba187c   Adhidarma Hadiwinoto   mongodb
165
166
167
168
                  var errorMessage = 'Error requesting saldoCheck: ' + err;
  
                  logger.warn(errorMessage, {err: err});
                  callbackReport(task.requestId, '40', errorMessage);
2af28a398   Adhidarma Hadiwinoto   create ts jika ti...
169
                  pushResponseToMongoDb(task, {supplier: config.globals.gateway_name, raw: errorMessage}, '40');
9b569c12b   Adhidarma Hadiwinoto   create soapclient...
170
              }
9e047c122   Adhidarma Hadiwinoto   saldoCheck
171

9b569c12b   Adhidarma Hadiwinoto   create soapclient...
172
173
              var balance;
              logger.verbose('saldoCheck result', {result: result});
9e047c122   Adhidarma Hadiwinoto   saldoCheck
174

d309c00e0   Adhidarma Hadiwinoto   prev balance
175
176
177
178
179
180
              try {
                  balance = result.outputParameter.bit61.$value;
              }
              catch(e) {
                  balance = 'UNKNOWN';
              }
9b569c12b   Adhidarma Hadiwinoto   create soapclient...
181
182
183
184
185
  
              if (task) {
                  callback(task, balance);
              }
          });
7a475ed37   Adhidarma Hadiwinoto   typo
186
      });
9e047c122   Adhidarma Hadiwinoto   saldoCheck
187
188
189
190
  
  }
  
  function billpayment(task, balance) {
5a947e400   Adhidarma Hadiwinoto   siap coba dapat r...
191
      var remoteProduct = task.remoteProduct.split(',');
b6b185202   Adhidarma Hadiwinoto   inputCheck
192
      var params = {
7f796c813   Adhidarma Hadiwinoto   coba easysoap
193
194
          userName: config.h2h_out.userid,
          productCode: remoteProduct[0] ,
7be37af22   Adhidarma Hadiwinoto   pakai terminal H2...
195
          terminal: 'H2HIPN10',
7f796c813   Adhidarma Hadiwinoto   coba easysoap
196
197
198
199
200
          transactionType: '50',
          billNumber: createBillNumber(task.destination),
          amount: remoteProduct[1],
          bit61: createBillNumber(task.destination),
          reff: task.requestId,
342d268ac   Adhidarma Hadiwinoto   ubah timeStamp fo...
201
          timeStamp: strftime('%Y-%m-%d %H:%M:%S', new Date())
7f796c813   Adhidarma Hadiwinoto   coba easysoap
202
      }
b6b185202   Adhidarma Hadiwinoto   inputCheck
203
204
      var signature = createSignature(params, config.h2h_out.password);
      params.signature = signature;
7f796c813   Adhidarma Hadiwinoto   coba easysoap
205

777c49c56   Adhidarma Hadiwinoto   hapus forceSoap12...
206
      soap.createClient(config.h2h_out.partner, function(err, soapClient) {
35d3e5057   Adhidarma Hadiwinoto   pakai signature
207

699851497   Adhidarma Hadiwinoto   rearrange params
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
          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) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
224
225
226
227
228
229
230
231
232
              logger.verbose(
                  'Got response',
                  {
                      lastEndpoint: soapClient.lastEndpoint,
                      lastRequest: soapClient.lastRequest,
                      lastMessage: soapClient.lastMessage,
                      lastResponse: soapClient.lastResponse,
                  }
              );
3899d9816   Adhidarma Hadiwinoto   log last request
233

5a947e400   Adhidarma Hadiwinoto   siap coba dapat r...
234
              if (err) {
1caba187c   Adhidarma Hadiwinoto   mongodb
235
236
237
238
                  var errorMessage = 'Error requesting service: ' + err;
  
                  logger.warn(errorMessage, {err: err});
                  callbackReport(task.requestId, '68', errorMessage);
64e3e4b8c   Adhidarma Hadiwinoto   set parsedResponse
239
                  pushResponseToMongoDb(task, {supplier: config.globals.gateway_name, raw: soapClient.lastResponse}, '68');
1caba187c   Adhidarma Hadiwinoto   mongodb
240

5a947e400   Adhidarma Hadiwinoto   siap coba dapat r...
241
242
                  return;
              }
1caba187c   Adhidarma Hadiwinoto   mongodb
243
              topupResponseHandler(task, result, balance, soapClient.lastResponse);
1f837fd31   Adhidarma Hadiwinoto   on progress
244
245
246
          });
      });
  }
1caba187c   Adhidarma Hadiwinoto   mongodb
247
  function topupResponseHandler(task, response, balance, rawResponse) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
248
249
      var st24rc = '68';
      var st24message = response.outputParameter.resultDesc.$value;
97991a1dc   Adhidarma Hadiwinoto   pakai whiskers
250

aa561d430   Adhidarma Hadiwinoto   sn
251
252
      var resultCode = parseInt(response.outputParameter.resultCode.$value);
      var bit39 = parseInt(response.outputParameter.bit39.$value);
064e7c879   Adhidarma Hadiwinoto   include sn di pus...
253
      var sn = '';
aa561d430   Adhidarma Hadiwinoto   sn
254
      if ( resultCode == 1 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
255
256
257
          // product disabled
          st24rc = '13';
      }
aa561d430   Adhidarma Hadiwinoto   sn
258
      else if ( resultCode == 2 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
259
260
261
          // prodcode disable
          st24rc = '13';
      }
aa561d430   Adhidarma Hadiwinoto   sn
262
      else if ( resultCode == 3 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
263
264
265
          // duplicate reff
          st24rc = '55';
      }
aa561d430   Adhidarma Hadiwinoto   sn
266
      else if ( resultCode == 4 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
267
268
269
          // not enough balance
          st24rc = '40';
      }
aa561d430   Adhidarma Hadiwinoto   sn
270
      else if ( resultCode == 5 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
271
272
273
          // username blocked
          st24rc = '40';
      }
aa561d430   Adhidarma Hadiwinoto   sn
274
      else if ( resultCode == 6 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
275
276
277
          // not exists username
          st24rc = '40';
      }
aa561d430   Adhidarma Hadiwinoto   sn
278
      else if ( resultCode == 11 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
279
280
281
          // invalid request
          st24rc = '40'
      }
aa561d430   Adhidarma Hadiwinoto   sn
282
      else if ( resultCode == 12 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
283
284
285
          // no route to host
          st24rc = '40'
      }
aa561d430   Adhidarma Hadiwinoto   sn
286
      else if ( resultCode == 13 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
287
288
289
          // invalid signature
          st24rc = '40'
      }
aa561d430   Adhidarma Hadiwinoto   sn
290
      else if ( bit39 == 6 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
291
292
293
          st24rc = '40';
          st24message = 'Error Transaksi ditolak karena terjadi error di H2H dengan response code diluar daftar ini. Silahkan hubungi H2H';
      }
aa561d430   Adhidarma Hadiwinoto   sn
294
      else if ( bit39 == 12 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
295
296
297
          st24rc = '40';
          st24message = 'Invalid Transaction Transaksi ditolak karena flow transaksi tidak valid';
      }
aa561d430   Adhidarma Hadiwinoto   sn
298
      else if ( bit39 == 13 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
299
300
301
          st24rc = '13';
          st24message = 'Invalid voucher nominal';
      }
aa561d430   Adhidarma Hadiwinoto   sn
302
      else if ( bit39 == 14 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
303
304
305
          st24rc = '14';
          st24message = 'MSISDN tidak ditemukan';
      }
aa561d430   Adhidarma Hadiwinoto   sn
306
      else if ( bit39 == 30 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
307
308
309
          st24rc = '40';
          st24message = 'Format Error';
      }
aa561d430   Adhidarma Hadiwinoto   sn
310
      else if ( bit39 == 31 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
311
312
313
          st24rc = '40';
          st24message = 'Kode bank tidak terdaftar';
      }
aa561d430   Adhidarma Hadiwinoto   sn
314
      else if ( bit39 == 63 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
315
316
317
          st24rc = '40';
          st24message = 'Reversal denied';
      }
aa561d430   Adhidarma Hadiwinoto   sn
318
      else if ( bit39 == 68 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
319
320
321
          st24rc = '68';
          st24message = 'Transaksi sedang dalam proses';
      }
aa561d430   Adhidarma Hadiwinoto   sn
322
      else if ( bit39 == 69 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
323
324
325
          st24rc = '68';
          st24message = 'Respon Ok lebih dari 24 detik';
      }
aa561d430   Adhidarma Hadiwinoto   sn
326
      else if ( bit39 == 70 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
327
328
329
          st24rc = '13';
          st24message = 'Voucher out of stock';
      }
aa561d430   Adhidarma Hadiwinoto   sn
330
      else if ( bit39 == 79 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
331
332
333
          st24rc = '14';
          st24message = 'Phone number is blocked by Telkomsel';
      }
aa561d430   Adhidarma Hadiwinoto   sn
334
      else if ( bit39 == 81 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
335
336
337
          st24rc = '14';
          st24message = 'Phone number is expired';
      }
aa561d430   Adhidarma Hadiwinoto   sn
338
      else if ( bit39 == 89 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
339
340
341
          st24rc = '40';
          st24message = 'Link to billing provider is down';
      }
aa561d430   Adhidarma Hadiwinoto   sn
342
      else if ( bit39 == 91 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
343
344
345
          st24rc = '40';
          st24message = 'Database problem';
      }
aa561d430   Adhidarma Hadiwinoto   sn
346
      else if ( bit39 == 92 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
347
348
349
          st24rc = '40';
          st24message = 'Unable to route transaction';
      }
aa561d430   Adhidarma Hadiwinoto   sn
350
      else if ( bit39 == 94 ) {
4252c2818   Adhidarma Hadiwinoto   penanganan rc
351
352
353
          st24rc = '40';
          st24message = 'Duplicate reversal request';
      }
aa561d430   Adhidarma Hadiwinoto   sn
354
      else if ( resultCode == 0 && bit39 == 0) {
aa561d430   Adhidarma Hadiwinoto   sn
355
356
357
          try {
              sn = response.outputParameter.bit61.$value.substring(43);
          }
e2e928e50   Adhidarma Hadiwinoto   typo
358
          catch(e) {
aa561d430   Adhidarma Hadiwinoto   sn
359
360
361
362
363
364
              sn = '';
          }
  
          st24message = 'SN=' + sn + '; ' + st24message;
          st24rc = '00';
      }
97991a1dc   Adhidarma Hadiwinoto   pakai whiskers
365

4252c2818   Adhidarma Hadiwinoto   penanganan rc
366
367
368
      var message =
          response.outputParameter.resultCode.$value
          + " " + response.outputParameter.resultDesc.$value
aa561d430   Adhidarma Hadiwinoto   sn
369
          + "; BIT39: " + response.outputParameter.bit39.$value
4252c2818   Adhidarma Hadiwinoto   penanganan rc
370
          ;
97991a1dc   Adhidarma Hadiwinoto   pakai whiskers
371

4252c2818   Adhidarma Hadiwinoto   penanganan rc
372
373
374
      if (response.outputParameter.resultDesc.$value != st24message) {
          var message = message + " " + st24message;
      }
97991a1dc   Adhidarma Hadiwinoto   pakai whiskers
375

d309c00e0   Adhidarma Hadiwinoto   prev balance
376
      message = message + ' -- Prev Balance: ' + balance;
64e3e4b8c   Adhidarma Hadiwinoto   set parsedResponse
377
      var parsedResponse = {
a5668f44f   Adhidarma Hadiwinoto   outputParameter
378
379
380
381
382
383
384
385
386
387
388
          productCode: response.outputParameter.productCode.$value,
          terminal: response.outputParameter.terminal.$value,
          transactionType: response.outputParameter.transactionType.$value,
          billNumber: response.outputParameter.billNumber.$value,
          amount: response.outputParameter.amount.$value,
          bit61: response.outputParameter.bit61.$value,
          reff: response.outputParameter.reff.$value,
          timeStamp: response.outputParameter.timeStamp.$value,
          resultCode: response.outputParameter.resultCode.$value,
          resultDesc: response.outputParameter.resultDesc.$value,
          bit39: response.outputParameter.bit39.$value,
872fa65c3   Adhidarma Hadiwinoto   combinedMessage
389
          prevBalance: balance,
064e7c879   Adhidarma Hadiwinoto   include sn di pus...
390
391
          sn: sn,
          st24message: st24message,
64e3e4b8c   Adhidarma Hadiwinoto   set parsedResponse
392
      }
872fa65c3   Adhidarma Hadiwinoto   combinedMessage
393
394
395
      var combinedMessage = '';
  
      Object.keys(parsedResponse).forEach(function(key,index) {
064e7c879   Adhidarma Hadiwinoto   include sn di pus...
396
          combinedMessage += key + ': ' + parsedResponse[key] + '; '
872fa65c3   Adhidarma Hadiwinoto   combinedMessage
397
398
399
400
      });
      combinedMessage = combinedMessage.trim();
  
      parsedResponse.MESSAGE = combinedMessage;
13e965f4e   Adhidarma Hadiwinoto   typo
401
      logger.info('Got result: ' + message, {response: response});
d309c00e0   Adhidarma Hadiwinoto   prev balance
402
      callbackReport(task.requestId, st24rc, st24message + ' -- Prev Balance: ' + balance);
64e3e4b8c   Adhidarma Hadiwinoto   set parsedResponse
403
      pushResponseToMongoDb(task, {supplier: config.globals.gateway_name, raw: rawResponse, parsed: parsedResponse}, st24rc);
97991a1dc   Adhidarma Hadiwinoto   pakai whiskers
404
  }
b6b185202   Adhidarma Hadiwinoto   inputCheck
405
  function createSignature(params, password) {
5a947e400   Adhidarma Hadiwinoto   siap coba dapat r...
406
      var passwordHash = crypto.createHash('sha256').update(password).digest().toString('hex');
dfcc535b5   Adhidarma Hadiwinoto   coba perbaiki cre...
407
      var plain =
b6b185202   Adhidarma Hadiwinoto   inputCheck
408
          params.userName
5a947e400   Adhidarma Hadiwinoto   siap coba dapat r...
409
          + passwordHash
b6b185202   Adhidarma Hadiwinoto   inputCheck
410
411
412
413
414
415
416
          + params.productCode
          + params.terminal
          + params.transactionType
          + params.billNumber
          + params.amount
          + params.reff
          + params.timeStamp;
dfcc535b5   Adhidarma Hadiwinoto   coba perbaiki cre...
417

4252c2818   Adhidarma Hadiwinoto   penanganan rc
418
      return crypto.createHash('sha1').update(plain).digest().toString('hex');
5a947e400   Adhidarma Hadiwinoto   siap coba dapat r...
419
  }
9e047c122   Adhidarma Hadiwinoto   saldoCheck
420
421
422
423
424
425
426
427
428
429
430
431
432
  function createSignatureForSaldoCheck(params, password) {
      var passwordHash = crypto.createHash('sha256').update(password).digest().toString('hex');
      var plain =
          params.userName
          + passwordHash
          + params.productCode
          + params.terminal
          + params.transactionType
          + params.reff
          + params.timeStamp;
  
      return crypto.createHash('sha1').update(plain).digest().toString('hex');
  }
5a947e400   Adhidarma Hadiwinoto   siap coba dapat r...
433
434
  function createBillNumber(destination) {
      return ("0000000000000" + destination).slice(-13);
1f837fd31   Adhidarma Hadiwinoto   on progress
435
436
437
438
  }
  
  exports.start = start;
  exports.topupRequest = topupRequest;
5a947e400   Adhidarma Hadiwinoto   siap coba dapat r...
439
440
  exports.createSignature = createSignature;
  exports.createBillNumber = createBillNumber;