Commit 0ce842ce by aa.gusti

Samsat init

1 parent d99457b1
###
# app configuration
# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
use = egg:iso8583_web
pyramid.reload_templates = true
pyramid.debug_authorization = false
pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.default_locale_name = id
pyramid.includes =
pyramid_debugtoolbar
sqlalchemy.url = postgresql://user:pass@localhost/dbname
timezone = Asia/Jakarta
localization = id_ID.UTF-8
mail.host = localhost
mail.port = 25
mail.username = user@example.com
mail.password = FIXME
mail.sender_name = Example Name
# By default, the toolbar only appears for clients from IP addresses
# '127.0.0.1' and '::1'.
# debugtoolbar.hosts = 127.0.0.1 ::1
###
# wsgi server configuration
###
[server:main]
use = egg:waitress#main
listen = localhost:6543
###
# logging configuration
# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
keys = root, iso8583_web
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = INFO
handlers = console
[logger_iso8583_web]
level = DEBUG
handlers =
qualname = iso8583_web
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s
###
# logging configuration
# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
keys = root, iso8583_web
[handlers]
keys = console, file
[formatters]
keys = generic
[logger_root]
level = INFO
handlers = console, file
[logger_iso8583_web]
level = DEBUG
handlers =
qualname = iso8583_web
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
[handler_file]
class = FileHandler
args = ('/home/sugiana/log/bank.log', 'a')
level = DEBUG
formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)s %(message)s
[host_pemda]
ip = 127.0.0.1
port = 10002
listen = true
streamer = bjb_with_suffix
timeout = 60
module = opensipkd.iso8583.bjb.pbb.test
# Aktifkan web server dimana inquiry dkk bisa dilakukan melalui web client.
[web]
port = 7000
threads = 12
[web_rpc]
route_path = /rpc
host = pemda
module = iso8583_web.scripts.views.jsonrpc
###
# logging configuration
# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
keys = root, iso8583_web
[handlers]
keys = console, file
[formatters]
keys = generic
[logger_root]
level = INFO
handlers = console, file
[logger_iso8583_web]
level = DEBUG
handlers =
qualname = iso8583_web
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
[handler_file]
class = FileHandler
args = ('/home/sugiana/log/pemda.log', 'a')
level = DEBUG
formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)s %(message)s
[module_opensipkd.iso8583.bjb.pbb.bogor_kota]
db_url = postgresql://user:pass@localhost/db
db_pool_size = 50
db_max_overflow = 100
persen_denda = 2
nip_pencatat = 999999999
# Tempat pembayaran
kd_kanwil = 01
kd_kantor = 01
# Penerjemahan nilai bit NN menjadi kd_tp
# Prioritas sesuai urutan
kd_tp =
bit42:TOKOPEDIA:46
bit42:BUKALAPAK:47
bit43:INDOMARET:48
bit43:ALFAMART:49
bit18:6010:69
bit18:6011:71
bit18:6012:72
bit18:6013:73
bit18:6014:74
bit18:6015:75
bit18:6016:76
bit18:6017:77
bit0:default:20
[host_bjb]
ip = 127.0.0.1
port = 10002
listen = false
streamer = bjb_with_suffix
timeout = 60
module = opensipkd.iso8583.bjb.pbb.bogor_kota
[host_mitracomm]
ip = 127.0.0.1
port = 8583
listen = true
streamer = mitracomm
timeout = 60
module = opensipkd.iso8583.bjb.pbb.bogor_kota
###
# logging configuration
# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
keys = root, iso8583_web
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = INFO
handlers = console
[logger_iso8583_web]
level = DEBUG
handlers =
qualname = iso8583_web
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)s %(message)s
# Aktifkan web server jika ingin inquiry dll melalui web client.
[web]
port = 7001
threads = 12
[web_host_linkaja]
ip = 127.0.0.1
module = iso8583_web.scripts.views.linkaja
host = bjb
[module_iso8583_web.scripts.views.linkaja]
route_path = /linkaja
db_url = postgresql://user:pass@localhost/agratek
[host_bjb]
ip = 127.0.0.1
port = 10003
listen = false
streamer = bjb_with_suffix
###
# logging configuration
# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
keys = root, iso8583_web
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = INFO
handlers = console
[logger_iso8583_web]
level = DEBUG
handlers =
qualname = iso8583_web
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)s %(message)s
# Aktifkan web server agar inquiry dll bisa dilakukan melalui web client.
[web]
port = 7000
threads = 12
[web_host_teller]
ip = 127.0.0.1
module = iso8583_web.scripts.views.jsonrpc
host = pemda
[module_iso8583_web.scripts.views.jsonrpc]
route_path = /rpc
[host_pemda]
ip = 127.0.0.1
port = 10002
listen = true
streamer = bjb_with_suffix
...@@ -14,6 +14,7 @@ def main(argv=sys.argv): ...@@ -14,6 +14,7 @@ def main(argv=sys.argv):
module_name = conf.get(section, 'module') module_name = conf.get(section, 'module')
if module_name != 'iso8583_web.scripts.views.linkaja': if module_name != 'iso8583_web.scripts.views.linkaja':
continue continue
db_url = conf.get(section, 'db_url') db_url = conf.get(section, 'db_url')
engine = create_engine(db_url) engine = create_engine(db_url)
engine.echo = True engine.echo = True
......
...@@ -16,7 +16,7 @@ ROUTE = 'rpc' ...@@ -16,7 +16,7 @@ ROUTE = 'rpc'
conf = dict() conf = dict()
class Webjob(BaseWebJob): class WebJob(BaseWebJob):
def timeout_error(self): # override def timeout_error(self): # override
raise JsonRpcBillerNetwork(message='Timeout') raise JsonRpcBillerNetwork(message='Timeout')
......
...@@ -75,7 +75,7 @@ def get_db_session(): ...@@ -75,7 +75,7 @@ def get_db_session():
return conf['db_session'] return conf['db_session']
class Webjob(BaseWebJob): class WebJob(BaseWebJob):
def timeout_error(self): # override def timeout_error(self): # override
return TimeoutError() return TimeoutError()
......
...@@ -7,10 +7,9 @@ from sqlalchemy import ( ...@@ -7,10 +7,9 @@ from sqlalchemy import (
ForeignKey, ForeignKey,
func, func,
JSON, JSON,
) )
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base() Base = declarative_base()
...@@ -88,3 +87,44 @@ class Log(Base): ...@@ -88,3 +87,44 @@ class Log(Base):
bit_102 = Column(String(32)) bit_102 = Column(String(32))
bit_107 = Column(String(8)) bit_107 = Column(String(8))
bit_062_data = Column(JSON) bit_062_data = Column(JSON)
class LogSam(Base):
__tablename__ = 'log_sam'
id = Column(Integer, primary_key=True)
created = Column(
DateTime(timezone=True), nullable=False, server_default=func.now())
rpc_id = Column(Integer, ForeignKey(Rpc.id), nullable=False)
ip = Column(String(15))
conf_name = Column(String(16), nullable=False)
message = Column(JSON)
mti = Column(String(4), nullable=False)
# bit_002 = Column(String(99))
bit_003 = Column(String(6))
# bit_004 = Column(String(12))
# bit_007 = Column(String(10))
# bit_011 = Column(String(6))
# bit_012 = Column(String(6))
# bit_013 = Column(String(4))
# bit_015 = Column(String(4))
# bit_018 = Column(String(4))
# bit_022 = Column(String(3))
# bit_032 = Column(String(4))
# bit_033 = Column(String(10))
# bit_035 = Column(String(99))
# bit_037 = Column(String(12))
# bit_039 = Column(String(2))
# bit_041 = Column(String(8))
# bit_042 = Column(String(15))
# bit_043 = Column(String(40))
# bit_047 = Column(String(99))
# bit_048 = Column(String(99))
# bit_049 = Column(String(3))
# bit_059 = Column(String(16))
# bit_060 = Column(String(3))
# bit_061 = Column(String(22))
# bit_062 = Column(String(512))
# bit_063 = Column(String(255))
# bit_102 = Column(String(32))
# bit_107 = Column(String(8))
bit_062_data = Column(JSON)
import transaction
import venusian
from ISO8583.ISOErrors import BitNotSet
from deform import (
ValidationFailure,
)
from iso8583_web.scripts.logger import (
log_web_info,
log_web_debug)
from iso8583_web.scripts.views import WebJob
from opensipkd.string import (
FixLength,
)
from pyramid.view import (
notfound_view_config,
)
from .structure import INVOICE_PROFILE
from .structure import Transaksi
from ..linkaja import (
WebJob,
# View as BaseView,
is_inquiry, RENDERER, get_db_session, is_reversal, is_payment, get_method,
get_form, date_from_str, csv_method, get_template_response, get_inquiry, get_payment)
from .. import View as BaseView
from ..linkaja.exceptions import (
InvoiceIdError,
NeedPostError,
InternalError,
HostError,
AlreadyPaidError,
BaseError,
AmountError,
BillRefNotFound,
PaymentNotFound,
)
from ..linkaja.models import (Rpc, LogSam)
from ..linkaja.structure import (
InquiryResponse,
PaymentResponse,
)
ROUTE = 'linkaja/sambat'
conf = dict()
# def get_inquiry(data):
# DBSession = get_db_session()
# bill_ref = int(data['bill_ref'])
# q = DBSession.query(Rpc).filter_by(id=bill_ref)
# return q.first()
# def get_payment(data):
# DBSession = get_db_session()
# bill_ref = int(data['bill_ref'])
# q = DBSession.query(Rpc).\
# filter_by(inquiry_id=bill_ref, trx_type='022')
# q = q.order_by(Rpc.id.desc())
# return q.first()
# def get_template_response(data):
# if is_inquiry(data):
# return InquiryResponse()
# d = PaymentResponse()
# d['Bill Ref'] = data['bill_ref']
# return d
# view decorator
# class sambat_method(object):
# def __init__(self, **kw):
# self.kw = kw
#
# def __call__(self, wrapped):
# kw = self.kw.copy()
# depth = kw.pop('_depth', 0)
#
# def callback(context, name, ob):
# config = context.config.with_package(info.module)
# config.add_view(view=ob, renderer=RENDERER, **kw)
#
# info = venusian.attach(
# wrapped, callback, category='pyramid', depth=depth + 1)
# if info.scope == 'class':
# # ensure that attr is set if decorating a class method
# kw.setdefault('attr', wrapped.__name__)
#
# kw['_info'] = info.codeinfo # fbo action_method
# return wrapped
class View(BaseView):
def get_web_job_cls(self): # Override
return WebJob
def not_found_error(self, hostname): # Override
return HostError(hostname)
def not_running_error(self, hostname): # Override
msg = 'Host {} belum terhubung'.format(hostname)
return InternalError(msg, 'Sedang offline')
def create_iso_log(self, iso, rpc):
conf = self.get_iso_conf()
iso_log = LogSam(
mti=iso.mti,
rpc_id=rpc.id,
ip=conf['ip'],
conf_name=conf['name'],
message=iso.data,
bit_003=iso.data["processingCode"])
# for bit in iso.get_bit_definition():
# try:
# value = iso.getBit(bit)
# except BitNotSet:
# continue
# field = 'bit_{}'.format(str(bit).zfill(3))
# setattr(iso_log, field, value)
try:
data = iso.data["additionalData"]
profile = FixLength(INVOICE_PROFILE)
profile.set_raw(data)
iso_log.bit_062_data = profile.to_dict()
except BitNotSet:
pass
return iso_log
def before_send_iso(self, data, inq, pay, req):
DBSession = get_db_session()
web_conf = self.get_web_conf()
row = Rpc(
ip=self.request.client_addr,
conf_name=web_conf['name'],
merchant=data['merchant'],
terminal=data['terminal'],
trx_type=data['trx_type'],
msisdn=data['msisdn'],
acc_no=data['acc_no'],
stan=req.get_stan())
row.trx_date = date_from_str(data['trx_date']),
if data.get('msg'):
row.msg = data['msg']
if data.get('amount'):
row.amount = int(data['amount'])
if not is_inquiry(data):
row.inquiry_id = inq and inq.id or pay.inquiry_id
row.ntb = data['trx_id']
with transaction.manager:
DBSession.add(row)
DBSession.flush()
DBSession.expunge_all() # Agar dapat row.id
iso_log = self.create_iso_log(req, row)
DBSession.add(iso_log)
return row
def after_send_iso(self, data, inq, pay, row, iso_resp):
DBSession = get_db_session()
iso_log = self.create_iso_log(iso_resp, row)
iso_data = iso_resp.response
web_data = get_template_response(data)
if iso_data["responseCode"] == '00':
web_data['Response Code'] = '00'
if is_inquiry(data):
web_data['Bill Ref'] = str(row.id)
if iso_data["additionalData"]:
profile = FixLength(INVOICE_PROFILE)
profile.set_raw(iso_data["additionalData"])
iso_log.bit_062_data = profile.to_dict()
web_data['Biller Name'] = row.biller_name = \
' '.join([profile['NOMOR POLISI'], profile['NAMA PEMILIK'].strip()])
web_data['Bill Amount'] = iso_data["amountTransaction"].lstrip('0')
if "numberTransactionP" in iso_data and iso_data["numberTransactionP"]:
web_data['Transaction ID'] = row.ntp = iso_data["numberTransactionP"] # NTP
err = None
elif iso_data["responseCode"] in ['33', '55']:
err = InvoiceIdError()
elif iso_data["responseCode"] == '54':
if is_reversal(data):
err = PaymentNotFound()
else:
err = AlreadyPaidError()
elif iso_data["responseCode"] == '51':
err = AmountError()
else:
err = BaseError()
if err:
web_data.from_err(err)
row.resp_msg = web_data['Notification Message']
self.log_send(web_data.values)
row.resp_code = web_data['Response Code']
row.resp_msg = web_data['Notification Message']
with transaction.manager:
DBSession.add(row)
DBSession.add(iso_log)
return web_data
def get_response(self, data):
# todo: merubah get response
log_web_debug("Start Response")
p = dict(invoice_id=data['acc_no'])
inq = pay = None
if not is_inquiry(data):
p['amount'] = data['amount']
p['ntb'] = data['trx_id']
if is_payment(data):
inq = get_inquiry(data)
if not inq:
print("Inquiry Not Found")
raise BillRefNotFound()
else:
pay = get_payment(data)
if not pay:
print("Payment Not Found")
raise BillRefNotFound()
p['stan'] = pay.stan
# conn = self.get_connection()
method = get_method(data)
# iso_func = getattr(conn.job, method)
iso_req = Transaksi(p, method, inq, pay)
row = self.before_send_iso(data, inq, pay, iso_req)
iso_req.send()
return self.after_send_iso(data, inq, pay, row, iso_req)
@csv_method(route_name=ROUTE)
def view_trx_sambat(self):
self.validate()
if not self.request.POST:
self.log_receive('GET {}'.format(self.request.GET))
raise NeedPostError()
items = self.request.POST.items()
self.log_receive('POST {}'.format(dict(items)))
items = self.request.POST.items()
form = get_form()
try:
c = form.validate(items)
except ValidationFailure as e:
d = e.error.asdict()
msg = e.error
for field, err in d.items():
msg = '{} {}'.format(field, err)
break
raise InternalError(msg)
data = dict(c)
return self.get_response(data)
# try:
# r = self.get_response(data)
# self.log_send(r)
# return r
# except BaseError as e:
# r = get_template_response(data)
# r['Response Code'] = e.code
# r['Notification Message'] = e.message
# return r
# @notfound_view_config()
# def view_not_found(self):
# msg = 'Path {} tidak ada'.format(self.request.path)
# self.log_receive(msg, True)
# return self.request.exception
# Dipanggil read_conf.py
def init(cfg):
conf.update(cfg)
# Dipanggil forwarder.py
def pyramid_init(config):
# config.add_renderer(RENDERER, 'iso8583_web.scripts.views.linkaja.Renderer')
config.add_route(ROUTE, conf['route_path'])
log_web_info('LinkAja Sambat route path {}'.format(conf['route_path']))
# pool_size = int(conf.get('db_pool_size', 50))
# max_overflow = int(conf.get('db_max_overflow', 100))
# engine = create_engine(
# conf['db_url'], pool_size=pool_size, max_overflow=max_overflow)
# session_factory = sessionmaker(bind=engine)
# conf['db_session'] = scoped_session(session_factory)
# register(conf['db_session'])
# import colander
# from opensipkd.string.row import Row
# from .exceptions import InternalError
import requests
from iso8583_web.scripts.views.linkaja import get_db_session, AlreadyPaidError, BillRefNotFound
from iso8583_web.scripts.views.linkaja.models import LogSam
from iso8583_web.tools.this_framework import get_settings
from datetime import datetime
INQ_REQ = {
"primaryAccountNumber": "622011888888888888",
"processingCode": "321000",
"amountTransaction": "",
"settlementDate": "0326",
"merchantType": "6015",
"aggregatorCode": "W0216",
"caCode": "CA1830",
"terminalAggregator": {
"terminalIdentifierNumber": "7782",
"terminalName": "BJBSAM",
"cardAcceptorName": "BJBSAM"
},
"currencyCode": "360",
"amountInformation": {
"billAmount": "",
"feeBJB": "",
"feeAggregator": "",
"totalAmount": ""
},
"pay": "PAY",
"featureCode": "009",
"billInformation": {
"bills": [{
"info": "1000000108767"
}
]
},
"sourceAccountNumber": "10023269392100",
"destinationAccountNumber": "1",
"systemTraceAuditNumber": "",
"additionalData": "",
"timeLocalTransaction": "090210",
"localTransactionDate": "0326",
"transmissionDateTime": "0903173122",
"posEntryModeCode": "110",
"track2Data": "622011888888888888=9912?",
"sequenceNumber": "1"
}
PAY_REQ = \
{
"processingCode": "521000",
"sequenceNumber": "",
"sourceAccountNumber": "0098889231001",
"systemTraceAuditNumber": "",
"terminalAggregator": {
"cardAcceptorName": "NAEE ",
"terminalIdentifierNumber": "1 ",
"terminalName": "TERM "
},
"settlementDate": "0326",
"timeLocalTransaction": "090210",
"track2Data": "622011888888888888=9912?",
"transmissionDateTime": "0107180458"
}
def send_data(json_data):
settings = get_settings()
bjb_sambat_url = "bjb_sambat_url" in settings and settings["bjb_sambat_url"] or \
"http://localhost/bjb/sambat/test"
data = json_data
if json_data["processingCode"] == '321000':
return INQ_RESP
elif json_data["processingCode"] == '521000':
return PAY_RESP
return requests.post(bjb_sambat_url, data=data)
class Transaksi(object):
def __init__(self, p, method, inq, pay):
self.settings = get_settings()
self.response = None
if method == "reversal": # data Payment ada (berarti reversal)
self.mti = "0400"
self.data["processingCode"] = "521000"
elif method == "payment": # data Inq ada (berarti payment)
db_session = get_db_session()
pay = db_session.query(LogSam).filter_by(rpc_id=inq.id, mti="0200", bit_003='521000').first()
if pay:
pay = db_session.query(LogSam).filter_by(rpc_id=inq.id, mti="0210", bit_003='521000').first()
if pay:
raise AlreadyPaidError()
inq = db_session.query(LogSam).filter_by(rpc_id=inq.id, mti="0200", bit_003='321000').first()
if not inq:
raise BillRefNotFound()
self.mti = "0200"
self.data = inq.message
self.data["processingCode"] = "521000"
self.set_local_time()
else:
self.mti = "0200"
self.data = INQ_REQ.copy()
self.data["caCode"] = "ca_code" in self.settings and self.settings["ca_code"] or "1234"
self.data["processingCode"] = "321000"
self.data["billInformation"]["bills"][0]["info"] = p["invoice_id"]
self.set_local_time()
def set_local_time(self):
time = datetime.now()
self.data["timeLocalTransaction"] = time.strftime("%HHmiss")
self.data["localTransactionDate"] = time.strftime("%MMDD")
self.data["transmissionDateTime"] = time.strftime("%MMDDHHmiss")
def get_stan(self):
return self.data["systemTraceAuditNumber"]
def send(self):
self.response = send_data(self.data)
self.mti = self.mti == "0200" and "0210" or "0410"
INVOICE_PROFILE = [
("NOMOR BAYAR", 16, "N"),
("NOMOR RANGKA", 25),
("NOMOR MESIN", 25),
("NOMOR IDENTITAS", 18, "N"),
("NAMA PEMILIK", 25),
("ALAMAT PEMILIK", 40),
("NOMOR POLISI", 9),
("WARNA PLAT", 6),
("MILIK KE", 3, "N"),
("NAMA JENIS KB", 15),
("NAMA MEREK KB", 15),
("NAMA MODEL KB", 30),
("TAHUN BUATAN", 4, "N"),
("TGL AKHIR PAJAK LAMA", 8, "N"),
("TGL AKHIR PAJAK BARU", 8, "N"),
("POKOK BBN", 12, "N"),
("DENDA BBN", 12, "N"),
("POKOK PKB", 12, "N"),
("DENDA PKB", 12, "N"),
("POKOK SWD", 12, "N"),
("DENDA SWD", 12, "N"),
("POKOK ADM", 12, "N"),
# ("STNK POKOK", 12, "N"),
("ADM TNKB", 12, "N"),
("JUMLAH", 12, "N"),
("KETERANGAN", 90),
("RESERVED_01", 5)
]
INQ_RESP = \
{
"additionalData": "361198483250691012345678901234564 54P879211 3603110611710004 TUMINO NUANSA MEKARSARI B - 1 / 15 RT 004/006 KA 3538 XCBIRU 001SEPEDA MOTOR R2YAMAHA 54P (CAST WHEEL) AT 20132020090920210909000000000000000000000000000000154000000000000000000000035000000000000000000000000000000000000000000000189000SUKSES 01",
"aggregatorCode": "W0216",
"amountInformation": {
"billAmount": "890000",
"feeAggregator": "0",
"feeBJB": "0",
"totalAmount": "890000"
},
"amountTransaction": "890000",
"billInformation": {
"bills": [
{
"info": "1000000108767"
}, {
"info": "ALBUS DUMBLEDORE"
}, {
"info": "BLACK MAGIC"
}, {
"info": "BLACK MAGIC 101"
}, {
"info": "890000"
}, {
"info": "0"
}, {
"info": "2019"
}, {
"info": "0"
}, {
"info": " "
}, {
"info": " REG"
}, {
"info": " "
}
]
},
"caCode": "CA1830",
"currencyCode": "360",
"destinationAccountNumber": "0012199936360 ",
"featureCode": "009",
"localTransactionDate": "0326",
"merchantType": "6015",
"pay": "PAY",
"posEntryModeCode": "110",
"primaryAccountNumber": "622011888888888888",
"processingCode": "321000",
"responseCode": "00",
"sequenceNumber": "000000880977",
"settlementDate": "0326",
"sourceAccountNumber": "0098889231001",
"systemTraceAuditNumber": "880977",
"terminalAggregator": {
"cardAcceptorName": "NAEE ",
"terminalIdentifierNumber": "1 ",
"terminalName": "TERM "
},
"timeLocalTransaction": "090210",
"track2Data": "622011888888888888=9912?",
"transmissionDateTime": "0107180458"
}
# PAYMENT
PAY_RESP = \
{
"additionalData": "'361198483250691012345678901234564 54P879211 3603110611710004 TUMINO NUANSA MEKARSARI B - 1 / 15 RT 004/006 KA 3538 XCBIRU 001SEPEDA MOTOR R2YAMAHA 54P (CAST WHEEL) AT 20132020090920210909000000000000000000000000000000154000000000000000000000035000000000000000000000000000000000000000000000189000SUKSES 01",
"aggregatorCode": "W0216",
"amountInformation": {
"billAmount": "206500",
"feeAggregator": "0",
"feeBJB": "0",
"totalAmount": "206500"
},
"amountTransaction": "000000890000",
"billInformation": {
"bills": [{
"info": "1000000108767"
}, {
"info": "ALBUS DUMBLEDORE"
}, {
"info": "BLACK MAGIC"
}, {
"info": "BLACK MAGIC 101"
}, {
"info": "890000"
}, {
"info": "0"
}, {
"info": "2019"
}, {
"info": "0"
}, {
"info": " "
}, {
"info": " REG"
}, {
"info": " "
}
]
},
"caCode": "CA1830",
"currencyCode": "360",
"destinationAccountNumber": "0012199936360 ",
"featureCode": "009",
"localTransactionDate": "0326",
"merchantType": "6015",
"numberTransactionBank": '1234567890',
"numberTransactionP": '0987654321',
"pay": "PAY",
"posEntryModeCode": "110",
"primaryAccountNumber": "622011888888888888",
"processingCode": "521000",
"responseCode": "00",
"sequenceNumber": "000000502959",
"settlementDate": "0326",
"sourceAccountNumber": "0098889231001",
"systemTraceAuditNumber": "502959",
"terminalAggregator": {
"cardAcceptorName": "NAEE ",
"terminalIdentifierNumber": "1 ",
"terminalName": "TERM "
},
"timeLocalTransaction": "090210",
"track2Data": "622011888888888888=9912?",
"transmissionDateTime": "0107180458"
}
###
# app configuration
# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
use = egg:iso8583_web
pyramid.reload_templates = false
pyramid.debug_authorization = false
pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.default_locale_name = id
sqlalchemy.url = postgresql://user:pass@localhost/dbname
timezone = Asia/Jakarta
localization = id_ID.UTF-8
mail.host = localhost
mail.port = 25
mail.username = user@example.com
mail.password = FIXME
mail.sender_name = Example Name
###
# wsgi server configuration
###
[server:main]
use = egg:waitress#main
listen = *:6543
###
# logging configuration
# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
keys = root, iso8583_web
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = WARN
handlers = console
[logger_iso8583_web]
level = WARN
handlers =
qualname = iso8583_web
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!