Commit fdb2abd41e9dafca6fb0a059b8f4c1ff34e762f1
1 parent
b450476d61
Exists in
master
registerResendDelay
Showing 4 changed files with 313 additions and 3 deletions Inline Diff
File was created | 1 | var redis = require('redis'); | |
2 | var moment = require('moment'); | ||
3 | var LRU = require('lru-cache'); | ||
4 | |||
5 | var config; | ||
6 | var logger; | ||
7 | var partner; | ||
8 | var imConfig; | ||
9 | var redisClient; | ||
10 | |||
11 | var resendHandlers = LRU({max: 2000, maxAge: 1000 * 3600 * 36}); | ||
12 | |||
13 | function init(options) { | ||
14 | if (options && options.config) { | ||
15 | config = options.config; | ||
16 | } | ||
17 | |||
18 | if (options && options.logger) { | ||
19 | logger = options.logger; | ||
20 | } | ||
21 | |||
22 | createRedisClient(config.globals.redis_host, config.globals.redis_port); | ||
23 | readImConfig(); | ||
24 | } | ||
25 | |||
26 | function createRedisClient(host, port) { | ||
27 | try { | ||
28 | redisClient = redis.createClient(port, host); | ||
29 | } catch(err) { | ||
30 | logger.warn("Error creating redis client to " + host + ':' + port); | ||
31 | } | ||
32 | } | ||
33 | |||
34 | function readImConfig(filename) { | ||
35 | |||
36 | if (!filename) { | ||
37 | filename = process.cwd() + '/config.im.json'; | ||
38 | } | ||
39 | |||
40 | try { | ||
41 | imConfig = require(filename); | ||
42 | } | ||
43 | catch(e) { | ||
44 | imConfig = {}; | ||
45 | } | ||
46 | |||
47 | logger.verbose('IM Config', {imConfig: imConfig}); | ||
48 | return imConfig; | ||
49 | } | ||
50 | |||
51 | function getPatternFromMessage(message, pattern, patternMatchIndex) { | ||
52 | var re = new RegExp(pattern); | ||
53 | var matches = message.match(re); | ||
54 | |||
55 | if (!matches) { | ||
56 | return null; | ||
57 | } | ||
58 | |||
59 | if (patternMatchIndex < matches.length) { | ||
60 | return matches[patternMatchIndex]; | ||
61 | } else { | ||
62 | return null; | ||
63 | } | ||
64 | } | ||
65 | |||
66 | function getPatternsFromMessage(message, patterns) { | ||
67 | var patternCount = patterns.length; | ||
68 | for (var i = 0; i < patternCount; i++) { | ||
69 | |||
70 | var pattern = patterns[i]; | ||
71 | |||
72 | var result = getPatternFromMessage(message, pattern.pattern, pattern.matchIndex); | ||
73 | if (result) { | ||
74 | return result; | ||
75 | } | ||
76 | } | ||
77 | } | ||
78 | |||
79 | function getTaskKey(task, chipInfo, today) { | ||
80 | if (!chipInfo && config && config.globals && config.globals.gateway_name) { | ||
81 | chipInfo = config.globals.gateway_name; | ||
82 | } | ||
83 | |||
84 | if (task.timestamp && !today) { | ||
85 | today = moment(task.timestamp, 'YYYYMMDDHHmmss').format('YYYYMMDD'); | ||
86 | } | ||
87 | |||
88 | return chipInfo + '.trx.date:' + today + '.rProduct:' + task.remoteProduct.toUpperCase() + '.dest:' + task.destination ; | ||
89 | } | ||
90 | |||
91 | function saveTask(task, cb) { | ||
92 | var key = getTaskKey(task, config.globals.gateway_name); | ||
93 | logger.verbose('Saving task', {key: key, task: task}); | ||
94 | |||
95 | redisClient.set(key, JSON.stringify(task), function() { | ||
96 | redisClient.expire(key, 3600*24); | ||
97 | if (cb) { | ||
98 | cb(); | ||
99 | } | ||
100 | }); | ||
101 | } | ||
102 | |||
103 | function getTask(remoteProduct, destination, cb) { | ||
104 | var dummyTask = { | ||
105 | remoteProduct: remoteProduct, | ||
106 | destination: destination, | ||
107 | } | ||
108 | |||
109 | var key = getTaskKey(dummyTask, config.globals.gateway_name, moment().format('YYYYMMDD')); | ||
110 | redisClient.get(key, function(err, result) { | ||
111 | if (err) { | ||
112 | logger.verbose('getTask: task not found', {key: key, params: dummyTask}); | ||
113 | |||
114 | cb(err, null); | ||
115 | return; | ||
116 | } | ||
117 | |||
118 | var task = {}; | ||
119 | |||
120 | try { | ||
121 | task = JSON.parse(result); | ||
122 | } | ||
123 | catch(e) { | ||
124 | logger.warn('getTask: Can not parse result', {key: key, params: dummyTask, data: result}); | ||
125 | err = "Can not parse result" | ||
126 | } | ||
127 | cb(err, task); | ||
128 | }); | ||
129 | } | ||
130 | |||
131 | function deleteTask(remoteProduct, destination) { | ||
132 | var dummyTask = { | ||
133 | remoteProduct: remoteProduct, | ||
134 | destination: destination, | ||
135 | } | ||
136 | |||
137 | var key = getTaskKey(dummyTask, config.globals.gateway_name, moment().format('YYYYMMDD')); | ||
138 | |||
139 | try { | ||
140 | redisClient.del(key); | ||
141 | } | ||
142 | catch(e) {}; | ||
143 | } | ||
144 | |||
145 | function createMessage(pattern, keywords) { | ||
146 | var msg = pattern; | ||
147 | |||
148 | for (var key in keywords) { | ||
149 | msg = msg.replace('[' + key + ']', keywords[key]); | ||
150 | } | ||
151 | return msg; | ||
152 | } | ||
153 | |||
154 | function getRemoteProductFromMessage(msg) { | ||
155 | return getPatternsFromMessage(msg, imConfig.product_patterns); | ||
156 | } | ||
157 | |||
158 | function getDestinationFromMessage(msg) { | ||
159 | return getPatternsFromMessage(msg, imConfig.destination_patterns); | ||
160 | } | ||
161 | |||
162 | function getSnFromMessage(msg) { | ||
163 | return getPatternsFromMessage(msg, imConfig.sn_patterns); | ||
164 | } | ||
165 | |||
166 | function getRcFromMessage(msg) { | ||
167 | var rcs = imConfig.response_codes; | ||
168 | var rcsCount = rcs.length; | ||
169 | |||
170 | for (var i = 0; i < rcsCount; i++) { | ||
171 | |||
172 | var item = rcs[i]; | ||
173 | var re = new RegExp(item.pattern); | ||
174 | if (msg.search(re) != -1) { | ||
175 | return item.rc; | ||
176 | } | ||
177 | |||
178 | } | ||
179 | return '68'; | ||
180 | } | ||
181 | |||
182 | function isAllowedFrom(sender) { | ||
183 | if (!config || !config.h2h_out || !config.h2h_out.allowed_response_from) { | ||
184 | return true; | ||
185 | } | ||
186 | |||
187 | whitelist = config.h2h_out.allowed_response_from.split(','); | ||
188 | whitelistCount = whitelist.length; | ||
189 | |||
190 | for(var i=0; i<whitelistCount; i++) { | ||
191 | if (sender == whitelist[i]) { | ||
192 | return true; | ||
193 | } | ||
194 | } | ||
195 | |||
196 | return false; | ||
197 | } | ||
198 | |||
199 | function checkForSameDayDuplicate(task, cbNoDupe, cbDupe, cbDupeWithSameReqId) { | ||
200 | getTask(task.remoteProduct, task.destination, function(err, archivedTask) { | ||
201 | if (err) { | ||
202 | logger.warn('Error on checking same day duplicate', {task: task}); | ||
203 | cbNoDupe(task); | ||
204 | return; | ||
205 | } | ||
206 | |||
207 | if (archivedTask && archivedTask.requestId) { | ||
208 | if (cbDupeWithSameReqId && task.requestId == archivedTask.requestId) { | ||
209 | logger.verbose('Duplicate trx on same day with same requestId', {task: task}); | ||
210 | cbDupeWithSameReqId(task, archivedTask); | ||
211 | return; | ||
212 | } | ||
213 | |||
214 | logger.verbose('Duplicate trx on same day', {task: task, archivedTask: archivedTask}); | ||
215 | cbDupe(task, archivedTask); | ||
216 | return; | ||
217 | } | ||
218 | |||
219 | cbNoDupe(task); | ||
220 | }); | ||
221 | } | ||
222 | |||
223 | function registerResendDelay(task) { | ||
224 | if (!task.requestId) { | ||
225 | logger.warn('Invalid task on resendDelay') | ||
226 | return; | ||
227 | } | ||
228 | |||
229 | if (!config || !config.globals || !config.globals.auto_resend_on_delay_secs) { | ||
230 | return; | ||
231 | } | ||
232 | |||
233 | if (!partner || !partner.topupRequest) { | ||
234 | logger.warn('Skip request resend delay because partner.topupRequest is not exists'); | ||
235 | return; | ||
236 | } | ||
237 | |||
238 | var retry = 10; | ||
239 | var oldHandler = resendHandlers.get(task.requestId); | ||
240 | if (oldHandler) { | ||
241 | retry = oldHandler.retry - 1; | ||
242 | } | ||
243 | |||
244 | if (retry <= 0) { | ||
245 | logger.verbose('Resend delay retry exceeded', {task: task}); | ||
246 | cancelResendDelay(task); | ||
247 | return; | ||
248 | } | ||
249 | |||
250 | logger.info('Resending task request', {task}); | ||
251 | var handlerData = { | ||
252 | handler: setTimeout(partner.topupRequest, config.globals.auto_resend_on_delay_secs, task), | ||
253 | task: task, | ||
254 | retry: retry | ||
255 | } | ||
256 | |||
257 | resendHandlers.set(task.requestId, handlerData); | ||
258 | } | ||
259 | |||
260 | function cancelResendDelay(task) { | ||
261 | if (!task || !task.requestId) { | ||
262 | logger.warn('Invalid task on cancelResendDelay'); | ||
263 | return; | ||
264 | } | ||
265 | |||
266 | var oldHandler = resendHandlers.get(task.requestId); | ||
267 | if (!oldHandler) { | ||
268 | return; | ||
269 | } | ||
270 | |||
271 | logger.verbose('Canceling resend delay', {task: task}); | ||
272 | |||
273 | try { | ||
274 | if (oldHandler.handler) { | ||
275 | clearTimeout(oldHandler.handler); | ||
276 | } | ||
277 | } | ||
278 | catch(e) {}; | ||
279 | |||
280 | try { | ||
281 | resendHandlers.del(task.requestId); | ||
282 | } | ||
283 | catch(e) {}; | ||
284 | } | ||
285 | |||
286 | exports.init = init; | ||
287 | exports.start = init; | ||
288 | exports.getPatternFromMessage = getPatternFromMessage; | ||
289 | exports.getPatternsFromMessage = getPatternsFromMessage; | ||
290 | exports.saveTask = saveTask; | ||
291 | exports.getTask = getTask; | ||
292 | exports.readImConfig = readImConfig; | ||
293 | exports.createMessage = createMessage; | ||
294 | exports.getRemoteProductFromMessage = getRemoteProductFromMessage; | ||
295 | exports.getDestinationFromMessage = getDestinationFromMessage; | ||
296 | exports.getRcFromMessage = getRcFromMessage; | ||
297 | exports.getSnFromMessage = getSnFromMessage; | ||
298 | exports.isAllowedFrom = isAllowedFrom; | ||
299 | exports.checkForSameDayDuplicate = checkForSameDayDuplicate; | ||
300 | exports.deleteTask = deleteTask; | ||
301 | exports.registerResendDelay = registerResendDelay; | ||
302 |
index.js
1 | var fs = require('fs'); | 1 | var fs = require('fs'); |
2 | var ini = require('ini'); | 2 | var ini = require('ini'); |
3 | var expresso = require('sate24-expresso'); | 3 | var expresso = require('sate24-expresso'); |
4 | var partner = require('./partner-ym'); | 4 | var partner = require('./partner-ym'); |
5 | var config = ini.parse(fs.readFileSync(__dirname + '/config.ini', 'utf-8')); | 5 | var config = ini.parse(fs.readFileSync(__dirname + '/config.ini', 'utf-8')); |
6 | 6 | ||
7 | process.chdir(__dirname); | 7 | process.chdir(__dirname); |
8 | 8 | ||
9 | var logger = require('sate24/logger.js').start(); | 9 | var logger = require('sate24/logger.js').start(); |
10 | var HttpServer = require('sate24/httpserver.js'); | 10 | var HttpServer = require('sate24/httpserver.js'); |
11 | var aaa = require('sate24/aaa.js'); | 11 | var aaa = require('sate24/aaa.js'); |
12 | var partner = require('./partner-ym.js'); | 12 | var partner = require('./partner-ym.js'); |
13 | 13 | ||
14 | var matrix = aaa.prepareMatrix(); | 14 | var matrix = aaa.prepareMatrix(); |
15 | 15 | ||
16 | var options = { | 16 | var options = { |
17 | 'aaa': aaa, | 17 | 'aaa': aaa, |
18 | 'logger': logger, | 18 | 'logger': logger, |
19 | 'config': config, | 19 | 'config': config, |
20 | 'matrix': matrix, | 20 | 'matrix': matrix, |
21 | 'partner': partner, | ||
21 | } | 22 | } |
22 | 23 | ||
23 | var httpServer = HttpServer.start(config, options); | 24 | var httpServer = HttpServer.start(config, options); |
24 | 25 | ||
25 | aaa.pause(); | 26 | aaa.pause(); |
26 | 27 | ||
27 | partner.start(options); | 28 | partner.start(options); |
28 | aaa.start(config, partner, options); | 29 | aaa.start(config, partner, options); |
29 | expresso.start(options); | 30 | expresso.start(options); |
30 | 31 |
package.json
1 | { | 1 | { |
2 | "name": "sate24-to-ym", | 2 | "name": "sate24-to-ym", |
3 | "version": "1.0.0", | 3 | "version": "1.0.0", |
4 | "description": "ST24 to YM H2H Out", | 4 | "description": "ST24 to YM H2H Out", |
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-ym.git" | 11 | "url": "git@gitlab.kodesumber.com:reload97/sate24-to-ym.git" |
12 | }, | 12 | }, |
13 | "keywords": [ | 13 | "keywords": [ |
14 | "st24", | 14 | "st24", |
15 | "reload97", | 15 | "reload97", |
16 | "r97", | 16 | "r97", |
17 | "yahoo", | 17 | "yahoo", |
18 | "ym", | 18 | "ym", |
19 | "yahoomessenger", | 19 | "yahoomessenger", |
20 | "ppob" | 20 | "ppob" |
21 | ], | 21 | ], |
22 | "author": "Adhidarma Hadiwinoto <me@adhisimon.org>", | 22 | "author": "Adhidarma Hadiwinoto <me@adhisimon.org>", |
23 | "license": "ISC", | 23 | "license": "ISC", |
24 | "dependencies": { | 24 | "dependencies": { |
25 | "lru-cache": "^4.0.1", | ||
25 | "sate24": "git+http://gitlab.kodesumber.com/reload97/node-sate24.git", | 26 | "sate24": "git+http://gitlab.kodesumber.com/reload97/node-sate24.git", |
26 | "sate24-expresso": "git+http://gitlab.kodesumber.com/reload97/sate24-expresso.git", | 27 | "sate24-expresso": "git+http://gitlab.kodesumber.com/reload97/sate24-expresso.git", |
27 | "yahoomessenger": "^0.1.3-Beta" | 28 | "yahoomessenger": "^0.1.3-Beta" |
28 | } | 29 | } |
29 | } | 30 | } |
30 | 31 |
partner-ym.js
1 | var im = require('sate24/im.js') | 1 | var im = require('./im.js') |
2 | var YM = require('yahoomessenger'); | 2 | var YM = require('yahoomessenger'); |
3 | var imAdaptor = require('./adaptor-ym'); | 3 | var imAdaptor = require('./adaptor-ym'); |
4 | 4 | ||
5 | var config; | 5 | var config; |
6 | var aaa; | 6 | var aaa; |
7 | var logger; | 7 | var logger; |
8 | var callbackReport; | 8 | var callbackReport; |
9 | 9 | ||
10 | function onLoginSuccessful() { | 10 | function onLoginSuccessful() { |
11 | logger.info('Login successful, resuming aaa communication'); | 11 | logger.info('Login successful, resuming aaa communication'); |
12 | aaa.resume(); | 12 | aaa.resume(); |
13 | } | 13 | } |
14 | 14 | ||
15 | function onPM(from, msg) { | 15 | function onPM(from, msg) { |
16 | 16 | ||
17 | if (!im.isAllowedFrom(from)) { | 17 | if (!im.isAllowedFrom(from)) { |
18 | logger.info('Ignoring message from unknown sender', {from: from, msg: msg}); | 18 | logger.info('Ignoring message from unknown sender', {from: from, msg: msg}); |
19 | return; | 19 | return; |
20 | } | 20 | } |
21 | 21 | ||
22 | var remoteProduct = im.getRemoteProductFromMessage(msg); | 22 | var remoteProduct = im.getRemoteProductFromMessage(msg); |
23 | var destination = im.getDestinationFromMessage(msg); | 23 | var destination = im.getDestinationFromMessage(msg); |
24 | 24 | ||
25 | if (!remoteProduct && !destination) { | 25 | if (!remoteProduct && !destination) { |
26 | logger.warn('Missing remote product or destination', {remoteProduct: remoteProduct, destination: destination, msg: msg}); | 26 | logger.warn('Missing remote product or destination', {remoteProduct: remoteProduct, destination: destination, msg: msg}); |
27 | return; | 27 | return; |
28 | } | 28 | } |
29 | 29 | ||
30 | logger.info('Got report from partner', {remoteProduct: remoteProduct, destination: destination, msg: msg}); | 30 | logger.info('Got report from partner', {remoteProduct: remoteProduct, destination: destination, msg: msg}); |
31 | im.getTask(remoteProduct, destination, function(err, task) { | 31 | im.getTask(remoteProduct, destination, function(err, task) { |
32 | if (err) { | 32 | if (err) { |
33 | logger.warn('Error getting relevant task'); | 33 | logger.warn('Error getting relevant task'); |
34 | return; | 34 | return; |
35 | } | 35 | } |
36 | 36 | ||
37 | if (!task) { | 37 | if (!task) { |
38 | logger.warn('Something wrong, undefined task without error') | 38 | logger.warn('Something wrong, undefined task without error') |
39 | return; | 39 | return; |
40 | } | 40 | } |
41 | 41 | ||
42 | logger.verbose('Got relevant task', {task: task, msg: msg}); | 42 | logger.verbose('Got relevant task', {task: task, msg: msg}); |
43 | var rc = im.getRcFromMessage(msg); | 43 | var rc = im.getRcFromMessage(msg); |
44 | if (rc == '00') { | 44 | if (rc == '00') { |
45 | var sn = im.getSnFromMessage(msg); | 45 | var sn = im.getSnFromMessage(msg); |
46 | if (sn) { | 46 | if (sn) { |
47 | msg = 'SN=' + sn + ';' + msg; | 47 | msg = 'SN=' + sn + ';' + msg; |
48 | } | 48 | } |
49 | } | 49 | } |
50 | 50 | ||
51 | if (['00', '55', '68'].indexOf(rc) == -1) { | 51 | if (['00', '55', '68'].indexOf(rc) == -1) { |
52 | im.deleteTask(remoteProduct, destination); | 52 | im.deleteTask(remoteProduct, destination); |
53 | } | 53 | } |
54 | 54 | ||
55 | callbackReport(task.requestId, rc, msg); | 55 | if (rc != '68') { |
56 | im.cancelResendDelay(task); | ||
57 | } | ||
58 | |||
59 | callbackReportWrapper(task.requestId, rc, msg); | ||
56 | }); | 60 | }); |
57 | } | 61 | } |
58 | 62 | ||
59 | function start(options) { | 63 | function start(options) { |
60 | if (options && options.config) { | 64 | if (options && options.config) { |
61 | config = options.config; | 65 | config = options.config; |
62 | } else { | 66 | } else { |
63 | console.log('Unknown options.config'); | 67 | console.log('Unknown options.config'); |
64 | process.exit('1'); | 68 | process.exit('1'); |
65 | } | 69 | } |
66 | 70 | ||
67 | if (options && options.aaa) { | 71 | if (options && options.aaa) { |
68 | aaa = options.aaa; | 72 | aaa = options.aaa; |
69 | } | 73 | } |
70 | 74 | ||
71 | if (options && options.aaa && options.aaa.callbackReport) { | 75 | if (options && options.aaa && options.aaa.callbackReport) { |
72 | callbackReport = options.aaa.callbackReport; | 76 | callbackReport = options.aaa.callbackReport; |
73 | } else { | 77 | } else { |
74 | console.log('Unknown options.aaa.callbackReport') | 78 | console.log('Unknown options.aaa.callbackReport') |
75 | process.exit(2); | 79 | process.exit(2); |
76 | } | 80 | } |
77 | 81 | ||
78 | if (options && options.logger) { | 82 | if (options && options.logger) { |
79 | logger = options.logger; | 83 | logger = options.logger; |
80 | } else { | 84 | } else { |
81 | logger = new winston.Logger({ | 85 | logger = new winston.Logger({ |
82 | transports: [ | 86 | transports: [ |
83 | new (winston.transports.Console)() | 87 | new (winston.transports.Console)() |
84 | ] | 88 | ] |
85 | }); | 89 | }); |
86 | } | 90 | } |
87 | 91 | ||
88 | var callbacks = { | 92 | var callbacks = { |
89 | onLoginSuccessful: onLoginSuccessful, | 93 | onLoginSuccessful: onLoginSuccessful, |
90 | onPM: onPM, | 94 | onPM: onPM, |
91 | } | 95 | } |
92 | 96 | ||
93 | im.init(options); | 97 | im.init(options); |
94 | imAdaptor.init(config.h2h_out.ym_id, config.h2h_out.ym_password, logger, callbacks); | 98 | imAdaptor.init(config.h2h_out.ym_id, config.h2h_out.ym_password, logger, callbacks); |
95 | } | 99 | } |
96 | 100 | ||
97 | function onSameDayDupe(task, archivedTask) { | 101 | function onSameDayDupe(task, archivedTask) { |
98 | if (task.requestId == archivedTask.requestId) { | 102 | if (task.requestId == archivedTask.requestId) { |
99 | logger.info('Mengulang trx untuk advice', {task: task}); | 103 | logger.info('Mengulang trx untuk advice', {task: task}); |
100 | _topupRequest(task); | 104 | _topupRequest(task); |
101 | } else { | 105 | } else { |
102 | logger.info('Terdeteksi trx sama dalam satu hari yang sama', {task: task}); | 106 | logger.info('Terdeteksi trx sama dalam satu hari yang sama', {task: task}); |
103 | callbackReport(task.requestId, '55', 'Terdeteksi trx sama dalam satu hari yang sama'); | 107 | callbackReport(task.requestId, '55', 'Terdeteksi trx sama dalam satu hari yang sama'); |
104 | } | 108 | } |
105 | } | 109 | } |
106 | 110 | ||
107 | function _topupRequest(task) { | 111 | function _topupRequest(task) { |
108 | var pattern = config.h2h_out.request_pattern; | 112 | var pattern = config.h2h_out.request_pattern; |
109 | 113 | ||
110 | var keywords = { | 114 | var keywords = { |
111 | remoteProduct: task.remoteProduct, | 115 | remoteProduct: task.remoteProduct, |
112 | destination: task.destination, | 116 | destination: task.destination, |
113 | pin: config.h2h_out.pin | 117 | pin: config.h2h_out.pin |
114 | } | 118 | } |
115 | 119 | ||
116 | im.saveTask(task, function() { | 120 | im.saveTask(task, function() { |
121 | im.registerResendDelay(task); | ||
122 | |||
117 | var msg = im.createMessage(pattern, keywords); | 123 | var msg = im.createMessage(pattern, keywords); |
118 | imAdaptor.sendMessage(config.h2h_out.partner, msg); | 124 | imAdaptor.sendMessage(config.h2h_out.partner, msg); |
119 | }); | 125 | }); |
120 | 126 | ||
121 | } | 127 | } |
122 | 128 | ||
123 | function topupRequest(task) { | 129 | function topupRequest(task) { |
124 | if (!aaa.isTodayTrx(task)) { | 130 | if (!aaa.isTodayTrx(task)) { |
125 | logger.warn('Maaf, transaksi beda hari tidak dapat dilakukan'); | 131 | logger.warn('Maaf, transaksi beda hari tidak dapat dilakukan'); |
126 | callbackReport(task.requestId, '68', 'Maaf, transaksi beda hari tidak dapat dilakukan'); | 132 | callbackReport(task.requestId, '68', 'Maaf, transaksi beda hari tidak dapat dilakukan'); |
133 | im.cancelResendDelay(task); | ||
127 | return; | 134 | return; |
128 | } | 135 | } |
129 | 136 | ||
130 | im.checkForSameDayDuplicate(task, _topupRequest, onSameDayDupe, _topupRequest); | 137 | im.checkForSameDayDuplicate(task, _topupRequest, onSameDayDupe, _topupRequest); |
131 | } | 138 | } |
132 | 139 | ||
133 | exports.start = start; | 140 | exports.start = start; |
134 | exports.topupRequest = topupRequest; | 141 | exports.topupRequest = topupRequest; |
135 | 142 |