Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
Owo Sugiana
/
iso8583-web
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit a1c645b7
authored
Jul 19, 2020
by
Owo Sugiana
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
Konfigurasi web yang lebih ringkas
1 parent
cbbddf07
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
540 additions
and
114 deletions
CHANGES.txt
README.rst
iso8583.ini → iso8583-bank.ini
iso8583-pemda.ini
iso8583_web/read_conf.py
iso8583_web/scripts/forwarder.py
iso8583_web/scripts/init_db_linkaja.py
iso8583_web/scripts/views/__init__.py
iso8583_web/scripts/views/jsonrpc.py
iso8583_web/scripts/views/linkaja/__init__.py
iso8583_web/scripts/views/linkaja/exceptions.py
iso8583_web/scripts/views/linkaja/structure.py
iso8583_web/scripts/web_client.py
iso8583_web/scripts/web_client_linkaja.py
CHANGES.txt
View file @
a1c645b
0.2.1 2020-07-19
----------------
- Konfigurasi web yang lebih ringkas
- LinkAja RC 48 saat payment tidak ditemukan
- Contoh konfigurasi untuk simulasi sebagai bank
- Dokumentasi yang lebih baik dan fokus pada transaksi
0.2 2020-06-30
0.2 2020-06-30
--------------
--------------
- Jalur web juga bisa multi modul
- Jalur web juga bisa multi modul
...
...
README.rst
View file @
a1c645b
...
@@ -2,12 +2,10 @@ Daemon ISO8583
...
@@ -2,12 +2,10 @@ Daemon ISO8583
==============
==============
Daemon ISO8583 ini bisa sebagai client maupun server. Berikut ini cara
Daemon ISO8583 ini bisa sebagai client maupun server. Berikut ini cara
pemasangannya. Nama paketnya mengandung web karena ia bisa dihubungi melalui
pemasangannya. Nama paketnya mengandung web karena ia bisa dihubungi melalui
web service JsonRPC untuk melakukan inquiry, payment, dan reversal.
web service JSON-RPC untuk inquiry, payment, dan reversal.
Pemasangan
Pemasangan
----------
----------
Buat Python virtual environment::
Buat Python virtual environment::
$ python3 -m venv ~/env
$ python3 -m venv ~/env
...
@@ -15,119 +13,327 @@ Buat Python virtual environment::
...
@@ -15,119 +13,327 @@ Buat Python virtual environment::
Awali dengan memasang paket `ebcdic <https://pypi.org/project/ebcdic/>`_
Awali dengan memasang paket `ebcdic <https://pypi.org/project/ebcdic/>`_
yang dibutuhkan `ISO8583 <https://pypi.org/project/ISO8583/>`_::
yang dibutuhkan `ISO8583 <https://pypi.org/project/ISO8583/>`_::
$ ~/env/bin/pip install
-r requirements.txt
$ ~/env/bin/pip install
ebcdic
Pemasangan yang tidak otomatis ini agar tidak menimbulkan kegagalan. Lanjut::
Pemasangan yang tidak otomatis ini agar tidak menimbulkan kegagalan. Lanjut::
$ git clone https://git.opensipkd.com/sugiana/iso8583-web
$ ~/env/bin/pip install git+https://git.opensipkd.com/sugiana/iso8583-web
$ ~/env/bin/pip install -e 'iso8583-web[testing]'
S
aatnya mencoba:
:
S
elanjutnya kita membutuhkan tiga terminal untuk simulasi
:
$ cd iso8583-web
1. ISO8583 daemon sebagai pemda. Ini akan mengakses bank ke port 10002.
$ ~/env/bin/pytest iso8583_web/test-conf.py
2. ISO8583 daemon sebagai bank. Ini akan listen di port 10002, dan pada
saat yang sama dia listen di port 7000 sebagai web server.
3. Web client sebagai simulasi aplikasi teller yang akan mengakses web
server tadi.
Pastikan tidak ada pesan ``failure``. Bila ada ``warning`` abaikan saja. Kini
Sebagai Pemda
salinlah file konfigurasi::
-------------
Buat file konfigurasi ``test-pemda.ini``::
$ cp iso8583.ini test-pemda.ini
[loggers]
keys = root, iso8583_web
Sesuaikan isi section ``[host_bjb]``. Anda bisa menambahkan host lainnya
dengan menambahkan awalan ``host_`` pada section.
Jalankan daemon-nya, anggap sebagai pemda (biller)::
[handlers]
keys = console, file
$ ~/env/bin/iso8583 test-pemda.ini
[formatters]
keys = generic
Anda akan mendapat pesan seperti ini::
[logger_root]
level = INFO
handlers = console, file
2019-02-07 20:41:30,180 INFO Connect to 127.0.0.1 port 10002
[logger_iso8583_web]
2019-02-07 20:41:30,180 ERROR [Errno 111] Connection refused
level = DEBUG
qualname = iso8583_web
Biarkan ini aktif. Buka konsol lain. Sekarang kita buat simulator BJB::
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
$ cp iso8583.ini test-bjb.ini
[handler_file]
class = FileHandler
args = ('/home/sugiana/log/pemda.log', 'a')
level = DEBUG
formatter = generic
Ubah file ``test-bjb.ini`` pada baris::
[formatter_generic]
format = %(asctime)s %(levelname)s %(message)s
[module_opensipkd.iso8583.bjb.pbb.bogor_kota]
db_url = postgresql://user:pass@localhost/db
persen_denda = 2
nip_pencatat = 999999999
kd_kanwil = 01
kd_kantor = 01
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]
[host_bjb]
ip = 127.0.0.1
ip = 127.0.0.1
port = 10002
port = 10002
listen = false
listen = false
streamer = bjb_with_suffix
streamer = bjb_with_suffix
timeout = 60
module = opensipkd.iso8583.bjb.pbb.bogor_kota
menjadi::
Kita bisa menambahkan host lainnya dengan menambahkan awalan ``host_`` pada
section, misalnya ``host_mitracomm``.
[host_pemda]
Modul ``opensipkd.iso8583.bjb.pbb.bogor_kota`` tidak ada di paket ini sehingga
ip = 127.0.0.1
kita perlu memasangnya::
port = 10002
listen = true
$ ~/env/bin/pip install git+https://git.opensipkd.com/sugiana/opensipkd-iso8583-bjb
streamer = bjb_with_suffix
Simpan, lalu jalankan
::
Jalankan daemon-nya
::
$ ~/env/bin/iso8583 test-bjb.ini
$ ~/env/bin/iso8583 test-pemda.ini
Anda akan mendapat pesan seperti ini::
2019-02-07 20:41:30,180 INFO Connect to 127.0.0.1 port 10002
2019-02-07 20:41:30,180 ERROR [Errno 111] Connection refused
Abaikan dulu *refused* itu karena daemon bank memang belum ada. Biarkan ini
aktif.
Log File
Sebagai Bank
--------
------------
Untuk menyimpan log ke dalam file lakukan perubahan pada file konfigurasi (INI
Buka terminal ke-2, dan buat file ``test-bank.ini``::
file). Pada section ``[handlers]`` baris ``keys`` tambahkan ``file`` sehingga
menjadi::
[loggers]
keys = root, iso8583_web
[handlers]
[handlers]
keys = console, file
keys = console, file
Pada section ``[logger_root]`` baris ``handlers`` tambahkan ``file`` sehingga
[formatters]
menjadi::
keys = generic
[logger_root]
[logger_root]
level = INFO
level = INFO
handlers = console, file
handlers = console, file
Setelah section ``[handler_console]`` tambahkan section ``[handler_file]``
[logger_iso8583_web]
seperti ini::
level = DEBUG
qualname = iso8583_web
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
[handler_file]
[handler_file]
class = FileHandler
class = FileHandler
args = ('/home/sugiana/tmp/pemda
.log', 'a')
args = ('/home/sugiana/log/bank
.log', 'a')
level = NOTSET
level = DEBUG
formatter = generic
formatter = generic
Lalu jalankan lagi daemon seperti di atas.
[formatter_generic]
format = %(asctime)s %(levelname)s %(message)s
JsonRpc
[host_pemda]
-------
ip = 127.0.0.1
Ini adalah web service untuk memudahkan pembuatan client. Misalkan kita ingin
port = 10002
membuat aplikasi teller bank. Pada ``test-bjb.ini`` aktifkan section
listen = true
``[web]``::
streamer = bjb_with_suffix
module = opensipkd.iso8583.bjb.pbb.test
[web]
port = 7000
threads = 12
[web_teller]
route_path = /rpc
host = pemda
module = iso8583_web.scripts.view.jsonrpc
allowed_ip =
127.0.0.1
10.8.20.1
Perbedaannya adalah pada:
1. Log file
2. ``listen = true`` yang berarti bank sebagai server-nya
3. Penggunaan modul ``opensipkd.iso8583.bjb.pbb.test`` dimana modul ini
tidak menggunakan database sehingga tidak perlu konfigurasi tambahan.
Juga ada konfigurasi terkait web server yang merupakan gerbang aplikasi teller
untuk transaksi. Perhatikan section ``web`` ini::
[web]
[web]
port = 7000
port = 7000
threads = 12
dimana:
* ``port`` adalah network port yang *listen*. Tentu saja yang dimaksud
adalah HTTP port.
* ``threads`` adalah jumlah *worker* yang siaga. Ini artinya pada saat yang
sama web server ini sanggup menangani 12 web client.
Selanjutnya section ``web_teller``::
[web_teller]
route_path = /rpc
host = pemda
module = iso8583_web.scripts.view.jsonrpc
allowed_ip =
127.0.0.1
10.8.20.1
Section yang berawalan ``web_`` adalah konfigurasi untuk setiap jenis *web client*.
Bandingkan dengan section yang berawalan ``host_`` yang berarti konfigurasi
untuk ISO8583. Berikut penjelasannya:
* ``route_path`` merupakan *URL path*, selalu awali dengan ``/``
* ``host = pemda`` berarti harus ada section ``host_pemda``. Ini merupakan
*routing*, akan diarahkan ke ISO8583 mana HTTP request ini.
* ``module`` merupakan *modul Pyramid* yang akan digunakan untuk menanggapi
*HTTP request*
* ``allowed_ip`` berisi IP yang diperkenankan menggunakan jalur ini. Jika
dikosongkan maka diperkenankan diakses dari IP manapun.
Bila konfigurasi web ini digabungkan maka URL-nya menjadi
``http://127.0.0.1:7000/rpc``.
Sekarang jalankan::
$ ~/env/bin/iso8583 test-bank.ini
Seharusnya ada penampakan seperti ini::
2020-07-18 22:27:44,360 INFO Web server JSON-RPC route path /rpc
2020-07-18 22:27:44,373 INFO Web server listen at 0.0.0.0:7000 with 12 workers
2020-07-18 22:27:44,373 INFO ISO8583 server listen at 0.0.0.0:10002
2020-07-18 22:27:46,592 INFO 127.0.0.1 allowed
2020-07-18 22:27:51,595 INFO 127.0.0.1 pemda 140197249940784 Receive [b'00560800822000000000000004000000000000000718222751222236301\x03']
2020-07-18 22:27:51,596 INFO 127.0.0.1 pemda 140197249940784 Raw to ISO8583 [b'0800822000000000000004000000000000000718222751222236301']
2020-07-18 22:27:51,598 INFO 127.0.0.1 pemda 140197249940784 -> 140197249940688 Decode MTI 0800 Data {7: '0718222751', 11: '222236', 70: '301'}
2020-07-18 22:27:51,602 INFO 127.0.0.1 pemda 140197249940784 -> 140197249940688 Encode MTI 0810 Data {7: '0718222751', 11: '222236', 39: '00', 70: '301'}
2020-07-18 22:27:51,602 INFO 127.0.0.1 pemda 140197249940784 ISO8583 to raw [b'081082200000020000000400000000000000071822275122223600301']
2020-07-18 22:27:51,603 INFO 127.0.0.1 pemda 140197249940784 Send [b'0058081082200000020000000400000000000000071822275122223600301\x03']
Berikut penjelasannya:
1. Baris ``Receive`` bermakna ada *raw stream* yang diterima, yaitu dari
``pemda`` yang berada di terminal pertama tadi.
2. Baris ``Raw to ISO8583`` bermakna hapus *network header* dari raw
stream agar menjadi dokumen ISO8583 saja.
3. Baris ``Decode`` bermakna *terjemahkan dokumen itu* agar mudah dibaca
manusia.
Sampai di sini ketiga baris log tersebut dinamakan *request*. Dalam kasus ini
disebut *echo request* karena:
1. MTI bernilai ``0800``
2. Bit 70 bernilai ``301``
Setiap request perlu mendapat *response* berarti perlu disiapkan *echo
response* yaitu:
1. MTI bernilai ``0810``
2. Bit 70 bernilai ``301``
Kembali ke log tadi, baris berikutnya adalah ``Encode`` yang berarti dokumen
ISO8583 akan disiapkan hingga ``Send``. Ini kebalikan sebelumnya dimana
``Receive`` hingga ``Decode``.
Keenam baris tersebut sering disebut dengan kondisi *echo established* yang
menandakan tidak ada masalah network sehingga siap transaksi.
Setelah *echo established* dengan daemon pemda selanjutnya lakukan *inquiry*
(cek tagihan) dengan cara::
$ ~/env/bin/iso8583_web_client --url=http://127.0.0.1:7000/rpc --invoice-id=3271010001007002701995
Hasilnya::
2020-07-18 23:53:03.150 Request: {'id': 1, 'method': 'inquiry', 'params': [{'invoice_id': '3271010001007002701995'}], 'jsonrpc': '2.0'}
2020-07-18 23:53:04.494 Response: {'jsonrpc': '2.0', 'id': 1, 'result': {'code': 0, 'message': 'OK', 'data': {'3': '341019', '4': '000000019536', '7': '0718235304', '11': '235069', '12': '235303', '13': '0718', '18': '6010', '33': '00110', '39': '00', '61': '3271010001007002701995', '62': '3271010001007002701995UW** *****SNA JL LINCAR I TEGAL GUNDIL BOGOR UTARA JAWA BARAT 00000000012300000000007219951130000000019536000000009378000000028914000000009378'}}}
2020-07-18 23:53:04.499 thread 1 1.3430681228637695 detik stan 235069
2020-07-18 23:53:04.499 Tidak ada yang gagal
Pastikan bit 39 bernilai ``00`` yang berarti siap dibayar. Lanjutkan dengan ``--payment`` dimana opsi ``--amount`` juga harus disertakan,
nilainya diperoleh dari *inquiry response* bit 4::
Kemudian restart daemon-nya. Setelah *echo established* dengan daemon pemda
$ ~/env/bin/iso8583_web_client --url=http://127.0.0.1:7000/rpc --invoice-id=3271010001007002701995 --payment --amount=19536
lakukan *echo request* dengan cara::
$ ~/env/bin/iso8583_web_client
Hasilnya::
Hasilnya menjadi seperti ini::
2020-07-19 05:49:51.532 Request: {'id': 1, 'method': 'payment', 'params': [{'invoice_id': '3271010001007002701995', 'amount': 19536, 'ntb': '0719054951', 'stan': '054951'}], 'jsonrpc': '2.0'}
2020-07-19 05:49:52.217 Response: {'jsonrpc': '2.0', 'id': 1, 'result': {'code': 0, 'message': 'OK', 'data': {'3': '541019', '4': '000000019536', '7': '0719054952', '11': '054237', '12': '054951', '13': '0719', '18': '6010', '33': '00110', '39': '00', '41': '', '42': '', '43': '', '47': '010192430486', '48': '0719054951', '61': '3271010001007002701995', '62': '3271010001007002701995UW** *****SNA JL LINCAR I TEGAL GUNDIL BOGOR UTARA JAWA BARAT 00000000012300000000007219951130000000019536000000009378000000028914000000009378'}}}
2020-07-19 05:49:52.222 thread 1 0.6849231719970703 detik stan 054237
2020-07-19 05:49:52.222 Tidak ada yang gagal
2019-04-22 10:47:03.625 Request: {'method': 'echo', 'params': [{'host': 'pemda'}], 'jsonrpc': '2.0', 'id': 0}
Lagi, pastikan bit 39 bernilai ``00`` yang berarti pembayaran berhasil.
2019-04-22 10:47:03.938 Response: {'jsonrpc': '2.0', 'id': 0, 'result': {'code': 0, 'message': 'OK', 'data': {'7': '0422104703', '11': '104703', '39': '00', '70': '301'}}}
Selanjutnya gunakan opsi ``--reversal`` untuk membatalkan pembayaran ini.
thread 0 0.3129305839538574 detik
Selain ``--amount`` kita juga membutuhkan opsi ``--stan`` dan ``--ntb`` yang
diperoleh saat *payment request* yaitu bit 11 dan bit 48 pada baris *Response*
di atas::
Jika ingin *stress test* silakan gunakan opsi ``-c 10`` yang berarti 10 kali
$ ~/env/bin/iso8583_web_client --url=http://127.0.0.1:7000/rpc --invoice-id=3271010001007002701995 --reversal --amount=19536 --ntb=0719054951 --stan=054237
bersamaan.
JsonRpc Log File
Hasilnya::
----------------
2020-07-19 06:10:58.334 Request: {'id': 1, 'method': 'reversal', 'params': [{'invoice_id': '3271010001007002701995', 'amount': 19536, 'ntb': '0719054951', 'stan': '054237'}], 'jsonrpc': '2.0'}
2020-07-19 06:10:58.847 Response: {'jsonrpc': '2.0', 'id': 1, 'result': {'code': 0, 'message': 'OK', 'data': {'3': '541019', '4': '000000019536', '7': '0719061058', '11': '054237', '39': '00', '48': '0719054951', '61': '3271010001007002701995'}}}
2020-07-19 06:10:58.852 thread 1 0.5126473903656006 detik stan 054237
2020-07-19 06:10:58.852 Tidak ada yang gagal
Pastikan bit 39 bernilai ``00`` yang menandakan pembatalan berhasil.
Stress Test
-----------
Ini adalah tentang mendapatkan jumlah maksimal transaksi yang berhasil pada
saat bersamaan. Gunakan opsi ``--count=12`` yang berarti 12 transaksi pada saat yang sama::
$ ~/env/bin/iso8583_web_client --url=http://127.0.0.1:7000/rpc --invoice-id=3271010001007002701995 --count=12
Hasil akhirnya akan tampak statistik::
2020-07-18 23:56:09.246 Tercepat thread 4 0.6237032413482666 detik stan 235419
2020-07-18 23:56:09.246 Terlama thread 8 2.6911497116088867 detik stan 236181
2020-07-18 23:56:09.246 Rerata 1.9630980730056762 detik / request
2020-07-18 23:56:09.246 Tidak ada yang gagal
Pastikan kita mendapat pesan ``Tidak ada yang gagal``. Angka 12 dipilih sesuai
dengan jumlah ``threads`` pada file konfigurasi ``test-bank.ini``. Silakan
naikkan angkanya hingga:
1. Ada yang gagal, biasanya karena timeout.
2. Kecepatan transaksi rata-rata melampaui ambang batas. Biasanya jangan
sampai lebih dari 15 detik.
Jika salah satu kondisi di atas tercapai maka turunkan nilai ``threads``.
JSON-RPC Log File
-----------------
Biasanya tahap awal pembuatan web client terjadi kesalahan yang tampak di
Biasanya tahap awal pembuatan web client terjadi kesalahan yang tampak di
client namun tak nampak di log web server. Untuk mengatasi hal ini lakukan
client namun tak nampak di log web server. Untuk mengatasi hal ini lakukan
penambahan di file konfigurasi section ``[loggers]`` menjadi seperti ini::
penambahan di file konfigurasi ``test-bank.ini`` pada section ``loggers``
sehingga menjadi seperti ini::
[loggers]
[loggers]
keys = root, iso8583_web, jsonrpc
keys = root, iso8583_web, jsonrpc
Lalu tambahkan section ``
[logger_jsonrpc]
`` berikut ini::
Lalu tambahkan section ``
logger_jsonrpc
`` berikut ini::
[logger_jsonrpc]
[logger_jsonrpc]
level = DEBUG
level = DEBUG
...
@@ -140,4 +346,67 @@ yang seharusnya ``echo`` maka di log akan tampil seperti ini::
...
@@ -140,4 +346,67 @@ yang seharusnya ``echo`` maka di log akan tampil seperti ini::
2019-02-21 14:00:47,135 DEBUG handling id:0 method:eco
2019-02-21 14:00:47,135 DEBUG handling id:0 method:eco
2019-02-21 14:00:47,135 DEBUG json-rpc method not found rpc_id:0 "eco"
2019-02-21 14:00:47,135 DEBUG json-rpc method not found rpc_id:0 "eco"
Semoga dipahami.
LinkAja
-------
Simulasi aplikasi teller sebelumnya menggunakan format JSON-RPC. Kali ini akan
kita coba dengan format yang sudah ditentukan LinkAja (produk PT Telkom). Modul
``linkaja`` membutuhkan database untuk pencatatan transaksi. Buatlah
database-nya terlebih dahulu. Lalu tambahkan baris berikut ini di file
``test-bank.ini``::
[web_linkaja]
route_path = /linkaja
host = pemda
module = iso8583_web.scripts.views.linkaja
db_url = postgresql://user:pass@localhost/db
allowed_ip =
127.0.0.1
10.8.30.1
Coba inquiry::
$ ~/env/bin/iso8583_web_client_linkaja --url=http://127.0.0.1:7000/linkaja --invoice-id=3271010001007002701995
Hasilnya::
2020-07-19 06:17:17.944 Request: {'merchant': 'ldm***1', 'terminal': 'Terminal Name', 'pwd': 'ldm***ss', 'msisdn': '628111234567', 'acc_no': '3271010001007002701995', 'trx_date': '20200719061717', 'trx_type': '021'}
2020-07-19 06:17:18.604 Response 200: ['00:UW** *****SNA:19536:16:'] -> {'Response Code': '00', 'Biller Name': 'UW** *****SNA', 'Bill Amount': '19536', 'Bill Ref': '16', 'Notification Message': ''}
2020-07-19 06:17:18.609 thread 1 0.654482364654541 detik 00:UW** *****SNA:19536:16:
2020-07-19 06:17:18.609 Tidak ada yang gagal
Pastikan ``Response Code`` bernilai ``00`` yang menandakan tagihan siap
dibayar. Lanjut ``--payment``, kali ini sertakan ``--bill-ref`` dan
``--amount`` yang diperoleh dari *inquiry response*::
$ ~/env/bin/iso8583_web_client_linkaja --url=http://127.0.0.1:7000/linkaja --invoice-id=3271010001007002701995 --payment --bill-ref=16 --amount=19536
Hasilnya::
2020-07-19 06:21:00.333 Request: {'merchant': 'ldm***1', 'terminal': 'Terminal Name', 'pwd': 'ldm***ss', 'msisdn': '628111234567', 'acc_no': '3271010001007002701995', 'trx_date': '20200719062100', 'trx_type': '022', 'amount': 19536, 'bill_ref': '16', 'trx_id': '0719062100'}
2020-07-19 06:21:01.056 Response 200: ['00:010123882462:16:'] -> {'Response Code': '00', 'Transaction ID': '010123882462', 'Bill Ref': '16', 'Notification Message': ''}
2020-07-19 06:21:01.061 thread 1 0.717498779296875 detik 00:010123882462:16:
2020-07-19 06:21:01.061 Tercepat 00:010123882462:16:
2020-07-19 06:21:01.061 Terlama 00:010123882462:16:
2020-07-19 06:21:01.061 Rerata 0.717498779296875 detik / request
2020-07-19 06:21:01.061 Tidak ada yang gagal
Lagi, pastikan ``Response Code`` bernilai ``00`` yang berarti pembayaran
berhasil. Lanjut coba reversal, kali ini sertakan ``--trx-id`` yang diperoleh dari
*payment request*::
$ ~/env/bin/iso8583_web_client_linkaja --url=http://127.0.0.1:7000/linkaja --invoice-id=3271010001007002701995 --reversal --bill-ref=16 --amount=19536 --trx-id=0719062100
Hasilnya::
2020-07-19 06:25:13.546 Request: {'merchant': 'ldm***1', 'terminal': 'Terminal Name', 'pwd': 'ldm***ss', 'msisdn': '628111234567', 'acc_no': '3271010001007002701995', 'trx_date': '20200719062513', 'trx_type': '023', 'amount': 19536, 'bill_ref': '16', 'trx_id': '0719062100'}
2020-07-19 06:25:14.121 Response 200: ['00::16:'] -> {'Response Code': '00', 'Transaction ID': '', 'Bill Ref': '16', 'Notification Message': ''}
2020-07-19 06:25:14.126 thread 1 0.5694727897644043 detik 00::16:
2020-07-19 06:25:14.127 Tercepat 00::16:
2020-07-19 06:25:14.127 Terlama 00::16:
2020-07-19 06:25:14.127 Rerata 0.5694727897644043 detik / request
2020-07-19 06:25:14.127 Tidak ada yang gagal
Pastikan ``Response Code`` bernilai ``00`` yang bermakna pembatalan pembayaran
berhasil.
Selamat mencoba.
iso8583.ini
→
iso8583
-bank
.ini
View file @
a1c645b
...
@@ -7,14 +7,14 @@
...
@@ -7,14 +7,14 @@
keys
=
root, iso8583_web
keys
=
root, iso8583_web
[handlers]
[handlers]
keys
=
console
keys
=
console
, file
[formatters]
[formatters]
keys
=
generic
keys
=
generic
[logger_root]
[logger_root]
level
=
INFO
level
=
INFO
handlers
=
console
handlers
=
console
, file
[logger_iso8583_web]
[logger_iso8583_web]
level
=
DEBUG
level
=
DEBUG
...
@@ -27,34 +27,29 @@ args = (sys.stderr,)
...
@@ -27,34 +27,29 @@ args = (sys.stderr,)
level
=
NOTSET
level
=
NOTSET
formatter
=
generic
formatter
=
generic
[handler_file]
class
=
FileHandler
args
=
('/home/sugiana/log/bank.log', 'a')
level
=
DEBUG
formatter
=
generic
[formatter_generic]
[formatter_generic]
format
=
%(asctime)s %(levelname)s %(message)s
format
=
%(asctime)s %(levelname)s %(message)s
# Aktifkan web server jika ingin simulasi sebagai bank dimana inquiry dkk
[host_pemda]
# bisa dilakukan melalui web client.
# [web]
# port = 7000
# threads = 12
#[web_host_linkaja]
#ip = 127.0.0.1
#module = iso8583_web.scripts.views.linkaja
#host = pemda
#[module_iso8583_web.scripts.views.linkaja]
#route_path = /linkaja
#db_url = postgresql://sugiana:a@localhost/agratek
[host_bjb]
ip
=
127.0.0.1
ip
=
127.0.0.1
port
=
10002
port
=
10002
listen
=
fals
e
listen
=
tru
e
streamer
=
bjb_with_suffix
streamer
=
bjb_with_suffix
timeout
=
60
[host_mitracomm]
module
=
opensipkd.iso8583.bjb.pbb.test
ip
=
127.0.0.1
port
=
8583
# Aktifkan web server dimana inquiry dkk bisa dilakukan melalui web client.
streamer
=
mitracomm
[web]
active
=
false
port
=
7000
threads
=
12
[web_rpc]
route_path
=
/rpc
host
=
pemda
module
=
iso8583_web.scripts.views.jsonrpc
iso8583-pemda.ini
0 → 100644
View file @
a1c645b
###
# 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
iso8583_web/read_conf.py
View file @
a1c645b
...
@@ -11,7 +11,7 @@ name_conf = dict()
...
@@ -11,7 +11,7 @@ name_conf = dict()
allowed_ips
=
list
()
allowed_ips
=
list
()
web
=
dict
()
web
=
dict
()
web_
ip
_conf
=
dict
()
web_
path
_conf
=
dict
()
def
get_conf
(
ip
,
port
):
def
get_conf
(
ip
,
port
):
...
@@ -40,6 +40,13 @@ def get_int(conf, section, option, default):
...
@@ -40,6 +40,13 @@ def get_int(conf, section, option, default):
return
default
return
default
def
get_list
(
conf
,
section
,
option
,
default
):
s
=
get_str
(
conf
,
section
,
option
,
''
)
if
s
:
return
s
.
split
()
return
default
MSG_DUPLICATE
=
'IP {ip} port {port} ganda. Perbaiki konfigurasi.'
MSG_DUPLICATE
=
'IP {ip} port {port} ganda. Perbaiki konfigurasi.'
...
@@ -74,8 +81,8 @@ def append_others(cfg, conf, section):
...
@@ -74,8 +81,8 @@ def append_others(cfg, conf, section):
cfg
[
key
]
=
val
cfg
[
key
]
=
val
def
load_module
(
cfg
,
conf
,
section
,
default
):
def
load_module
(
cfg
,
conf
,
section
):
cfg
[
'module'
]
=
get_str
(
conf
,
section
,
'module'
,
default
)
cfg
[
'module'
]
=
conf
.
get
(
section
,
'module'
)
cfg
[
'module_obj'
]
=
get_module_object
(
cfg
[
'module'
])
cfg
[
'module_obj'
]
=
get_module_object
(
cfg
[
'module'
])
module_section
=
'module_'
+
cfg
[
'module'
]
module_section
=
'module_'
+
cfg
[
'module'
]
if
conf
.
has_section
(
module_section
):
if
conf
.
has_section
(
module_section
):
...
@@ -92,14 +99,19 @@ def read_web_conf(conf, section):
...
@@ -92,14 +99,19 @@ def read_web_conf(conf, section):
web
[
'port'
]
=
conf
.
getint
(
section
,
'port'
)
web
[
'port'
]
=
conf
.
getint
(
section
,
'port'
)
web
[
'threads'
]
=
conf
.
getint
(
section
,
'threads'
)
web
[
'threads'
]
=
conf
.
getint
(
section
,
'threads'
)
return
return
if
section
.
find
(
'web_
host_
'
)
!=
0
:
if
section
.
find
(
'web_'
)
!=
0
:
return
return
cfg
=
dict
()
cfg
=
dict
()
cfg
[
'name'
]
=
section
.
split
(
'_'
)[
-
1
]
cfg
[
'name'
]
=
section
.
split
(
'web_'
)[
-
1
]
cfg
[
'ip'
]
=
conf
.
get
(
section
,
'ip'
)
cfg
[
'allowed_ip'
]
=
get_list
(
conf
,
section
,
'allowed_ip'
,
[])
cfg
[
'host'
]
=
conf
.
get
(
section
,
'host'
)
append_others
(
cfg
,
conf
,
section
)
load_module
(
cfg
,
conf
,
section
,
'iso8583_web.scripts.views.jsonrpc'
)
cfg
[
'module_obj'
]
=
get_module_object
(
cfg
[
'module'
])
web_ip_conf
[
cfg
[
'ip'
]]
=
dict
(
cfg
)
try
:
f_init
=
getattr
(
cfg
[
'module_obj'
],
'init'
)
f_init
(
cfg
)
except
AttributeError
:
pass
web_path_conf
[
cfg
[
'route_path'
]]
=
dict
(
cfg
)
def
read_host_conf
(
conf
,
section
):
def
read_host_conf
(
conf
,
section
):
...
@@ -120,7 +132,7 @@ def read_host_conf(conf, section):
...
@@ -120,7 +132,7 @@ def read_host_conf(conf, section):
cfg
[
'echo'
]
=
get_boolean
(
conf
,
section
,
'echo'
,
not
cfg
[
'listen'
])
cfg
[
'echo'
]
=
get_boolean
(
conf
,
section
,
'echo'
,
not
cfg
[
'listen'
])
cfg
[
'timeout'
]
=
get_int
(
conf
,
section
,
'timeout'
,
60
)
cfg
[
'timeout'
]
=
get_int
(
conf
,
section
,
'timeout'
,
60
)
append_others
(
cfg
,
conf
,
section
)
append_others
(
cfg
,
conf
,
section
)
load_module
(
cfg
,
conf
,
section
,
'opensipkd.iso8583.network'
)
load_module
(
cfg
,
conf
,
section
)
if
cfg
[
'listen'
]:
if
cfg
[
'listen'
]:
if
cfg
[
'port'
]
not
in
listen_ports
:
if
cfg
[
'port'
]
not
in
listen_ports
:
listen_ports
.
append
(
cfg
[
'port'
])
listen_ports
.
append
(
cfg
[
'port'
])
...
...
iso8583_web/scripts/forwarder.py
View file @
a1c645b
...
@@ -20,7 +20,7 @@ from ..read_conf import (
...
@@ -20,7 +20,7 @@ from ..read_conf import (
read_conf
,
read_conf
,
ip_conf
,
ip_conf
,
web
as
web_conf
,
web
as
web_conf
,
web_
ip
_conf
,
web_
path
_conf
,
listen_ports
,
listen_ports
,
allowed_ips
,
allowed_ips
,
get_conf
,
get_conf
,
...
@@ -347,7 +347,7 @@ def start_web_server():
...
@@ -347,7 +347,7 @@ def start_web_server():
host
=
'0.0.0.0'
host
=
'0.0.0.0'
with
Configurator
()
as
config
:
with
Configurator
()
as
config
:
config
.
include
(
'pyramid_tm'
)
config
.
include
(
'pyramid_tm'
)
for
ip
,
cfg
in
web_ip
_conf
.
items
():
for
path
,
cfg
in
web_path
_conf
.
items
():
cfg
[
'module_obj'
]
.
pyramid_init
(
config
)
cfg
[
'module_obj'
]
.
pyramid_init
(
config
)
config
.
scan
(
cfg
[
'module'
])
config
.
scan
(
cfg
[
'module'
])
config
.
scan
(
__name__
)
config
.
scan
(
__name__
)
...
...
iso8583_web/scripts/init_db_linkaja.py
View file @
a1c645b
...
@@ -10,5 +10,5 @@ def main(argv=sys.argv):
...
@@ -10,5 +10,5 @@ def main(argv=sys.argv):
conf
.
read
(
conf_file
)
conf
.
read
(
conf_file
)
cf
=
conf
[
'module_iso8583_web.scripts.views.linkaja'
]
cf
=
conf
[
'module_iso8583_web.scripts.views.linkaja'
]
engine
=
create_engine
(
cf
[
'db_url'
])
engine
=
create_engine
(
cf
[
'db_url'
])
engine
.
echo
t
=
True
engine
.
echo
=
True
Base
.
metadata
.
create_all
(
engine
)
Base
.
metadata
.
create_all
(
engine
)
iso8583_web/scripts/views/__init__.py
View file @
a1c645b
...
@@ -5,7 +5,7 @@ from time import (
...
@@ -5,7 +5,7 @@ from time import (
from
opensipkd.tcp.connection
import
join_ip_port
from
opensipkd.tcp.connection
import
join_ip_port
from
iso8583_web.read_conf
import
(
from
iso8583_web.read_conf
import
(
name_conf
,
name_conf
,
web_
ip
_conf
,
web_
path
_conf
,
)
)
from
iso8583_web.scripts.logger
import
(
from
iso8583_web.scripts.logger
import
(
log_web_info
,
log_web_info
,
...
@@ -122,13 +122,20 @@ class View(object):
...
@@ -122,13 +122,20 @@ class View(object):
return
found_conn
return
found_conn
def
get_web_conf
(
self
):
def
get_web_conf
(
self
):
return
web_
ip_conf
.
get
(
self
.
request
.
client_addr
)
return
web_
path_conf
.
get
(
self
.
request
.
path
)
def
get_iso_conf
(
self
):
def
get_iso_conf
(
self
):
web_conf
=
self
.
get_web_conf
()
web_conf
=
self
.
get_web_conf
()
name
=
web_conf
[
'host'
]
name
=
web_conf
[
'host'
]
return
name_conf
[
name
]
return
name_conf
[
name
]
def
validate
(
self
):
conf
=
self
.
get_web_conf
()
if
not
conf
[
'allowed_ip'
]:
return
if
self
.
request
.
client_addr
not
in
conf
[
'allowed_ip'
]:
raise
self
.
not_found_error
(
self
.
request
.
client_addr
)
def
not_found_error
(
self
,
hostname
):
def
not_found_error
(
self
,
hostname
):
msg
=
'Host {} tidak ditemukan di konfigurasi'
.
format
(
hostname
)
msg
=
'Host {} tidak ditemukan di konfigurasi'
.
format
(
hostname
)
return
Exception
(
msg
)
return
Exception
(
msg
)
...
...
iso8583_web/scripts/views/jsonrpc.py
View file @
a1c645b
...
@@ -12,6 +12,7 @@ from . import (
...
@@ -12,6 +12,7 @@ from . import (
)
)
ROUTE
=
'rpc'
conf
=
dict
()
conf
=
dict
()
...
@@ -50,20 +51,24 @@ class View(BaseView):
...
@@ -50,20 +51,24 @@ class View(BaseView):
def
log_send
(
self
,
p
):
def
log_send
(
self
,
p
):
BaseView
.
log_send
(
self
,
p
)
BaseView
.
log_send
(
self
,
p
)
@jsonrpc_method
(
endpoint
=
'rpc'
)
@jsonrpc_method
(
endpoint
=
ROUTE
)
def
echo
(
self
,
p
):
def
echo
(
self
,
p
):
self
.
validate
()
return
self
.
get_response
(
'echo'
,
'echo_request'
)
return
self
.
get_response
(
'echo'
,
'echo_request'
)
@jsonrpc_method
(
endpoint
=
'rpc'
)
@jsonrpc_method
(
endpoint
=
ROUTE
)
def
inquiry
(
self
,
p
):
def
inquiry
(
self
,
p
):
self
.
validate
()
return
self
.
get_response
(
'inquiry'
,
p
)
return
self
.
get_response
(
'inquiry'
,
p
)
@jsonrpc_method
(
endpoint
=
'rpc'
)
@jsonrpc_method
(
endpoint
=
ROUTE
)
def
payment
(
self
,
p
):
def
payment
(
self
,
p
):
self
.
validate
()
return
self
.
get_response
(
'payment'
,
p
)
return
self
.
get_response
(
'payment'
,
p
)
@jsonrpc_method
(
endpoint
=
'rpc'
)
@jsonrpc_method
(
endpoint
=
ROUTE
)
def
reversal
(
self
,
p
):
def
reversal
(
self
,
p
):
self
.
validate
()
return
self
.
get_response
(
'reversal'
,
p
)
return
self
.
get_response
(
'reversal'
,
p
)
...
@@ -75,4 +80,5 @@ def init(cfg):
...
@@ -75,4 +80,5 @@ def init(cfg):
# Dipanggil forwarder.py
# Dipanggil forwarder.py
def
pyramid_init
(
config
):
def
pyramid_init
(
config
):
config
.
include
(
'pyramid_rpc.jsonrpc'
)
config
.
include
(
'pyramid_rpc.jsonrpc'
)
config
.
add_jsonrpc_endpoint
(
'rpc'
,
conf
[
'route_path'
])
config
.
add_jsonrpc_endpoint
(
ROUTE
,
conf
[
'route_path'
])
log_web_info
(
'JSON-RPC route path {}'
.
format
(
conf
[
'route_path'
]))
iso8583_web/scripts/views/linkaja/__init__.py
View file @
a1c645b
...
@@ -11,6 +11,7 @@ from pyramid.view import (
...
@@ -11,6 +11,7 @@ from pyramid.view import (
view_config
,
view_config
,
notfound_view_config
,
notfound_view_config
,
)
)
from
pyramid.response
import
Response
from
deform
import
(
from
deform
import
(
Form
,
Form
,
Button
,
Button
,
...
@@ -23,6 +24,11 @@ from opensipkd.string import (
...
@@ -23,6 +24,11 @@ from opensipkd.string import (
)
)
from
opensipkd.iso8583.bjb.pbb.structure
import
INVOICE_PROFILE
from
opensipkd.iso8583.bjb.pbb.structure
import
INVOICE_PROFILE
from
iso8583_web.scripts.tools
import
iso_to_dict
from
iso8583_web.scripts.tools
import
iso_to_dict
from
iso8583_web.read_conf
import
web_path_conf
from
iso8583_web.scripts.logger
import
(
log_web_info
,
log_web_error
,
)
from
..
import
(
from
..
import
(
WebJob
as
BaseWebJob
,
WebJob
as
BaseWebJob
,
View
as
BaseView
,
View
as
BaseView
,
...
@@ -38,6 +44,7 @@ from .exceptions import (
...
@@ -38,6 +44,7 @@ from .exceptions import (
BaseError
,
BaseError
,
AmountError
,
AmountError
,
BillRefNotFound
,
BillRefNotFound
,
PaymentNotFound
,
)
)
from
.structure
import
(
from
.structure
import
(
DataRequest
,
DataRequest
,
...
@@ -51,7 +58,7 @@ from .models import (
...
@@ -51,7 +58,7 @@ from .models import (
)
)
ROUTE
=
'
rpc
'
ROUTE
=
'
linkaja
'
RENDERER
=
'csv'
RENDERER
=
'csv'
METHOD
=
{
METHOD
=
{
'021'
:
'inquiry'
,
'021'
:
'inquiry'
,
...
@@ -104,7 +111,7 @@ def get_payment(data):
...
@@ -104,7 +111,7 @@ def get_payment(data):
DBSession
=
get_db_session
()
DBSession
=
get_db_session
()
bill_ref
=
int
(
data
[
'bill_ref'
])
bill_ref
=
int
(
data
[
'bill_ref'
])
q
=
DBSession
.
query
(
Rpc
)
.
filter_by
(
q
=
DBSession
.
query
(
Rpc
)
.
filter_by
(
inquiry_id
=
bill_ref
,
trx_type
=
data
[
'trx_type'
]
)
inquiry_id
=
bill_ref
,
trx_type
=
'022'
)
q
=
q
.
order_by
(
Rpc
.
id
.
desc
())
q
=
q
.
order_by
(
Rpc
.
id
.
desc
())
return
q
.
first
()
return
q
.
first
()
...
@@ -149,7 +156,6 @@ class csv_method(object):
...
@@ -149,7 +156,6 @@ class csv_method(object):
kw
.
setdefault
(
'attr'
,
wrapped
.
__name__
)
kw
.
setdefault
(
'attr'
,
wrapped
.
__name__
)
kw
[
'_info'
]
=
info
.
codeinfo
# fbo action_method
kw
[
'_info'
]
=
info
.
codeinfo
# fbo action_method
print
(
'DEBUG wrapped {}'
.
format
(
wrapped
))
return
wrapped
return
wrapped
...
@@ -237,6 +243,9 @@ class View(BaseView):
...
@@ -237,6 +243,9 @@ class View(BaseView):
elif
iso_data
[
39
]
in
[
'33'
,
'55'
]:
elif
iso_data
[
39
]
in
[
'33'
,
'55'
]:
err
=
InvoiceIdError
()
err
=
InvoiceIdError
()
elif
iso_data
[
39
]
==
'54'
:
elif
iso_data
[
39
]
==
'54'
:
if
is_reversal
(
data
):
err
=
PaymentNotFound
()
else
:
err
=
AlreadyPaidError
()
err
=
AlreadyPaidError
()
elif
iso_data
[
39
]
==
'51'
:
elif
iso_data
[
39
]
==
'51'
:
err
=
AmountError
()
err
=
AmountError
()
...
@@ -278,6 +287,7 @@ class View(BaseView):
...
@@ -278,6 +287,7 @@ class View(BaseView):
@csv_method
(
route_name
=
ROUTE
)
@csv_method
(
route_name
=
ROUTE
)
def
view_trx
(
self
):
def
view_trx
(
self
):
self
.
validate
()
if
not
self
.
request
.
POST
:
if
not
self
.
request
.
POST
:
self
.
log_receive
(
'GET {}'
.
format
(
self
.
request
.
GET
))
self
.
log_receive
(
'GET {}'
.
format
(
self
.
request
.
GET
))
raise
NeedPostError
()
raise
NeedPostError
()
...
@@ -294,6 +304,7 @@ class View(BaseView):
...
@@ -294,6 +304,7 @@ class View(BaseView):
break
break
raise
InternalError
(
msg
)
raise
InternalError
(
msg
)
data
=
dict
(
c
)
data
=
dict
(
c
)
return
self
.
get_response
(
data
)
try
:
try
:
r
=
self
.
get_response
(
data
)
r
=
self
.
get_response
(
data
)
self
.
log_send
(
r
)
self
.
log_send
(
r
)
...
@@ -310,6 +321,27 @@ class View(BaseView):
...
@@ -310,6 +321,27 @@ class View(BaseView):
self
.
log_receive
(
msg
,
True
)
self
.
log_receive
(
msg
,
True
)
return
self
.
request
.
exception
return
self
.
request
.
exception
def
log_prefix
(
request
):
web_conf
=
web_path_conf
.
get
(
request
.
path
)
name
=
web_conf
[
'name'
]
return
'{} {} {}'
.
format
(
request
.
client_addr
,
name
,
id
(
request
))
@view_config
(
context
=
BaseError
)
def
view_exception
(
exc
,
request
):
r
=
InquiryResponse
()
r
[
'Response Code'
]
=
exc
.
code
r
[
'Notification Message'
]
=
exc
.
message
prefix
=
log_prefix
(
request
)
msg
=
'{} {} {}'
.
format
(
prefix
,
'Send'
,
r
)
log_web_error
(
msg
)
response
=
Response
(
str
(
r
))
response
.
status_int
=
200
return
response
# Dipanggil read_conf.py
# Dipanggil read_conf.py
def
init
(
cfg
):
def
init
(
cfg
):
conf
.
update
(
cfg
)
conf
.
update
(
cfg
)
...
@@ -319,6 +351,7 @@ def init(cfg):
...
@@ -319,6 +351,7 @@ def init(cfg):
def
pyramid_init
(
config
):
def
pyramid_init
(
config
):
config
.
add_renderer
(
RENDERER
,
'iso8583_web.scripts.views.linkaja.Renderer'
)
config
.
add_renderer
(
RENDERER
,
'iso8583_web.scripts.views.linkaja.Renderer'
)
config
.
add_route
(
ROUTE
,
conf
[
'route_path'
])
config
.
add_route
(
ROUTE
,
conf
[
'route_path'
])
log_web_info
(
'LinkAja route path {}'
.
format
(
conf
[
'route_path'
]))
pool_size
=
int
(
conf
.
get
(
'db_pool_size'
,
50
))
pool_size
=
int
(
conf
.
get
(
'db_pool_size'
,
50
))
max_overflow
=
int
(
conf
.
get
(
'db_max_overflow'
,
100
))
max_overflow
=
int
(
conf
.
get
(
'db_max_overflow'
,
100
))
engine
=
create_engine
(
engine
=
create_engine
(
...
...
iso8583_web/scripts/views/linkaja/exceptions.py
View file @
a1c645b
...
@@ -50,3 +50,8 @@ class AmountError(BaseError):
...
@@ -50,3 +50,8 @@ class AmountError(BaseError):
class
BillRefNotFound
(
BaseError
):
class
BillRefNotFound
(
BaseError
):
code
=
'47'
code
=
'47'
message
=
'bill_ref tidak ditemukan'
message
=
'bill_ref tidak ditemukan'
class
PaymentNotFound
(
BaseError
):
code
=
'48'
message
=
'Belum ada pembayaran'
iso8583_web/scripts/views/linkaja/structure.py
View file @
a1c645b
...
@@ -44,6 +44,9 @@ class InquiryResponse(Row):
...
@@ -44,6 +44,9 @@ class InquiryResponse(Row):
Row
.
__setitem__
(
self
,
name
,
value
)
Row
.
__setitem__
(
self
,
name
,
value
)
def
__str__
(
self
):
def
__str__
(
self
):
return
self
.
to_str
()
def
to_str
(
self
):
return
':'
.
join
(
list
(
self
))
return
':'
.
join
(
list
(
self
))
def
from_err
(
self
,
err
):
def
from_err
(
self
,
err
):
...
...
iso8583_web/scripts/web_client.py
View file @
a1c645b
...
@@ -68,13 +68,23 @@ def send(p):
...
@@ -68,13 +68,23 @@ def send(p):
try
:
try
:
resp
=
requests
.
post
(
url
,
data
=
json
.
dumps
(
p
),
headers
=
headers
)
resp
=
requests
.
post
(
url
,
data
=
json
.
dumps
(
p
),
headers
=
headers
)
durations
[
key
]
=
time
()
-
start
durations
[
key
]
=
time
()
-
start
if
resp
.
status_code
==
200
:
json_resp
=
resp
.
json
()
json_resp
=
resp
.
json
()
log_info
(
'Response: {}'
.
format
(
json_resp
))
log_info
(
'Response: {}'
.
format
(
json_resp
))
json_responses
[
key
]
=
json_resp
json_responses
[
key
]
=
json_resp
else
:
log_info
(
'Status Code: {}'
.
format
(
resp
.
status_code
))
log_info
(
'Body: {}'
.
format
([
resp
.
text
]))
json_responses
[
key
]
=
dict
(
fatal
=
resp
.
text
)
except
requests
.
exceptions
.
ConnectionError
as
e
:
except
requests
.
exceptions
.
ConnectionError
as
e
:
durations
[
key
]
=
time
()
-
start
durations
[
key
]
=
time
()
-
start
log_info
(
'Response: {}'
.
format
(
e
))
log_info
(
'Response: {}'
.
format
(
e
))
json_responses
[
key
]
=
dict
(
fatal
=
e
)
json_responses
[
key
]
=
dict
(
fatal
=
e
)
except
json
.
decoder
.
JSONDecodeError
as
e
:
durations
[
key
]
=
time
()
-
start
log_info
(
'Body: {}'
.
format
([
resp
.
text
]))
log_info
(
'Response: {}'
.
format
(
e
))
json_responses
[
key
]
=
dict
(
fatal
=
e
)
finally
:
finally
:
end_threads
.
append
(
key
)
end_threads
.
append
(
key
)
...
@@ -130,7 +140,7 @@ def show_durations():
...
@@ -130,7 +140,7 @@ def show_durations():
key_slowest
=
key
key_slowest
=
key
total_duration
+=
duration
total_duration
+=
duration
log_info
(
msg
)
log_info
(
msg
)
if
key_fastest
:
if
key_fastest
!=
key_slowest
:
log_info
(
'Tercepat {}'
.
format
(
messages
[
key_fastest
]))
log_info
(
'Tercepat {}'
.
format
(
messages
[
key_fastest
]))
log_info
(
'Terlama {}'
.
format
(
messages
[
key_slowest
]))
log_info
(
'Terlama {}'
.
format
(
messages
[
key_slowest
]))
log_info
(
'Rerata {} detik / request'
.
format
(
total_duration
/
len
(
durations
)))
log_info
(
'Rerata {} detik / request'
.
format
(
total_duration
/
len
(
durations
)))
...
...
iso8583_web/scripts/web_client_linkaja.py
View file @
a1c645b
...
@@ -146,7 +146,7 @@ def show_durations():
...
@@ -146,7 +146,7 @@ def show_durations():
else
:
else
:
errors
[
err
]
=
1
errors
[
err
]
=
1
log_info
(
'thread {} {} detik {}'
.
format
(
tid
,
duration
,
msg
))
log_info
(
'thread {} {} detik {}'
.
format
(
tid
,
duration
,
msg
))
if
tid_fastest
:
if
tid_fastest
!=
tid_slowest
:
log_info
(
'Tercepat {}'
.
format
(
messages
[
tid_fastest
]))
log_info
(
'Tercepat {}'
.
format
(
messages
[
tid_fastest
]))
log_info
(
'Terlama {}'
.
format
(
messages
[
tid_slowest
]))
log_info
(
'Terlama {}'
.
format
(
messages
[
tid_slowest
]))
log_info
(
'Rerata {} detik / request'
.
format
(
total_duration
/
len
(
durations
)))
log_info
(
'Rerata {} detik / request'
.
format
(
total_duration
/
len
(
durations
)))
...
...
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment