transaction.py
7.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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
82
83
84
85
86
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
from datetime import datetime
from ISO8583.ISOErrors import BitNotSet
from opensipkd.string import (
DateTimeVar,
DateVar, TimeVar,
exception_message,
)
from opensipkd.iso8583.network import Doc as BaseTransaction
from .structure import (
TRANSACTION_BITS,
INQUIRY_CODE,
PAYMENT_CODE,
REPRINT1_CODE,
REPRINT2_CODE,
RC_OK,
ERR_TRANSACTION_DATE,
ERR_SETTLEMENT_DATE,
ERR_OTHER,
ERR_TRANSACTION_DATETIME,
RC_INVALID_NUMBER,
ERR_SETTLEMENT_DATE,
ERR_TRANSACTION_DATETIME,
ERR_TRANSACTION_DATE,
ERR_INVALID_BANK,
ERR_INVALID_NUMBER,
ERR_TRANSACTION_TIME,
)
from opensipkd.waktu import create_datetime
from iso8583_web.scripts.forwarder import Log
CHANNEL_NAMES = {
'INDOMARET': 1,
'ALFAMART': 2,
'ALFAMIDI': 3,
'TOKOPEDIA': 4,
'KASPRO': 5,
'BUKALAPAK': 6,
'VALUESTREAM': 9,
}
class Transaction(BaseTransaction, Log):
def __init__(self, *args, **kwargs):
self.conf = kwargs["conf"]
self.mod_conf = dict()
for key in self.conf['module_conf']:
if key.find('samsat_banten_') < 0:
continue
name = key[14:]
self.mod_conf[name] = self.conf['module_conf'][key]
del kwargs["conf"]
BaseTransaction.__init__(self, *args, **kwargs)
self.transmission_datetime = DateTimeVar()
self.transaction_date = DateVar()
self.settlement_date = DateVar()
self.transaction_time = TimeVar()
self.transaction_datetime = DateTimeVar()
# Override
def get_bit_definition(self):
return TRANSACTION_BITS
# Override
def get_func_name(self):
return self.is_sign_on_request() or self.is_sign_off_request() or \
self.is_echo_request() or \
self.is_inquiry_request() or self.is_payment_request() or \
self.is_reversal()
# Override
def process(self):
func_name = self.from_iso.get_func_name()
if func_name:
func = getattr(self, func_name)
func()
else:
self.ack_function_not_found()
# Override
def set_response(self):
if self.from_iso.is_network_request():
BaseTransaction.set_response(self)
elif self.from_iso.is_transaction():
self.set_transaction_response()
elif self.from_iso.is_reversal():
self.set_reversal_response()
# Override
def setIsoContent(self, raw):
BaseTransaction.setIsoContent(self, raw)
self.raw = raw
def is_transaction_response(self):
return self.getMTI() == '0210'
def is_response(self):
return BaseTransaction.is_response(self) or self.is_transaction_response()
def is_transaction(self):
return self.getMTI() in ['0200', '0210']
def get_transaction_code(self):
return self.getBit(3)
def is_inquiry_response(self):
return self.getMTI() == '0210' and \
self.get_transaction_code() == INQUIRY_CODE
def is_inquiry_request(self):
if not self.is_transaction():
return
code = self.get_transaction_code()
return code == INQUIRY_CODE and 'inquiry_response'
def is_payment_request(self):
if not self.is_transaction():
return
code = self.get_transaction_code()
return code in (PAYMENT_CODE, REPRINT1_CODE, REPRINT2_CODE) and \
'payment_response'
def is_reprint(self):
return self.get_transaction_code() in (REPRINT1_CODE, REPRINT2_CODE)
def set_transaction_response(self):
kini = datetime.now()
self.setBit(12, kini.strftime('%H%M%S'))
self.setBit(13, kini.strftime('%m%d'))
self.setMTI('0210')
# Sesuai kolom yang berisi E (Equal) pada dokumentasi
self.copy([2, 3, 11, 12, 13, 15, 18, 22, 32, 33, 35, 37, 41, 43, 49,
61, 62])
def get_transmission_datetime(self):
raw = self.get_value(7)
self.transmission_datetime.set_raw(raw)
# without time zone
t = self.transmission_datetime.get_value()
# with time zone
t = create_datetime(t.year, t.month, t.day, t.hour, t.minute, t.second)
return t
def get_transaction_date(self):
raw = self.get_value(13)
self.transaction_date.set_raw(raw)
try:
return self.transaction_date.get_value()
except ValueError:
msg = ERR_TRANSACTION_DATE.format(d=raw)
self.ack_other(msg)
def get_settlement_date(self):
raw = self.get_value(15)
self.settlement_date.set_raw(raw)
try:
return self.settlement_date.get_value()
except ValueError:
msg = ERR_SETTLEMENT_DATE.format(d=raw)
self.ack_other(msg)
def get_transaction_date_raw(self):
return self.get_value(13)
def get_transaction_datetime_raw(self):
return self.get_transaction_date_raw() + self.get_transaction_time_raw()
def get_transaction_datetime(self):
raw = self.get_transaction_datetime_raw()
self.transaction_datetime.set_raw(raw)
try:
return self.transaction_datetime.get_value()
except ValueError:
self.ack_transaction_datetime()
def get_transaction_time_raw(self):
return self.get_value(12)
def get_transaction_time(self):
raw = self.get_transaction_time_raw()
self.transaction_time.set_raw(raw)
try:
return self.transaction_time.get_value()
except ValueError:
self.ack_transaction_time()
def ack_transaction_datetime(self):
raw = self.get_transaction_datetime_raw()
msg = ERR_TRANSACTION_DATETIME.format(raw=[raw])
self.ack_other(msg)
def ack_transaction_time(self):
raw = self.get_transaction_time_raw()
msg = ERR_TRANSACTION_TIME.format(raw=[raw])
self.ack_other(msg)
def get_bit_invoice_profile(self):
return 61
def get_invoice_id_raw(self):
return self.get_value(self.get_bit_invoice_profile())
def set_invoice_profile(self, raw):
self.setBit(self.get_bit_invoice_profile(), raw)
def get_ntb(self):
return self.get_value(37)
def set_ntb(self, ntb):
self.setBit(37, ntb)
def set_ntp(self, ntp):
self.setBit(47, ntp)
def get_amount(self):
return int(self.get_value(4))
def get_channel_id(self):
return self.get_value(18)
def get_channel_name(self):
try:
s = self.get_value(43)
except BitNotSet:
return ''
t = s.split()
return t and t[0] or ''
def get_channel_name_to_id(self):
name = self.get_channel_name()
if name in CHANNEL_NAMES:
s = CHANNEL_NAMES[name]
return str(s).zfill(3)
return '000'
def get_bank_ip(self):
return self.conf['ip']
def get_bank_id(self):
# if 'id' in self.conf:
# return self.conf['id'] # bjb
return int(self.from_iso.get_value(32))
def is_reversal(self):
s = self.getMTI()
return s[:2] == '04' and 'reversal_response'
def set_reversal_response(self):
s = self.from_iso.getMTI()
mti = s[:2] + '1' + s[3:] # 0400 -> 0410, 0401 -> 0411
self.setMTI(mti)
self.copy(from_iso=self.from_iso)
def ack_other(self, msg=ERR_OTHER):
self.setBit(62, msg)
BaseTransaction.ack_other(self, msg)
def ack_timeout(self, msg='Biller Timeout'):
self.ack(68, msg)
def set_transaction_code(self, code):
self.setBit(3, code)