Commit 2810ef06 by Owo Sugiana

Kali pertama

0 parents
0.1.0 13-9-2020
---------------
- Kali pertama, berasal dari paket iso8583-web agar lebih modular.
Modul LinkAja untuk Pyramid
===========================
Ini merupakan modul Pyramid untuk menerjemahkan data host to host LinkAja.
Untuk penggunaannya lihat paket
`iso8583-web <https://git.opensipkd.com/sugiana/iso8583-web>`_.
# view decorator
class csv_method:
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 BaseError(Exception):
code = '49'
message = 'Ada kesalahan yang belum dipahami'
class NeedPostError(BaseError):
code = '40'
message = 'HTTP Request harus POST'
class TrxTypeError(BaseError):
code = '41'
message = 'trx_type tidak dikenal'
class InternalError(BaseError):
def __init__(self, orig_msg, msg='Ada kesalahan internal'):
self.orig_msg = orig_msg
self.message = msg
class TimeoutError(BaseError):
code = '42'
message = 'Timeout'
class InvoiceIdError(BaseError):
code = '43'
message = 'acc_no tidak ditemukan'
class HostError(BaseError):
code = '44'
def __init__(self, hostname):
self.hostname = hostname
self.message = 'Host {} tidak terdaftar'.format(hostname)
class AlreadyPaidError(BaseError):
code = '45'
message = 'Memang sudah lunas'
class AmountError(BaseError):
code = '46'
message = 'Jumlah pembayaran tidak sesuai tagihan'
class BillRefNotFound(BaseError):
code = '47'
message = 'bill_ref tidak ditemukan'
class PaymentNotFound(BaseError):
code = '48'
message = 'Belum ada pembayaran'
class LinkError(BaseError):
code = '49'
message = 'Koneksi terputus'
import colander
from deform import Form
from .structure import METHOD
class DataRequest(colander.Schema):
merchant = colander.SchemaNode(colander.String())
terminal = colander.SchemaNode(colander.String())
pwd = colander.SchemaNode(colander.String())
trx_type = colander.SchemaNode(colander.String())
msisdn = colander.SchemaNode(colander.String())
acc_no = colander.SchemaNode(colander.String())
msg = colander.SchemaNode(colander.String(), missing=colander.drop)
trx_date = colander.SchemaNode(colander.String())
amount = colander.SchemaNode(colander.String(), missing=colander.drop)
# Saat payment dan reversal, diperoleh dari inquiry response
bill_ref = colander.SchemaNode(colander.String(), missing=colander.drop)
# Saat payment dan reversal, dibuat saat payment request (NTB)
trx_id = colander.SchemaNode(colander.String(), missing=colander.drop)
def form_validator(form, value):
if value['trx_type'] not in METHOD:
raise TrxTypeError()
def get_form():
schema = DataRequest(validator=form_validator)
return Form(schema)
class Renderer:
def __init__(self, info):
pass
def __call__(self, value, system):
''' value bertipe InquiryResponse '''
request = system.get('request')
if request is not None:
response = request.response
ct = response.content_type
if ct == response.default_content_type:
response.content_type = 'text/csv'
return str(value)
from opensipkd.string import (
FixLength,
FullDateTimeVar,
)
from opensipkd.string.row import Row
from .structure import (
INQUIRY_RESP_FIELDS,
PAYMENT_RESP_FIELDS,
METHOD,
METHOD_CODE,
)
from .exceptions import InternalError
class InquiryResponse(Row):
def __init__(self):
super().__init__(INQUIRY_RESP_FIELDS)
def __setitem__(self, name, value):
if value.find(':') > -1:
msg = f'Ada titik dua pada {name} yaitu {value}'
raise InternalError(msg)
Row.__setitem__(self, name, value)
def __str__(self):
return self.to_str()
def to_str(self):
return ':'.join(list(self))
def from_err(self, err):
self.values['Response Code'] = err.code
self.values['Notification Message'] = err.message
def from_raw(self, raw):
t = raw.split(':')
i = -1
for fieldname in self.fieldnames:
i += 1
if not t[i:i+1]:
return
self.values[fieldname] = t[i]
class PaymentResponse(InquiryResponse):
def __init__(self):
Row.__init__(self, PAYMENT_RESP_FIELDS)
def get_method(data):
return METHOD[data['trx_type']]
def is_inquiry(data):
return data['trx_type'] == METHOD_CODE['inquiry']
def is_payment(data):
return data['trx_type'] == METHOD_CODE['payment']
def is_reversal(data):
return data['trx_type'] == METHOD_CODE['reversal']
def get_template_response(data):
if is_inquiry(data):
return InquiryResponse()
d = PaymentResponse()
d['Bill Ref'] = data['bill_ref']
return d
def date_from_str(s):
t = FullDateTimeVar()
t.set_raw(s)
return t.get_value()
def get_trx_date(data):
return date_from_str(data['trx_date'])
INQUIRY_RESP_FIELDS = (
'Response Code',
'Biller Name',
'Bill Amount',
'Bill Ref', # STAN
'Notification Message')
PAYMENT_RESP_FIELDS = (
'Response Code',
'Transaction ID', # NTP
'Bill Ref', # STAN
'Notification Message')
METHOD = {
'021': 'inquiry',
'022': 'payment',
'023': 'reversal'}
METHOD_CODE = dict()
for key, value in METHOD.items():
METHOD_CODE[value] = key
import os
import sys
import subprocess
from setuptools import (
setup,
find_packages,
)
here = os.path.abspath(os.path.dirname(__file__))
with open(os.path.join(here, 'README.rst')) as f:
README = f.read()
with open(os.path.join(here, 'CHANGES.txt')) as f:
CHANGES = f.read()
line = CHANGES.splitlines()[0]
version = line.split()[0]
requires = [
'colander',
'venusian',
'opensipkd-hitung @ git+https://git.opensipkd.com/sugiana/opensipkd-hitung.git',
]
setup(
name='pyramid-linkaja',
version=version,
description='Modul Pyramid untuk menerjemahkan data host to host LinkAja,'\
' produk PT Telkom',
long_description=README + '\n\n' + CHANGES,
classifiers=[
'Programming Language :: Python :: 3.6',
'Framework :: Pyramid',
'Topic :: Internet :: WWW/HTTP',
'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
],
author='Owo Sugiana',
author_email='sugiana@gmail.com',
url='https://git.opensipkd.com/sugiana/pyramid-linkaja',
keywords='web pyramid pylons',
packages=find_packages(),
include_package_data=True,
zip_safe=False,
install_requires=requires,
)
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!