Commit 1006f7c4 by solo

a

2 parents 783c7b91 35442adc
Generic single-database configuration.
\ No newline at end of file \ No newline at end of file
from __future__ import with_statement
from logging.config import fileConfig
from sqlalchemy import engine_from_config
from sqlalchemy import pool
from alembic import context
# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config
# Interpret the config file for Python logging.
# This line sets up loggers basically.
fileConfig(config.config_file_name)
# add your model's MetaData object here
# for 'autogenerate' support
# from myapp import mymodel
# target_metadata = mymodel.Base.metadata
target_metadata = None
# other values from the config, defined by the needs of env.py,
# can be acquired:
# my_important_option = config.get_main_option("my_important_option")
# ... etc.
def run_migrations_offline():
"""Run migrations in 'offline' mode.
This configures the context with just a URL
and not an Engine, though an Engine is acceptable
here as well. By skipping the Engine creation
we don't even need a DBAPI to be available.
Calls to context.execute() here emit the given string to the
script output.
"""
url = config.get_main_option("sqlalchemy.url")
context.configure(
url=url, target_metadata=target_metadata, literal_binds=True
)
with context.begin_transaction():
context.run_migrations()
def run_migrations_online():
"""Run migrations in 'online' mode.
In this scenario we need to create an Engine
and associate a connection with the context.
"""
connectable = engine_from_config(
config.get_section(config.config_ini_section),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)
with connectable.connect() as connection:
context.configure(
connection=connection, target_metadata=target_metadata
)
with context.begin_transaction():
context.run_migrations()
if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()
"""${message}
Revision ID: ${up_revision}
Revises: ${down_revision | comma,n}
Create Date: ${create_date}
"""
from alembic import op
import sqlalchemy as sa
${imports if imports else ""}
# revision identifiers, used by Alembic.
revision = ${repr(up_revision)}
down_revision = ${repr(down_revision)}
branch_labels = ${repr(branch_labels)}
depends_on = ${repr(depends_on)}
def upgrade():
${upgrades if upgrades else "pass"}
def downgrade():
${downgrades if downgrades else "pass"}
...@@ -64,4 +64,9 @@ api-partner-act,/api/partner/{act}/act,Api Act partner,1,0 ...@@ -64,4 +64,9 @@ api-partner-act,/api/partner/{act}/act,Api Act partner,1,0
api-partner-view,/api/partner/{id}/view,Api View partner,1,0 api-partner-view,/api/partner/{id}/view,Api View partner,1,0
api-partner-add,/api/partner/add,Api Add partner,1,0 api-partner-add,/api/partner/add,Api Add partner,1,0
api-partner-edit,/api/partner/{id}/edit,Api Edit partner,1,0 api-partner-edit,/api/partner/{id}/edit,Api Edit partner,1,0
api-partner-delete,/api/partner/{id}/delete,Api Delete partner,1,0
\ No newline at end of file \ No newline at end of file
api-partner-delete,/api/partner/{id}/delete,Api Delete partner,1,0
odeo-purchase,/api/odeo/prepaid/purchase,'API TEST ODEO PURCHASE,1,0
odeo-prepaid-inquiry-pln,/api/odeo/prepaid/pln/inquiry,'API TEST ODEO PLN PRE INQUIRY,1,0
odeo-postpaid-inquiry,/api/odeo/postpaid/inquiry,'API TEST ODEO INQUIRY POSTPAUD,1,0
api-vsi,/api/vsi,'API VSI,1,0
\ No newline at end of file \ No newline at end of file
# from datetime import datetime
#
# import colander
# from agratek.api.merchant.views.api_merchant import get_vendor_produk
# from datatables import ColumnDT
# from deform import widget, Form, ValidationFailure
# from opensipkd.base.views import DataTables
# from pyramid.httpexceptions import HTTPFound
# from pyramid.view import view_config
#
# from . import BaseView # , save_file_upload
# from ..models import (DBSession, flush_row, Satuan)
# # from ..models import (H2hArInvoice, H2hArInvoiceDet)
# from ..models import (Produk, Partner, PartnerLog, PartnerProduk, H2hArInvoice, H2hArInvoiceDet)
# from ..tools import (btn_reset,
# btn_cancel, btn_delete, btn_save, auth_from_rpc, get_settings, os)
# from opensipkd.pasar.models.views import (deferred_produk, deferred_vendor,
# deferred_customer)
#
# class Payment(colander.Schema):
# """
# timeStamp Y N 14 API Request Date
# tXid Y AN 30 Transaction ID
# callBackUrl Y AN 255 Payment result forward url (on browser) direplace oleh systen
# merchantToken Y AN 255 merchantToken (dibuat oleh system)
# """
#
# time_stamp = colander.SchemaNode(
# colander.String(),
# oid="time_stamp",
# )
#
# tx_id = colander.SchemaNode(
# colander.String(), title='Customer',
# oid="tx_id",
# widget=widget.PasswordWidget(min_length=30, max_length=30)
# )
#
# callback_url = colander.SchemaNode(
# colander.String(), title='Callback URL',
# oid="callback_url",
# widget=widget.TextInputWidget()
# )
#
# class CcPay(Payment):
# """
# cardNo Y N 20 Full card number
# cardExpYymm Y N 4 card expiry(YYMM)
# cardCvv Y N 4 card CVV
# cardHolderNm Y (CIMB) AN 50 Card Holder Name
# :return:
# """
# card_name = colander.SchemaNode(
# colander.String(), title='Card Expired',
# oid="card_no",
# widget=widget.TextInputWidget(min_length=30, max_length=30)
# )
# card_no = colander.SchemaNode(
# colander.String(), title='Card Number',
# oid="card_no",
# widget=widget.TextInputWidget(min_length=16, max_length=16)
# )
# card_exp = colander.SchemaNode(
# colander.String(), title='Card Expired',
# oid="card_no",
# widget=widget.TextInputWidget(min_length=4, max_length=4)
# )
# card_cvv = colander.SchemaNode(
# colander.String(), title='Card Expired',
# oid="card_no",
# widget=widget.PasswordWidget(min_length=3, max_length=3)
# )
#
# class ClickPay(Payment):
# """
# clickPayNo Y N 16 ClickPay number
# dataField3 Y N 16 Token input 3 for clickpay
# clickPayToken Y N 6 Code response from token
# :return:
# """
# pay_no = colander.SchemaNode(
# colander.String(), title='Click Pay No',
# oid="pay_no",
# widget=widget.TextInputWidget(min_length=16, max_length=16)
# )
#
# data_field_3 = colander.SchemaNode(
# colander.String(), title='Click Pay No',
# oid="data_field_3",
# widget=widget.TextInputWidget(min_length=16, max_length=16)
# )
# token = colander.SchemaNode(
# colander.String(), title='Click Pay No',
# oid="token",
# widget=widget.TextInputWidget(min_length=6, max_length=6)
# )
#
# class AddSchema(Payment):
# customer_id = colander.SchemaNode(
# colander.Integer(), title='Customer',
# oid="customer_id", widget=deferred_customer)
#
# produk_id = colander.SchemaNode(
# colander.Integer(), title='Produk',
# oid="produk_id", widget=deferred_produk)
#
#
# def WalletPay(Payment):
# pass
#
#
#
# def payment_validator(form, values):
# pass
#
# def get_form(request, class_form, buttons=None, row=None, validator=payment_validator):
# schema = class_form(validator=validator)
# schema = schema.bind(vendor=Partner.get_vendor_list(),
# produk=Produk.get_e_list(),
# customer=Partner.get_customer_list())
# schema.request = request
# if row:
# schema.deserialize(row)
# if not buttons:
# buttons = (btn_save, btn_reset)
# return Form(schema, buttons=buttons)
#
#
# def route_list(request):
# return HTTPFound(location=request.route_url('api-customer-list'))
#
#
# def save(values, row):
# # if not row:
# # row = H2hArInvoice()
# # row.create_uid = values['uid']
# # row.created = datetime.now()
# # else:
# # row.update_uid = values['uid']
# # row.updated = datetime.now()
#
# row.from_dict(values)
# flush_row(row)
# return row
#
#
# # def save_request(request, values, values_det, row=None):
# # if not row:
# # row = H2hArInvoice()
# # values['uid'] = request.user.id
# # values['status'] = 'status' in values and values['status'] and 1 or 0
# # else:
# # values['update_uid'] = request.user.id
# # values['updated'] = datetime.now()
# # DBSession.query(H2hArInvoiceDet).filter(H2hArInvoiceDet.ar_invoice_id == row.id).delete()
# #
# # row = save(values, row)
# #
# # row_det = H2hArInvoiceDet()
# # row_det.id_pel = values['id_pel']
# # row_det.ar_invoice_id = row.id
# # row_det = save(values_det, row_det)
# # request.session.flash('Data %s Berhasil disimpan' % values['kode'])
# # # return row
# #
# #
# # form_params_edit = dict(scripts="""
# # $(document).ready(function(){
# # });
# # """)
# #
# # form_params_view = dict(scripts="""
# # $(document).ready(function(){
# # });
# # """)
# #
# # def session_failed(request, session_name):
# # r = dict(form=request.session[session_name])
# # del request.session[session_name]
# # return r
# #
# # def id_not_found(request):
# # id = request.matchdict['id']
# # request.session.flash('Data %s Tidak Ditemukan' % id, 'error')
# # return route_list(request)
# #
# #
# # def query_id(request):
# # id = request.matchdict['id']
# # return H2hArInvoice.query_id(id)
# #
# #
#
#
# class ViewData(BaseView):
# @view_config(route_name='api-merchant-payment',
# # permission="api-customer-admin",
# renderer='templates/form.pt')
# def view_payment(self):
# request = self.req
# # form = get_form(request, AddSchema)
# # form_params = dict(scripts=None)
# form = get_form(request, Payment)
# settings = get_settings()
# if request.POST:
# controls = request.POST.items()
# try:
# c = form.validate(controls)
# except ValidationFailure as e:
# form.set_appstruct(e.cstruct)
# return
# # dict(form=form, params=form_params_edit)
#
# values = dict(c.items())
# registrasi = PartnerPay.query_tx_id(values["tx_id"]).first()
# if not registrasi:
# request.session.flash("Registrasi Payment Tidak Ditemukan", "error")
# return
#
# vendor_produk = PartnerProduk.get_produk(registrasi.vendor_id, registrasi.produk_id).first()
# if not vendor_produk:
# request.session.flash("Produk Tidak Ditemukan", "error")
# return
# url = os.path.join(settings["np_url"], "payment")
# return HTTPFound(location=url, par)
#
# return dict(form=form, params=form_params_edit)
#
...@@ -98,7 +98,7 @@ def callback_merchant(order): ...@@ -98,7 +98,7 @@ def callback_merchant(order):
url = customer.website url = customer.website
users = customer.users users = customer.users
status = order.status == 1 and "SUCCESS" \ status = order.status == 1 and "SUCCESS" \
or order.status > -2 and "FAILED" \ or order.status < -2 and "FAILED" \
or "PENDING" or "PENDING"
key = invoice.cust_inv_no + users.user_name + users.api_key + status key = invoice.cust_inv_no + users.user_name + users.api_key + status
signature = sha256(key) signature = sha256(key)
...@@ -123,8 +123,7 @@ def callback_merchant(order): ...@@ -123,8 +123,7 @@ def callback_merchant(order):
js = get_jsonrpc(method="notify", params=dict(data=data)) js = get_jsonrpc(method="notify", params=dict(data=data))
log.info("Notify: %s %s" %(url, js)) log.info("Notify: %s %s" %(url, js))
try: try:
with requests.session(): requests.post(url, data=js, timeout=10)
requests.post(url, data=data, timeout=10)
except: except:
pass pass
......
import base64 import base64
import json import json
import re
from time import sleep from time import sleep
import requests import requests
...@@ -33,22 +34,7 @@ class Vendor(VendorClass): ...@@ -33,22 +34,7 @@ class Vendor(VendorClass):
def get_url(self, url=None): def get_url(self, url=None):
return url and self.url + url or self.url return url and self.url + url or self.url
# def request_post(self, data, url=None): def _inquiry(self):
# # data = json.dumps(params)
# url = url and self.url + url or self.url
# return requests.post(url, data=data, verify=False,
# headers=self.get_headers(), timeout=15)
# # try:
# # pass
# except requests.exceptions.RequestException as e:
# resp = None
#
# return resp
def inquiry(self):
if not self.v_produk_kd or not self.id_pel:
return self.set_response(message='Parameter tidak lengkap')
if self.v_produk_kd[:3] == 'PLN' and self.v_produk_kd != 'PLNPASCA': if self.v_produk_kd[:3] == 'PLN' and self.v_produk_kd != 'PLNPASCA':
params = dict( params = dict(
number=self.id_pel number=self.id_pel
...@@ -68,54 +54,42 @@ class Vendor(VendorClass): ...@@ -68,54 +54,42 @@ class Vendor(VendorClass):
resp = requests.get(url, params=params, verify=False, resp = requests.get(url, params=params, verify=False,
headers=self.get_headers(), timeout=timeout) headers=self.get_headers(), timeout=timeout)
except: except:
return self.set_response(message="Biller Not Response") return
if not resp: if not resp:
return self.set_response(message="Biller No Response") return
try: try:
result = json.loads(resp.text) result = json.loads(resp.text)
except: except:
result = resp.text result = resp.text
self.response = result
self.response = result
log.info("Inquiry Response: %s" % self.response) log.info("Inquiry Response: %s" % self.response)
if resp.status_code == 200: if resp.status_code == 200:
self.status = 1 # sukses self.status = 1 # sukses
data = "data" in result and result["data"] or None data = "data" in result and result["data"] or None
parsd = self.pars_data(data) return self.pars_data(data)
if parsd:
parsd.update(code=0,
message="SUCCES",
status="SUCCESS")
elif resp.status_code == 400:
self.status = -1
message = "data" in result and result["data"] or {}
message = message and "errors" in message and message["errors"] or message
message = type(message) is list and ", ".join(message) or message
parsd = dict(code=resp.status_code,
message=message)
else: else:
self.status = -1 return
parsd = None
return self.set_response(parsd) # parsd
def inquiry(self):
# def gagal_transaksi(self, inq): if not self.v_produk_kd or not self.id_pel:
# self.status = -2 # Try Other Vendor return self.set_response(message='Parameter tidak lengkap')
# if inq: parsd = self._inquiry()
# inq.update(dict(code=68, if not parsd:
# message="PENDING", return self.set_failed() # parsd
# status="PENDING")) return self.set_success(parsd) # parsd
# return self.set_response(data=inq, typ="payment")
# else:
# parsd = self.get_price()
# parsd.update(dict(code=68,
# message="PENDING",
# status="PENDING"))
# return self.set_response(data=parsd, typ="payment")
def payment(self): def payment(self):
#Jika kategory bukan e-pulsa Call Inquiry First
parsd = None
if self.vendor_produk.produk.kategori.kode != "e-pulsa":
parsd = self._inquiry()
if not parsd:
return self.set_failed()
params = dict( params = dict(
data=dict( data=dict(
denom=self.v_produk_kd, denom=self.v_produk_kd,
...@@ -125,14 +99,6 @@ class Vendor(VendorClass): ...@@ -125,14 +99,6 @@ class Vendor(VendorClass):
self.request = params self.request = params
log.info("Payment Request: %s" % self.request) log.info("Payment Request: %s" % self.request)
self.save_log("payment") self.save_log("payment")
parsd = None
if self.vendor_produk.produk.kategori.kode in ["e-payment", "e-voucher"]:
parsd = self.inquiry()
if parsd["code"] != 0:
self.status = -3
return self.set_response(typ="payment",
message="Data Tagihan Tidah ditemukan")
if not parsd: if not parsd:
parsd = self.get_price() parsd = self.get_price()
...@@ -144,8 +110,7 @@ class Vendor(VendorClass): ...@@ -144,8 +110,7 @@ class Vendor(VendorClass):
resp = None resp = None
if resp is None: if resp is None:
self.status = 0 return self.set_pending(parsd, typ="payment")
return self.set_pending(parsd)
# todo: dibuat seolah menjadi belum di transaksikan # todo: dibuat seolah menjadi belum di transaksikan
# todo: membuat cron untuk melakukan pengecekan transaksi # todo: membuat cron untuk melakukan pengecekan transaksi
try: try:
...@@ -156,8 +121,7 @@ class Vendor(VendorClass): ...@@ -156,8 +121,7 @@ class Vendor(VendorClass):
result = resp.text result = resp.text
self.response = result self.response = result
log.info("Payment Response: %s" % self.response) log.info("Payment Response: %s" % self.response)
self.status = 0 return self.set_pending(parsd, typ="payment")
return self.set_pending(parsd)
# odeo mengembalikan result dalam bentuk status # odeo mengembalikan result dalam bentuk status
# 0200 ok # 0200 ok
...@@ -167,30 +131,22 @@ class Vendor(VendorClass): ...@@ -167,30 +131,22 @@ class Vendor(VendorClass):
data = "data" in result and result["data"] or {} data = "data" in result and result["data"] or {}
if not data: if not data:
self.status = 0 self.status = 0
return self.set_pending(parsd) return self.set_pending(parsd, typ="payment")
self.vend_inv_no = "order_id" in data and data["order_id"] or self.vend_inv_no self.vend_inv_no = "order_id" in data and data["order_id"] or self.vend_inv_no
self.amt_buy = "price" in data and data["price"] or self.amt_buy self.amt_buy = "price" in data and data["price"] or self.amt_buy
if "rc" in data: if "rc" in data:
if data["rc"] == "13": if data["rc"] == "13": # Gagal
return self.set_failed(parsd) return self.set_failed(parsd, typ="payment")
elif data["rc"] == "67": elif data["rc"] == "67": # Gagal Double
return self.set_double(parsd) return self.set_failed(parsd, typ="payment")
elif data["rc"] == "68": # Pending
elif data["rc"] == "68": return self.set_pending(parsd, typ="payment")
self.status = -1 # pending
return self.set_pending(parsd)
else: else:
self.serial_number = 'serial_number' in data and data["serial_numner"] \ self.serial_number = 'serial_number' in data and data["serial_numner"] \
or self.serial_number or self.serial_number
return self.set_success(parsd) return self.set_success(parsd, typ="payment")
elif resp.status_code == 400: elif resp.status_code == 400:
self.status = -3
data = "data" in result and result["data"] or None data = "data" in result and result["data"] or None
message = "" message = ""
if data and "errors" in data: if data and "errors" in data:
...@@ -204,12 +160,9 @@ class Vendor(VendorClass): ...@@ -204,12 +160,9 @@ class Vendor(VendorClass):
sn_spl = message[pos:].split(" ") sn_spl = message[pos:].split(" ")
sn = len(sn_spl) > 1 and sn_spl[1] or "" sn = len(sn_spl) > 1 and sn_spl[1] or ""
parsd["serial_number"] = sn parsd["serial_number"] = sn
return self.set_failed(parsd, message=message) return self.set_failed(parsd, message=message, typ="payment")
elif resp.status_code == 401: elif resp.status_code == 401:
self.status = -2 return self.set_failed(parsd, typ="payment")
# todo: create cron yang status -2
return self.set_pending(parsd)
def advice(self): def advice(self):
if not self.v_produk_kd or not self.id_pel or not self.invoice_det: if not self.v_produk_kd or not self.id_pel or not self.invoice_det:
...@@ -248,7 +201,7 @@ class Vendor(VendorClass): ...@@ -248,7 +201,7 @@ class Vendor(VendorClass):
self.status = 1 # sukses self.status = 1 # sukses
data = "data" in result and result["data"] or None data = "data" in result and result["data"] or None
parsd = self.pars_data(data) parsd = self.pars_data(data)
return self.set_success(parsd,"payment")
elif resp.status_code == 400: elif resp.status_code == 400:
self.status = -3 self.status = -3
parsd = dict(code=resp.status_code, parsd = dict(code=resp.status_code,
...@@ -272,22 +225,33 @@ class Vendor(VendorClass): ...@@ -272,22 +225,33 @@ class Vendor(VendorClass):
result['nama'] = data["name"] result['nama'] = data["name"]
if "subscriber_name" in data and data["subscriber_name"]: if "subscriber_name" in data and data["subscriber_name"]:
result['nama'] = data["subscriber_name"] result['nama'] = data["subscriber_name"]
if "ref_id" in data and data["ref_id"]:
result['ref_no'] = data["ref_id"]
if "subtotal" in data and data["subtotal"]:
result['subtotal'] = data["subtotal"]
if "discount" in data and data["discount"]:
result['discount'] = data["discount"]
if "total" in data and data["total"]:
result['total'] = data["total"]
if "tarif" in data and data["tariff"]:
result['tarif'] = data["tariff"]
rincian = {} rincian = {}
if "tariff" in data and data["tariff"]:
rincian['tarif'] = data["tariff"]
if "number" in data: if "number" in data:
rincian['no_meter'] = data["number"] rincian['no_meter'] = data["number"]
if "power" in data: if "power" in data:
rincian['daya'] = data["power"] rincian['power'] = data["power"]
if self.v_produk_kd[:3] == "PLN" and self.v_produk_kd != "PLNPASCA":
harga = "price" in data and data["price"] or 0
pokok = harga and int(re.sub("\D","", self.v_produk_kd))*1000 or 0
admin = int(self.vendor_produk.produk.harga)
rincian["pokok"] = pokok
rincian["admin"] = admin
rincian["denda"] = 0
rincian["total"] = pokok+admin
rincian["token"] = "token" in data and data["token"] or ""
elif self.v_produk_kd == "PLNPASCA":
if 'tarif' in rincian and rincian['tarif']:
p = rincian['tarif'].split('/')
if len(p)>1:
rincian["power"] = p[1][:-2]
if "subscriber_id" in data and data["subscriber_id"]:
rincian['no_meter'] = data["subscriber_id"]
i = 1
inquiries = 'inquiries' in data and data['inquiries'] \ inquiries = 'inquiries' in data and data['inquiries'] \
or 'inquiry' in data and data['inquiry'] or {} or 'inquiry' in data and data['inquiry'] or {}
...@@ -296,137 +260,99 @@ class Vendor(VendorClass): ...@@ -296,137 +260,99 @@ class Vendor(VendorClass):
result["rincian"] = rincian result["rincian"] = rincian
return result return result
if self.v_produk_kd == "PLNPASCA" or self.v_produk_kd[:3] == "PAM": inquirieses = type(inquiries) is list and inquiries or [inquiries]
pokok = denda = admin = 0 pokok = denda = admin = 0
period = meter = "" period = meter = ""
jml_period = 0 jml_period = 0
i = 0 i = 0
for inq in inquiries: for inquiries in inquirieses:
pokok += int(inq["base_price"]) if "base_price" in inquiries:
denda += int(inq["fine"]) pokok += int(inquiries["base_price"])
if "admin" in inq: if "fine" in inquiries:
admin += int(inq["admin"]) denda += int(inquiries["fine"])
if "admin_fee" in inq: if "admin" in inquiries:
admin += int(inq["admin_fee"]) admin += int(inquiries["admin"])
period += "period" in inq and inq["period"] + " " if "admin_fee" in inquiries:
jml_period += 1 admin += int(inquiries["admin_fee"])
if "meter_changes" in inq:
meter += inq["meter_changes"] if "coll_fee" in inquiries:
i += 1 if "coll_fee" in rincian:
rincian['coll_fee'] += int(inquiries["coll_fee"])
rincian["pokok"] = pokok else:
rincian["denda"] = denda rincian['coll_fee'] = int(inquiries["coll_fee"])
rincian["admin"] = admin
rincian["period"] = period if "bill_rest" in inquiries:
rincian["jml_bulan"] = jml_period if "bill_rest" in rincian:
if meter: rincian['bill_rest'] += int(inquiries["bill_rest"])
result["meter"] = meter else:
rincian['bill_rest'] = int(inquiries["bill_rest"])
else:
inquirieses = type(inquiries) is list and inquiries or [inquiries] if "period" in inquiries:
i = 0 period += " " + inquiries["period"]
for inquiries in inquirieses:
if "base_price" in inquiries: if "meter_changes" in inquiries:
if "pokok" in rincian: if "meter" in rincian:
rincian['pokok'] += int(inquiries["base_price"]) rincian['meter'] += inquiries["meter_changes"]
else: else:
rincian['pokok'] = int(inquiries["base_price"]) rincian['meter'] = inquiries["meter_changes"]
if "fine" in inquiries: if "usages" in inquiries:
if "denda" in rincian: if "penggunaan" in rincian:
rincian['denda'] += int(inquiries["fine"]) rincian['penggunaan'] += inquiries["usages"]
else: else:
rincian['denda'] = int(inquiries["fine"]) rincian['penggunaan'] = inquiries["usages"]
if "coll_fee" in inquiries: if "installment" in inquiries:
if "coll_fee" in rincian: if "installment" in rincian:
rincian['coll_fee'] += int(inquiries["coll_fee"]) rincian['installment'] += " " + inquiries["installment"]
else: else:
rincian['coll_fee'] = int(inquiries["coll_fee"]) rincian['installment'] = inquiries["installment"]
if "platform" in inquiries:
if "bill_rest" in inquiries: if "platform" in rincian:
if "restitusi" in rincian: rincian['platform'] += " " + inquiries["platform"]
rincian['restitusi'] += int(inquiries["bill_rest"]) else:
else: rincian['platform'] = inquiries["platform"]
rincian['restitusi'] = int(inquiries["bill_rest"])
if "due_date" in inquiries:
if "admin" in inquiries: if "jth_tempo" in rincian:
if "admin" in rincian: rincian['jth_tempo'] += " " + inquiries["due_date"]
rincian['admin'] += int(inquiries["admin"]) else:
else: rincian['jth_tempo'] = inquiries["due_date"]
rincian['admin'] = int(inquiries["admin"])
if "branch_code" in inquiries:
if "admin_fee" in inquiries: rincian['cabang'] = inquiries["branch_code"]
if "admin" in rincian:
rincian['admin'] += int(inquiries["admin_fee"]) if "branch_name" in inquiries:
else: rincian['nm_cabang'] = inquiries["branch_name"]
rincian['admin'] = int(inquiries["admin_fee"])
if "month_counts" in inquiries:
if "period" in inquiries: rincian['jml_bulan'] = inquiries["month_counts"]
if "period" in rincian:
rincian['period'] += " " + inquiries["period"] if "participant_counts" in inquiries:
else: rincian['anggota'] = inquiries["participant_counts"]
rincian['period'] = inquiries["period"]
i += 1
if "meter_changes" in inquiries:
if "meter" in rincian: self.amt_buy = data["total"]
rincian['meter'] += inquiries["meter_changes"] rincian["pokok"] = pokok
else: rincian["denda"] = denda
rincian['meter'] = inquiries["meter_changes"]
if "usages" in inquiries:
if "penggunaan" in rincian:
rincian['penggunaan'] += inquiries["usages"]
else:
rincian['penggunaan'] = inquiries["usages"]
if "installment" in inquiries:
if "periode" in rincian:
rincian['periode'] += " " + inquiries["installment"]
else:
rincian['periode'] = inquiries["installment"]
if "due_date" in inquiries:
if "jth_tempo" in rincian:
rincian['jth_tempo'] += " " + inquiries["due_date"]
else:
rincian['jth_tempo'] = inquiries["due_date"]
if "branch_code" in inquiries:
rincian['kd_cabang'] = inquiries["branch_code"]
if "branch_name" in inquiries:
rincian['nm_cabang'] = inquiries["branch_name"]
if "month_counts" in inquiries:
rincian['jml_bulan'] = inquiries["month_counts"]
if "participant_counts" in inquiries:
rincian['anggota'] = inquiries["participant_counts"]
i += 1
self.amt_buy = result["total"]
harga_pokok = result["subtotal"] - rincian["admin"]
admin = int(self.vendor_produk.produk.harga * i) admin = int(self.vendor_produk.produk.harga * i)
rincian["admin"] = admin rincian["admin"] = admin
result["subtotal"] = int(harga_pokok) + admin rincian["total"] = pokok+denda+admin
rincian["period"] = period
if not 'jml_bulan' in rincian:
rincian["jml_bulan"] = i
result["subtotal"] = rincian["total"]
product_id = self.invoice_det.produk.id product_id = self.invoice_det.produk.id
if hasattr(self.invoice_det, "customer_id"): if hasattr(self.invoice_det, "customer_id"):
partner_id = self.invoice_det.customer_id partner_id = self.invoice_det.customer_id
else: else:
partner_id = self.invoice_det.h2h_ar_invoice.customer_id partner_id = self.invoice_det.h2h_ar_invoice.customer_id
# hitung discount jika discount awal negatif discount + discount awal
discount = PartnerProduk.get_discount(partner_id, product_id) discount = PartnerProduk.get_discount(partner_id, product_id)
self.discount = discount * i self.discount = discount * i
if result["discount"] < 0:
self.discount += result["discount"]
result["discount"] = self.discount result["discount"] = self.discount
self.amt_sell = int(harga_pokok) + admin - self.discount # self.amt_sell = result["total"]
result["total"] = self.amt_sell
result['jml_data'] = i
result['rincian'] = rincian result['rincian'] = rincian
return result return result
import base64
from opensipkd.base.tools import get_random_number
from pyramid.view import view_config
import logging
log = logging.getLogger(__name__)
"""
odeo-purchase http://server/api/odeo/prepaid/purchase
"""
def validate_header(request):
env = request.environ
# http_header = env["HTTP_HEADER"]
# log.info(env)
if 'HTTP_AUTHORIZATION' not in env:
log.info("HTTP_AUTHORIZATION tidak ditemukan")
return
auth = env['HTTP_AUTHORIZATION'].split()
log.info(auth)
if len(auth) < 2 or auth[0] != "Bearer":
log.info('Error Auth')
return
key = ":".join(['agratek', '4444444']).encode()
key_encoded = base64.b64encode(key).decode()
log.info(key_encoded)
if auth[1] != key_encoded:
return
return True
def anauthorized(request):
request.response.status = 401
result = {
"status": "UNAUTHORIZED",
"data": {
"errors": [
"Unauthorized"
]
},
"message": ""
}
return result
def bad_request(request, message=None):
if not message:
message = "Paramter(s) Expected"
request.response.status = 400
result = {
"status": "BAD_REQUEST",
"data": {
"errors": [
"ERROR_MESSAGE_1",
"ERROR_MESSAGE_2",
"ERROR_MESSAGE_ETC"
]
},
"message": message
}
return result
def produk_not_found(request):
return bad_request(request, "Prduk Not Found")
@view_config(route_name='odeo-purchase', renderer='json', request_method="POST")
def view_odeo_purchase(request):
if not validate_header(request):
return anauthorized(request)
params = request.params
data = request.json
if not data or 'data' not in data:
return bad_request(request, 'Data not found')
log.info(data)
data = data['data']
if not data or 'denom' not in data or 'number' not in data:
return bad_request(request)
denom = data["denom"]
number = data['number']
if denom == "TSEL5":
status_code = number[-2:]
status = "SUCCESS"
rc="00"
if status_code == '99':
status = "PENDING"
rc = "68"
elif status_code == '88':
status = "FAILED"
rc = "13"
elif status_code == '77':
status = "DOUBLE"
rc = "67"
result = {
"status": status,
"data": {
"order_id": get_random_number(6),
"price": 5675
},
"message": ""
}
if rc != "00":
message = rc=="68" and "TRX ke {} Sedang Di Proses".format(number) or ""
message = rc=="67" and "TRX ke {} Gagal Doble Transaksi".format(number) or message
message = rc=="13" and "TRX ke {} Gagal".format(number) or message
result["data"].update({"rc":rc, "message":message})
if rc == "68":
result.update({"status": "SUCCESS"})
return result
elif denom == "PLN20":
return {"status": "SUCCESS",
"data": {'price': 22500,
'rc': '68',
'message': 'Trx ke 1234567890 sedang diproses. Harga Rp22,600 REFF#199111',
'order_id': get_random_number(5)},
'message': ''}
elif denom == "PLNPASCA":
status = number[-2:] == '99' and "PENDING" or "SUCCESS"
return {
"status": status,
"data": {
"price": 301600,
"order_id": get_random_number(6),
},
"message": ""
}
elif denom == "BPJSKES1":
status = number[-2:] == '99' and "PENDING" or "SUCCESS"
return {
"status": status,
"data": {
"price": 156100,
"order_id": get_random_number(6),
},
"message": ""
}
elif denom[:3] == "PAM":
status = number[-2:] == '99' and "PENDING" or "SUCCESS"
return {
"status": status,
"data": {
"price": 301600,
"order_id": get_random_number(6),
},
"message": ""
}
elif denom == "PGN":
status = number[-2:] == '99' and "PENDING" or "SUCCESS"
return {
"status": status,
"data": {
"price": 301600,
"order_id": get_random_number(6),
},
"message": ""
}
elif denom == "MF":
status = number[-2:] == '99' and "PENDING" or "SUCCESS"
return {
"status": status,
"data": {
"price": 376100,
"order_id": get_random_number(6),
},
"message": ""
}
elif denom[:6] == "TELKOM":
status = number[-2:] == '99' and "PENDING" or "SUCCESS"
return {
"status": status,
"data": {
"price": 300600,
"order_id": get_random_number(6),
},
"message": ""
}
return produk_not_found(request)
@view_config(route_name='odeo-prepaid-inquiry-pln', renderer='json', request_method="GET")
def view_odeo_pln_pre(request):
if not validate_header(request):
return anauthorized(request)
params = request.params
number = "number" in params and params["number"] or ""
if not number:
return bad_request(request)
return {
"status": "SUCCESS",
"data": {
"number": "XXX",
"subscriber_id": "XXX",
"name": "XXX",
"tariff": "XXX",
"power": "XXX"
},
"message": ""
}
@view_config(route_name='odeo-postpaid-inquiry', renderer='json', request_method="GET")
def view_odeo_postpaid(request):
if not validate_header(request):
return anauthorized(request)
params = request.params
denom = "denom" in params and params["denom"] or ""
number = "number" in params and params["number"] or ""
if not denom or not number:
return bad_request(request)
if number[-2:] == "99":
return bad_request(request, "Subscriber Not Found")
if denom == "BPJSKES1":
return {
"status": "SUCCESS",
"data": {
"subscriber_id": "XXX",
"subscriber_name": "XXX",
"ref_id": "XXX",
"inquiries": {
"branch_code": "-",
"branch_name": "XXX",
"month_counts": 1,
"participant_counts": 3,
"base_price": 154200,
"bill_rest": 0,
"admin": 2500
},
"subtotal": 156700,
"discount": 600,
"total": 156100
},
"message": ""
}
elif denom == "PLNPASCA":
return {
"status": "SUCCESS",
"data": {
"subscriber_id": "XXX",
"subscriber_name": "XXX",
"ref_id": "XXX",
"tariff": "R1/1300VA",
"inquiries": [
{
"period": "2016-08",
"base_price": 300000,
"fine": 0,
"admin_fee": 2500
},
{
"period": "2016-07",
"base_price": 300000,
"fine": 10000,
"admin_fee": 2500
}
],
"subtotal": 302500,
"discount": 900,
"total": 301600
},
"message": ""
}
elif denom[:3] == "PAM":
return {
"status": "SUCCESS",
"data": {
"subscriber_id": "XXX",
"subscriber_name": "XXX",
"ref_id": "XXX",
"inquiries": [
{
"period": "XXX",
"base_price": 300000,
"fine": 0,
"admin_fee": 2500,
"meter_changes": "XXX"
}
],
"subtotal": 302500,
"discount": 900,
"total": 301600
},
"message": ""
}
elif denom == "PGN":
return {
"status": "SUCCESS",
"data": {
"subscriber_id": "XXX",
"subscriber_name": "XXX",
"ref_id": "XXX",
"inquiries": {
"period": "XXX",
"meter_changes": "XXX",
"usages": "XXX",
"base_price": 300000,
"admin_fee": 2500
},
"subtotal": 302500,
"discount": 900,
"total": 301600
},
"message": ""
}
elif denom[:2] == "MF":
return {
"status": "SUCCESS",
"data": {
"subscriber_id": "XXX",
"subscriber_name": "XXX",
"ref_id": "XXX",
"inquiries": {
"installment": "XXX",
"due_date": "XXX",
"platform": "XXX",
"base_price": 300000,
"coll_fee": 0,
"fine": 75000,
"admin": 2000
},
"subtotal": 377000,
"discount": 900,
"total": 376100
},
"message": ""
}
elif denom[:6] == "TELKOM":
return {
"status": "SUCCESS",
"data": {
"subscriber_id": "XXX",
"subscriber_name": "XXX",
"ref_id": "XXX",
"inquiries": {
"period": "XXX",
"base_price": 300000,
"admin_fee": 1500
},
"subtotal": 301500,
"discount": 900,
"total": 300600
},
"message": ""
}
return produk_not_found(request)
# @view_config(route_name='odeo-order', renderer='json', request_method="GET")
# def view_odeo_pln_pre(request):
# if not validate_header(request):
# return anauthorized(request)
# matchdict = request.matchdict
# id = "id" in matchdict and matchdict["id"] or ""
# return {
# "order_id": 123,
# "name": "Telkomsel 5",
# "msisdn": "08xx",
# "serial_number": "XXX",
# "status": "COMPLETED",
# "price": 5000
# }
...@@ -61,7 +61,7 @@ class AddSchema(colander.Schema): ...@@ -61,7 +61,7 @@ class AddSchema(colander.Schema):
oid="satuan_id", widget=deferred_satuan) oid="satuan_id", widget=deferred_satuan)
volume = colander.SchemaNode( volume = colander.SchemaNode(
colander.Integer(), colander.Integer(),
oid="volume " oid="volume"
) )
......
Penggunaan Alembic
==================
1. Masuk ke folder module yang akan diinstall
Jalankan perintah berikut ini pada terminal:
```bash
$ alembic init alembic
$ cd alembic
```
2. Edit file `env.py`
Ubah baris 23
```python
# target_metadata = None
from opensipkd.base.models import Base
target_metadata = Base.metadata
version_table = "alembic_pasar_version" # gunakan sesuai dengan dama module biar gak tumpang tindih
```
3. copy alembic.ini.tpl ke folder alembic menjadi alembic.ini:
```commandline
cp ../alembic.ini.tpl alembic.ini
```
4. edit alembic.ini
```ini
sqlalchemy.url = {{db_url}}
sqlalchemy.url = dengan url yang akan digunakan
```
5. Untuk membuat file revisi:
```commandline
alembic -c alembic\alembic.ini revision -m "add modules in produk_category"
```
Output:
```commandline
Generating C:\project\apps3\pasar\models\alembic\versions\dee47015bc2e_add_modules_in_produk_category.py ... done
```
6. Edit file revisi tersebut
ubah pada bagian upgrade
```python
def upgrade():
op.add_column('produk_kategori', sa.Column('moduels', sa.String(64)))
def downgrade():
op.drop_column('produk_kategori', sa.Column('moduels', sa.String(64)))
```
7. Run migrastion
```commandline
alembic -c alembic\alembic.ini upgrade head
```
Catatan:
Jenis operasi standard
```python
def upgrade():
op.create_table(
'account',
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('name', sa.String(50), nullable=False),
sa.Column('description', sa.Unicode(200)),
)
def downgrade():
op.drop_table('account')
```
\ No newline at end of file \ No newline at end of file
import base64
import json
import re
from time import sleep
import requests
from opensipkd.base import get_settings
from opensipkd.pasar.models import PartnerProduk, H2hArInvoiceDet
from ..vendor import VendorClass
import logging
log = logging.getLogger(__name__)
import urllib3
urllib3.disable_warnings()
timeout = 20
class Vendor(VendorClass):
def __init__(self, vendor_produk, invoice_det):
VendorClass.__init__(self, vendor_produk, invoice_det=invoice_det)
# id_pel, customer_id, cust_trx, row
settings = get_settings()
self.mid = 'test_mid' in settings and settings['odeo_mid'] or None
self.key = 'test_key' in settings and settings['odeo_key'] or None
self.url = 'test_url' in settings and settings['odeo_url'] or None
key = ":".join([self.mid, self.key]).encode()
self.auth = base64.b64encode(key).decode()
def get_headers(self):
return {'Authorization': 'Bearer {key}'.format(key=self.auth)}
def get_url(self, url=None):
return url and self.url + url or self.url
def _inquiry(self):
if self.v_produk_kd[:3] == 'PLN' and self.v_produk_kd != 'PLNPASCA':
params = dict(
number=self.id_pel
)
url = self.get_url('/prepaid/pln/inquiry')
else:
params = dict(
denom=self.v_produk_kd,
number=self.id_pel
)
url = self.get_url('/postpaid/inquiry')
self.request = params
log.info("Inquiry Request: url: %s params %s" % (url, params))
self.save_log("inquiry")
try:
resp = requests.get(url, params=params, verify=False,
headers=self.get_headers(), timeout=timeout)
except:
return
if not resp:
return
try:
result = json.loads(resp.text)
except:
result = resp.text
self.response = result
log.info("Inquiry Response: %s" % self.response)
if resp.status_code == 200:
self.status = 1 # sukses
data = "data" in result and result["data"] or None
return self.pars_data(data)
else:
return
def inquiry(self):
if not self.v_produk_kd or not self.id_pel:
return self.set_response(message='Parameter tidak lengkap')
parsd = self._inquiry()
if not parsd:
return self.set_failed() # parsd
return self.set_success(parsd) # parsd
def payment(self):
#Jika kategory bukan e-pulsa Call Inquiry First
parsd = None
if self.vendor_produk.produk.kategori.kode != "e-pulsa":
parsd = self._inquiry()
if not parsd:
return self.set_failed()
params = dict(
data=dict(
denom=self.v_produk_kd,
number=self.id_pel
)
)
self.request = params
log.info("Payment Request: %s" % self.request)
self.save_log("payment")
if not parsd:
parsd = self.get_price()
url = self.get_url("/prepaid/purchase")
try:
resp = requests.post(url, data=json.dumps(params), verify=False,
headers=self.get_headers(), timeout=timeout)
except:
resp = None
if resp is None:
return self.set_pending(parsd, typ="payment")
# todo: dibuat seolah menjadi belum di transaksikan
# todo: membuat cron untuk melakukan pengecekan transaksi
try:
result = json.loads(resp.text)
self.response = result
log.info("Payment Response: %s" % self.response)
except:
result = resp.text
self.response = result
log.info("Payment Response: %s" % self.response)
return self.set_pending(parsd, typ="payment")
# odeo mengembalikan result dalam bentuk status
# 0200 ok
# 0400 bad request
# 0401 auth error
if resp.status_code == 200 and type(result) is dict: # 0200
data = "data" in result and result["data"] or {}
if not data:
self.status = 0
return self.set_pending(parsd, typ="payment")
self.vend_inv_no = "order_id" in data and data["order_id"] or self.vend_inv_no
self.amt_buy = "price" in data and data["price"] or self.amt_buy
if "rc" in data:
if data["rc"] == "13": # Gagal
return self.set_failed(parsd, typ="payment")
elif data["rc"] == "67": # Gagal Double
return self.set_failed(parsd, typ="payment")
elif data["rc"] == "68": # Pending
return self.set_pending(parsd, typ="payment")
else:
self.serial_number = 'serial_number' in data and data["serial_numner"] \
or self.serial_number
return self.set_success(parsd, typ="payment")
elif resp.status_code == 400:
data = "data" in result and result["data"] or None
message = ""
if data and "errors" in data:
msg = data["errors"][0]
pos = msg.find("Sisa saldo")
message = pos > -1 and msg[:pos] or msg
pos = message.find("SN: ")
sn = ""
if pos > -1:
sn_spl = message[pos:].split(" ")
sn = len(sn_spl) > 1 and sn_spl[1] or ""
parsd["serial_number"] = sn
return self.set_failed(parsd, message=message, typ="payment")
elif resp.status_code == 401:
return self.set_failed(parsd, typ="payment")
def advice(self):
if not self.v_produk_kd or not self.id_pel or not self.invoice_det:
return dict(code=9999,
message='Parameter tidak lengkap')
if self.kategori == 'e-payment':
order_id = self.invoice_det.vend_inv_no
url = self.get_url('/order/{order_id}'.format(order_id=order_id))
params = None
self.request = url
else:
params = dict(
data=dict(
denom=self.v_produk_kd,
number=self.id_pel
)
)
self.request = params
url = self.get_url('/prepaid/purchase-get')
self.save_log("advice")
try:
resp = requests.get(url, params=params, verify=False,
headers=self.get_headers(), timeout=timeout)
except:
return self.set_response()
try:
result = json.loads(resp.text)
except:
result = resp.text
self.response = result
if resp.ok:
self.status = 1 # sukses
data = "data" in result and result["data"] or None
parsd = self.pars_data(data)
return self.set_success(parsd,"payment")
elif resp.status_code == 400:
self.status = -3
parsd = dict(code=resp.status_code,
message=resp.text)
else:
self.status = -4
parsd = dict(code=500,
message="Other Error")
self.save_log('advice')
return parsd
def pars_data(self, data):
result = dict()
if not data:
return result
if "subscriber_id" in data and data["subscriber_id"]:
result['id_pel'] = data["subscriber_id"]
if "name" in data and data["name"]:
result['nama'] = data["name"]
if "subscriber_name" in data and data["subscriber_name"]:
result['nama'] = data["subscriber_name"]
rincian = {}
if "tariff" in data and data["tariff"]:
rincian['tarif'] = data["tariff"]
if "number" in data:
rincian['no_meter'] = data["number"]
if "power" in data:
rincian['power'] = data["power"]
if self.v_produk_kd[:3] == "PLN" and self.v_produk_kd != "PLNPASCA":
harga = "price" in data and data["price"] or 0
pokok = harga and int(re.sub("\D","", self.v_produk_kd))*1000 or 0
admin = int(self.vendor_produk.produk.harga)
rincian["pokok"] = pokok
rincian["admin"] = admin
rincian["denda"] = 0
rincian["total"] = pokok+admin
rincian["token"] = "token" in data and data["token"] or ""
elif self.v_produk_kd == "PLNPASCA":
if 'tarif' in rincian and rincian['tarif']:
p = rincian['tarif'].split('/')
if len(p)>1:
rincian["power"] = p[1][:-2]
if "subscriber_id" in data and data["subscriber_id"]:
rincian['no_meter'] = data["subscriber_id"]
i = 1
inquiries = 'inquiries' in data and data['inquiries'] \
or 'inquiry' in data and data['inquiry'] or {}
if not inquiries:
result["jml_data"] = 1
result["rincian"] = rincian
return result
inquirieses = type(inquiries) is list and inquiries or [inquiries]
pokok = denda = admin = 0
period = meter = ""
jml_period = 0
i = 0
for inquiries in inquirieses:
if "base_price" in inquiries:
pokok += int(inquiries["base_price"])
if "fine" in inquiries:
denda += int(inquiries["fine"])
if "admin" in inquiries:
admin += int(inquiries["admin"])
if "admin_fee" in inquiries:
admin += int(inquiries["admin_fee"])
if "coll_fee" in inquiries:
if "coll_fee" in rincian:
rincian['coll_fee'] += int(inquiries["coll_fee"])
else:
rincian['coll_fee'] = int(inquiries["coll_fee"])
if "bill_rest" in inquiries:
if "bill_rest" in rincian:
rincian['bill_rest'] += int(inquiries["bill_rest"])
else:
rincian['bill_rest'] = int(inquiries["bill_rest"])
if "period" in inquiries:
period += " " + inquiries["period"]
if "meter_changes" in inquiries:
if "meter" in rincian:
rincian['meter'] += inquiries["meter_changes"]
else:
rincian['meter'] = inquiries["meter_changes"]
if "usages" in inquiries:
if "penggunaan" in rincian:
rincian['penggunaan'] += inquiries["usages"]
else:
rincian['penggunaan'] = inquiries["usages"]
if "installment" in inquiries:
if "installment" in rincian:
rincian['installment'] += " " + inquiries["installment"]
else:
rincian['installment'] = inquiries["installment"]
if "platform" in inquiries:
if "platform" in rincian:
rincian['platform'] += " " + inquiries["platform"]
else:
rincian['platform'] = inquiries["platform"]
if "due_date" in inquiries:
if "jth_tempo" in rincian:
rincian['jth_tempo'] += " " + inquiries["due_date"]
else:
rincian['jth_tempo'] = inquiries["due_date"]
if "branch_code" in inquiries:
rincian['cabang'] = inquiries["branch_code"]
if "branch_name" in inquiries:
rincian['nm_cabang'] = inquiries["branch_name"]
if "month_counts" in inquiries:
rincian['jml_bulan'] = inquiries["month_counts"]
if "participant_counts" in inquiries:
rincian['anggota'] = inquiries["participant_counts"]
i += 1
self.amt_buy = data["total"]
rincian["pokok"] = pokok
rincian["denda"] = denda
admin = int(self.vendor_produk.produk.harga * i)
rincian["admin"] = admin
rincian["total"] = pokok+denda+admin
rincian["period"] = period
if not 'jml_bulan' in rincian:
rincian["jml_bulan"] = i
result["subtotal"] = rincian["total"]
product_id = self.invoice_det.produk.id
if hasattr(self.invoice_det, "customer_id"):
partner_id = self.invoice_det.customer_id
else:
partner_id = self.invoice_det.h2h_ar_invoice.customer_id
discount = PartnerProduk.get_discount(partner_id, product_id)
self.discount = discount * i
result["discount"] = self.discount
# self.amt_sell = result["total"]
result['rincian'] = rincian
return result
import base64
from opensipkd.base.tools import get_random_number
from pyramid.view import view_config
import logging
log = logging.getLogger(__name__)
"""
odeo-purchase http://server/api/odeo/prepaid/purchase
"""
def validate_header(request):
env = request.environ
# http_header = env["HTTP_HEADER"]
# log.info(env)
# if 'HTTP_AUTHORIZATION' not in env:
# log.info("HTTP_AUTHORIZATION tidak ditemukan")
# return
#
# auth = env['HTTP_AUTHORIZATION'].split()
# log.info(auth)
# if len(auth) < 2 or auth[0] != "Bearer":
# log.info('Error Auth')
# return
#
# key = ":".join(['agratek', '4444444']).encode()
# key_encoded = base64.b64encode(key).decode()
# log.info(key_encoded)
# if auth[1] != key_encoded:
# return
return True
def anauthorized(request):
request.response.status = 401
result = {
"status": "UNAUTHORIZED",
"data": {
"errors": [
"Unauthorized"
]
},
"message": ""
}
return result
def bad_request(request, message=None):
if not message:
message = "Paramter(s) Expected"
request.response.status = 400
result = {
"status": "BAD_REQUEST",
"data": {
"errors": [
"ERROR_MESSAGE_1",
"ERROR_MESSAGE_2",
"ERROR_MESSAGE_ETC"
]
},
"message": message
}
return result
def produk_not_found(request):
return bad_request(request, "Prduk Not Found")
@view_config(route_name='odeo-purchase', renderer='json', request_method="POST")
def view_odeo_purchase(request):
if not validate_header(request):
return anauthorized(request)
params = request.params
data = request.json
if not data or 'data' not in data:
return bad_request(request, 'Data not found')
log.info(data)
data = data['data']
if not data or 'denom' not in data or 'number' not in data:
return bad_request(request)
denom = data["denom"]
number = data['number']
if denom == "TSEL5":
status_code = number[-2:]
status = "SUCCESS"
rc="00"
if status_code == '99':
status = "PENDING"
rc = "68"
elif status_code == '88':
status = "FAILED"
rc = "13"
elif status_code == '77':
status = "DOUBLE"
rc = "67"
result = {
"status": status,
"data": {
"order_id": get_random_number(6),
"price": 5675
},
"message": ""
}
if rc != "00":
message = rc=="68" and "TRX ke {} Sedang Di Proses".format(number) or ""
message = rc=="67" and "TRX ke {} Gagal Doble Transaksi".format(number) or message
message = rc=="13" and "TRX ke {} Gagal".format(number) or message
result["data"].update({"rc":rc, "message":message})
if rc == "68":
result.update({"status": "SUCCESS"})
return result
elif denom == "PLN20":
return {"status": "SUCCESS",
"data": {'price': 22500,
'rc': '68',
'message': 'Trx ke 1234567890 sedang diproses. Harga Rp22,600 REFF#199111',
'order_id': get_random_number(5)},
'message': ''}
elif denom == "PLNPASCA":
status = number[-2:] == '99' and "PENDING" or "SUCCESS"
return {
"status": status,
"data": {
"price": 301600,
"order_id": get_random_number(6),
},
"message": ""
}
elif denom == "BPJSKES1":
status = number[-2:] == '99' and "PENDING" or "SUCCESS"
return {
"status": status,
"data": {
"price": 156100,
"order_id": get_random_number(6),
},
"message": ""
}
elif denom[:3] == "PAM":
status = number[-2:] == '99' and "PENDING" or "SUCCESS"
return {
"status": status,
"data": {
"price": 301600,
"order_id": get_random_number(6),
},
"message": ""
}
elif denom == "PGN":
status = number[-2:] == '99' and "PENDING" or "SUCCESS"
return {
"status": status,
"data": {
"price": 301600,
"order_id": get_random_number(6),
},
"message": ""
}
elif denom == "MF":
status = number[-2:] == '99' and "PENDING" or "SUCCESS"
return {
"status": status,
"data": {
"price": 376100,
"order_id": get_random_number(6),
},
"message": ""
}
elif denom[:6] == "TELKOM":
status = number[-2:] == '99' and "PENDING" or "SUCCESS"
return {
"status": status,
"data": {
"price": 300600,
"order_id": get_random_number(6),
},
"message": ""
}
return produk_not_found(request)
@view_config(route_name='odeo-prepaid-inquiry-pln', renderer='json', request_method="GET")
def view_odeo_pln_pre(request):
if not validate_header(request):
return anauthorized(request)
params = request.params
number = "number" in params and params["number"] or ""
if not number:
return bad_request(request)
return {
"status": "SUCCESS",
"data": {
"number": "XXX",
"subscriber_id": "XXX",
"name": "XXX",
"tariff": "XXX",
"power": "XXX"
},
"message": ""
}
@view_config(route_name='odeo-postpaid-inquiry', renderer='json', request_method="GET")
def view_odeo_postpaid(request):
if not validate_header(request):
return anauthorized(request)
params = request.params
denom = "denom" in params and params["denom"] or ""
number = "number" in params and params["number"] or ""
if not denom or not number:
return bad_request(request)
if number[-2:] == "99":
return bad_request(request, "Subscriber Not Found")
if denom == "BPJSKES1":
return {
"status": "SUCCESS",
"data": {
"subscriber_id": "XXX",
"subscriber_name": "XXX",
"ref_id": "XXX",
"inquiries": {
"branch_code": "-",
"branch_name": "XXX",
"month_counts": 1,
"participant_counts": 3,
"base_price": 154200,
"bill_rest": 0,
"admin": 2500
},
"subtotal": 156700,
"discount": 600,
"total": 156100
},
"message": ""
}
elif denom == "PLNPASCA":
return {
"status": "SUCCESS",
"data": {
"subscriber_id": "XXX",
"subscriber_name": "XXX",
"ref_id": "XXX",
"tariff": "R1/1300VA",
"inquiries": [
{
"period": "2016-08",
"base_price": 300000,
"fine": 0,
"admin_fee": 2500
},
{
"period": "2016-07",
"base_price": 300000,
"fine": 10000,
"admin_fee": 2500
}
],
"subtotal": 302500,
"discount": 900,
"total": 301600
},
"message": ""
}
elif denom[:3] == "PAM":
return {
"status": "SUCCESS",
"data": {
"subscriber_id": "XXX",
"subscriber_name": "XXX",
"ref_id": "XXX",
"inquiries": [
{
"period": "XXX",
"base_price": 300000,
"fine": 0,
"admin_fee": 2500,
"meter_changes": "XXX"
}
],
"subtotal": 302500,
"discount": 900,
"total": 301600
},
"message": ""
}
elif denom == "PGN":
return {
"status": "SUCCESS",
"data": {
"subscriber_id": "XXX",
"subscriber_name": "XXX",
"ref_id": "XXX",
"inquiries": {
"period": "XXX",
"meter_changes": "XXX",
"usages": "XXX",
"base_price": 300000,
"admin_fee": 2500
},
"subtotal": 302500,
"discount": 900,
"total": 301600
},
"message": ""
}
elif denom[:2] == "MF":
return {
"status": "SUCCESS",
"data": {
"subscriber_id": "XXX",
"subscriber_name": "XXX",
"ref_id": "XXX",
"inquiries": {
"installment": "XXX",
"due_date": "XXX",
"platform": "XXX",
"base_price": 300000,
"coll_fee": 0,
"fine": 75000,
"admin": 2000
},
"subtotal": 377000,
"discount": 900,
"total": 376100
},
"message": ""
}
elif denom[:6] == "TELKOM":
return {
"status": "SUCCESS",
"data": {
"subscriber_id": "XXX",
"subscriber_name": "XXX",
"ref_id": "XXX",
"inquiries": {
"period": "XXX",
"base_price": 300000,
"admin_fee": 1500
},
"subtotal": 301500,
"discount": 900,
"total": 300600
},
"message": ""
}
return produk_not_found(request)
# @view_config(route_name='odeo-order', renderer='json', request_method="GET")
# def view_odeo_pln_pre(request):
# if not validate_header(request):
# return anauthorized(request)
# matchdict = request.matchdict
# id = "id" in matchdict and matchdict["id"] or ""
# return {
# "order_id": 123,
# "name": "Telkomsel 5",
# "msisdn": "08xx",
# "serial_number": "XXX",
# "status": "COMPLETED",
# "price": 5000
# }
...@@ -6,26 +6,14 @@ Invoice To Customer ...@@ -6,26 +6,14 @@ Invoice To Customer
""" """
import hashlib import hashlib
import json import logging
import re
from datetime import datetime
from importlib import import_module from importlib import import_module
import colander from ..models import (flush_row, PartnerProduk)
import requests from ..tools import (get_settings)
import xmltodict
from deform import widget, Form, ValidationFailure
# from opensipkd.pasar.models import PartnerLog
from pyramid.httpexceptions import HTTPFound
from pyramid.view import view_config
from . import BaseView # , save_file_upload
from ..models import (DBSession, flush_row, Partner, PartnerProduk, H2hArInvoiceDet)
from ..models import (Produk, ProdukKategori)
from ..tools import (btn_next, date_from_str, get_settings, btn_reset,
btn_inquiry, btn_advice, btn_payment, get_jsonrpc)
from ..tools import log # from opensipkd.pasar.models import PartnerLog
log = logging.getLogger(__name__)
class VendorClass(object): class VendorClass(object):
...@@ -55,7 +43,7 @@ class VendorClass(object): ...@@ -55,7 +43,7 @@ class VendorClass(object):
self.amt_sell = 0 self.amt_sell = 0
self.discount = 0 self.discount = 0
self.trx_id = 0 self.trx_id = 0
def set_response(self, data=None, message=None, code=999, typ="inquiry"): def set_response(self, data=None, message=None, code=999, typ="inquiry"):
if not data and message: if not data and message:
message = message and message or "No Response From Biller" message = message and message or "No Response From Biller"
...@@ -69,17 +57,34 @@ class VendorClass(object): ...@@ -69,17 +57,34 @@ class VendorClass(object):
def set_success(self, data=None, typ="payment"): def set_success(self, data=None, typ="payment"):
self.status = 1 self.status = 1
self.result = data
data = data and data or {} data = data and data or {}
data.update(dict(code=0, data.update(dict(code=0,
message="SUCCESS", message="SUCCESS",
status="SUCCESS")) status="SUCCESS"))
func = self.vendor_produk.produk.kategori.module
pckgs = 'agratek.api.merchant.views.vendor'
log.info("Module: %s Pckgs: %s" % (func, pckgs))
modul = import_module(pckgs)
cls = hasattr(modul, func) and getattr(modul, func) or None
if cls:
data['denom'] = self.invoice_det.produk.kode
data['id_pel'] = self.id_pel
data['nama'] = 'nama' in data and data['nama'] or None
cls_module = cls(data)
data = cls_module.sukses()
return self.set_response(data, typ=typ) return self.set_response(data, typ=typ)
def set_failed(self, data=None, message=None, typ="payment"): def set_failed(self, data=None, message=None, typ="payment"):
self.status = -3 self.status = -3
data = data and data or {} data = data and data or {}
message = message and message or "FAILED" message = message and message or "FAILED"
data.update(dict(code=13, data.update(dict(denom=self.vendor_produk.produk.kode,
id_pel=self.id_pel,
code=13,
message=message, message=message,
status="FAILED")) status="FAILED"))
return self.set_response(data, typ=typ) return self.set_response(data, typ=typ)
...@@ -88,15 +93,20 @@ class VendorClass(object): ...@@ -88,15 +93,20 @@ class VendorClass(object):
self.status = -3 self.status = -3
message = message and message or "DOUBLE" message = message and message or "DOUBLE"
data = data and data or {} data = data and data or {}
data.update(dict(code=67, data.update(dict(denom=self.vendor_produk.produk.kode,
id_pel=self.id_pel,
code=67,
message=message, message=message,
status="FAILED")) status="FAILED"))
return self.set_response(data, typ=typ) return self.set_response(data, typ=typ)
def set_pending(self, data=None, message=None, typ="payment"): def set_pending(self, data=None, message=None, typ="payment"):
self.status = -1
data = data and data or {} data = data and data or {}
message = message and message or "PENDING" message = "TRX ke {} sedang di proses".format(self.id_pel)
data.update(dict(code=68, data.update(dict(denom=self.vendor_produk.produk.kode,
id_pel=self.id_pel,
code=68,
status="PENDING", status="PENDING",
message=message) message=message)
) )
...@@ -104,13 +114,13 @@ class VendorClass(object): ...@@ -104,13 +114,13 @@ class VendorClass(object):
def get_price(self, pokok=0): def get_price(self, pokok=0):
product_id = self.invoice_det.produk_id product_id = self.invoice_det.produk_id
self.amt_buy = pokok+self.vendor_produk.harga self.amt_buy = pokok + self.vendor_produk.harga
if hasattr(self.invoice_det, "customer_id"): if hasattr(self.invoice_det, "customer_id"):
customer_id = self.invoice_det.customer_id customer_id = self.invoice_det.customer_id
else: else:
customer_id = self.invoice_det.h2h_ar_invoice.customer_id customer_id = self.invoice_det.h2h_ar_invoice.customer_id
harga = pokok+self.vendor_produk.produk.harga harga = pokok + self.vendor_produk.produk.harga
self.discount = PartnerProduk.get_discount(customer_id, product_id) self.discount = PartnerProduk.get_discount(customer_id, product_id)
self.amt_sell = harga - self.discount self.amt_sell = harga - self.discount
return dict( return dict(
...@@ -121,6 +131,14 @@ class VendorClass(object): ...@@ -121,6 +131,14 @@ class VendorClass(object):
def save_log(self, typ): def save_log(self, typ):
self.invoice_det.status = self.status self.invoice_det.status = self.status
if self.result:
if "total" in self.result:
self.amt_sell = self.result["total"]
if "rincian" in self.result and self.result["rincian"] \
and "token" in self.result["rincian"] \
and self.result["rincian"]["token"]:
self.serial_number = self.result["rincian"]["token"]
self.result["serial_number"] = self.serial_number
if hasattr(self.invoice_det, 'serial_number'): if hasattr(self.invoice_det, 'serial_number'):
self.invoice_det.serial_number = self.serial_number self.invoice_det.serial_number = self.serial_number
...@@ -153,45 +171,229 @@ class VendorClass(object): ...@@ -153,45 +171,229 @@ class VendorClass(object):
flush_row(self.invoice_det) flush_row(self.invoice_det)
# class Other(object): class Result(object):
# def __init_subclass__(self, **kwargs): def __init__(self, values, **kwargs):
# self.settings = get_settings() self.values = values
# vendor_produk = "vendor_produk" in kwargs and kwargs["vendor_produk"] or None if "rincian" in values:
# self.vendor_id = vendor_produk.partner_id discount = int(self.values["discount"])
# self.produk_id = vendor_produk.produk_id subtotal = int(values["rincian"]["total"])
# self.v_produk_kd = vendor_produk.kode self.values["subtotal"] = subtotal
# self.produk_kd = vendor_produk.produk.kode self.values["discount"] = discount
# self.kategori = vendor_produk.produk.kategori.nama self.values["total"] = subtotal - discount
# values = "values" in kwargs and kwargs["values"] or None
# # self.bill_no = bill_no """
# self.customer_id = 'customer_id' in values and values['customer_id'] or None {
# self.cust_trx = 'cust_trx' in values and values['cust_trx'] or None "denom": "TSEL5",
# row = 'row' in values and values['row'] or None "id_pel": "0812121212",
# self.partner_log = row "subtotal": 5675,
# self.partner_log_id = row and row.id or None "discount": 0,
# "total": 5675,
# self.status = row and row.status or 0 "code":0
# self.amt_buy = row and row.amt_buy or 0 "status": "PENDING"
# self.amt_sell = row and row.amt_sell or 0 "message":""
# self.cust_trx = row and row.cust_trx or "" }
# self.vend_trx = row and row.vend_trx or "" """
#
# self.response = None def set_denom(self):
# self.request = None return {
# 'denom': self.values['denom'],
# # bill_no, customer_id = customer_id, 'id_pel': self.values['id_pel']}
# # cust_trx_id = cust_trx_id, row = row,
# # def set_value(self):
# result = {
# def get_product(self): 'subtotal': self.values['subtotal'],
# pass 'discount': self.values['discount'],
# 'total': self.values['total']}
# def inquiry(self): if self.values["nama"]:
# pass result.update({'nama': self.values["nama"]})
# serial_numnber = 'serial_number' in self.values and self.values["serial_number"] or ""
# def payment(self): result.update({'serial_number': serial_numnber})
# pass
return result
def sukses(self):
result = self.set_denom()
result.update(self.set_value())
result.update({'code': 0,
'message': 'Transaksi Berhasil',
'status': 'SUCCESS',
})
return result
def pending(self):
result = self.set_denom()
result.update(self.set_value())
result.update({'code': 68,
'message': 'Silahkan lakukan manual advice setelah beberapa saat',
'status': 'PENDING'})
return result
def gagal(self):
result = self.set_denom()
result.update({'code': 99,
'message': 'Silahkan coba beberapa saat lagi',
'status': 'FAILED',
})
return result
def not_found(self):
result = self.set_denom()
result.update({'code': 55,
'message': 'Data Tidak ditemukan',
'status': 'FAILED',
})
return result
def allready_paid(self):
result = self.set_denom()
result.update({'code': 54,
'message': 'Data sudah dibayar',
'status': 'FAILED',
})
return result
class PulsaResult(Result):
pass
class Rincian(Result):
def rincian(self):
pass # Override Please
def sukses(self):
result = super().sukses()
result["rincian"] = self.rincian()
return result
def pending(self):
result = super().pending()
result["rincian"] = self.rincian()
return result
class PlnPreResult(Rincian):
def rincian(self):
log.info("Values: {}".format(self.values))
pokok = self.values["rincian"]["pokok"]
admin = self.values["rincian"]["admin"]
denda = self.values["rincian"]["denda"]
result = dict(
pokok=pokok,
denda=denda,
admin=admin,
total=pokok + denda + admin,
tarif=self.values["rincian"]["tarif"],
no_meter=self.values["rincian"]["no_meter"],
power=self.values["rincian"]["power"],
)
if self.values["rincian"]["token"]:
result.update({'token': self.values["rincian"]["token"]})
return result
class PlnPascaResult(Rincian):
def rincian(self):
pokok = self.values["rincian"]["pokok"]
admin = self.values["rincian"]["admin"]
denda = self.values["rincian"]["denda"]
result = dict(
period=self.values["rincian"]["period"],
jml_bulan=self.values["rincian"]["jml_bulan"],
pokok=pokok,
denda=denda,
admin=admin,
total=pokok + denda + admin,
tarif=self.values["rincian"]["tarif"],
no_meter=self.values["rincian"]["no_meter"],
power=self.values["rincian"]["power"],
)
return result
class PgnResult(Rincian):
def rincian(self):
pokok = self.values["rincian"]["pokok"]
admin = self.values["rincian"]["admin"]
denda = self.values["rincian"]["denda"]
return dict(
pokok=self.values["rincian"]["pokok"],
denda=self.values["rincian"]["denda"],
admin=self.values["rincian"]["admin"],
total=pokok + denda + admin,
period=self.values["rincian"]["period"],
meter=self.values["rincian"]["meter"],
penggunaan=self.values["rincian"]["penggunaan"],
)
class MfResult(Rincian):
def rincian(self):
pokok = self.values["rincian"]["pokok"]
admin = self.values["rincian"]["admin"]
denda = self.values["rincian"]["denda"]
coll_fee = self.values["rincian"]["coll_fee"]
return dict(
pokok=pokok,
denda=denda,
admin=admin,
coll_fee=coll_fee,
total=pokok + denda + admin+ coll_fee,
period=self.values["rincian"]["period"],
jth_tempo=self.values["rincian"]["jth_tempo"],
platform=self.values["rincian"]["platform"],
)
class TelkomResult(Rincian):
def rincian(self):
pokok = self.values["rincian"]["pokok"]
admin = self.values["rincian"]["admin"]
denda = self.values["rincian"]["denda"]
return dict(
period=self.values["rincian"]["period"],
pokok=pokok,
denda=denda,
admin=admin,
total=pokok + denda + admin,
)
class BpjsResult(Rincian):
def rincian(self):
pokok = self.values["rincian"]["pokok"]
admin = self.values["rincian"]["admin"]
denda = self.values["rincian"]["denda"]
return dict(
bill_rest=self.values["rincian"]["bill_rest"],
cabang=self.values["rincian"]["cabang"],
nm_cabang=self.values["rincian"]["nm_cabang"],
anggota=self.values["rincian"]["anggota"],
jml_bulan=self.values["rincian"]["jml_bulan"],
pokok=pokok,
denda=denda,
admin=admin,
total=pokok + denda + admin,
)
class PdamResult(Rincian):
def rincian(self):
pokok = self.values["rincian"]["pokok"]
admin = self.values["rincian"]["admin"]
denda = self.values["rincian"]["denda"]
result = dict(
period=self.values["rincian"]["period"],
jml_bulan=self.values["rincian"]["jml_bulan"],
meter=self.values["rincian"]["meter"],
pokok=pokok,
denda=denda,
admin=admin,
total=pokok + denda + admin,
)
return result
def sha256(hash_string): def sha256(hash_string):
return hashlib.sha256(hash_string.encode()).hexdigest() return hashlib.sha256(hash_string.encode()).hexdigest()
...@@ -9,65 +9,68 @@ from opensipkd.base import get_settings ...@@ -9,65 +9,68 @@ from opensipkd.base import get_settings
from opensipkd.pasar.models import Partner, PartnerProduk, Produk from opensipkd.pasar.models import Partner, PartnerProduk, Produk
from pyramid_rpc.jsonrpc import JsonRpcError from pyramid_rpc.jsonrpc import JsonRpcError
from ..vendor import VendorClass
vsi_status = { vsi_status = {
"11": {"message": "ERROR NEED TO SIGN ON", "status": -1}, "11": {"message": "ERROR NEED TO SIGN ON", "status": -3, "code": 99},
"12": {"message": "ERROR Tidak bisa dibatalkan", "status": -1}, "12": {"message": "ERROR Tidak bisa dibatalkan", "status": -1, "code": 68},
"13": {"message": "ERROR Nilai Transaksi tidak valid", "status": -3}, "13": {"message": "ERROR Nilai Transaksi tidak valid", "status": -3, "code": 99},
"14": {"message": "ERROR ID Tidak Terdaftar", "status": -3}, "17": {"message": "ERROR ID Punya Tunggakan", "status": -3, "code": 99},
"15": {"message": "ERROR No Meter Tidak Terdaftar", "status": -3},
"16": {"message": "ERROR PRR SUBSCRIBER", "status": -3}, "88": {"message": "ERROR Tagihan sudah dibayar", "status": -3, "code": 54},
"17": {"message": "ERROR ID Punya Tunggakan", "status": -3}, "89": {"message": "ERROR Tagihan tidak tersedia", "status": -3, "code": 55},
"18": {"message": "ERROR Permintaan Sedang diproses", "status": -1},
"26": {"message": "Quota Transaksi Agen Tidak Mencukupi. Silahkan Kontak Agen.", "status": -2}, "14": {"message": "ERROR ID Tidak Terdaftar", "status": -3, "code": 55},
"29": {"message": "ERROR Kode Hash tidak valid", "status": -2}, "15": {"message": "ERROR No Meter Tidak Terdaftar", "status": -3, "code": 55},
"30": {"message": "ERROR Pesan tidak valid", "status": -2}, "33": {"message": "ERROR Produk tidak terdaftar", "status": -3, "code": 55},
"31": {"message": "ERROR Kode Bank tidak terdaftar", "status": -2}, "31": {"message": "ERROR Kode Bank tidak terdaftar", "status": -3, "code": 55},
"32": {"message": "ERROR Sentral tidak terdaftar", "status": -2}, "32": {"message": "ERROR Sentral tidak terdaftar", "status": -3, "code": 55},
"33": {"message": "ERROR Produk tidak terdaftar", "status": -2}, "16": {"message": "ERROR PRR SUBSCRIBER", "status": -3, "code": 55},
"34": {"message": "ERROR PPID Tidak terdaftar", "status": -2}, "34": {"message": "ERROR PPID Tidak terdaftar", "status": -3, "code": 55},
"35": {"message": "ERROR Akun Tidak Terdaftar", "status": -2}, "35": {"message": "ERROR Akun Tidak Terdaftar", "status": -3, "code": 55},
"41": {"message": "ERROR Nilai Transaksi dibawah Nilai Minimum", "status": -2}, "53": {"message": "ERROR Produk tidak ditemukan", "status": -3, "code": 55},
"42": {"message": "ERROR Nilai Transaksi diatas Nilai Maximum", "status": -2}, "56": {"message": "ERROR Nomor Telpon Tidak diketahui", "status": -3, "code": 55},
"43": {"message": "ERROR Daya Baru Lebih Kecil dari Daya Sekarang", "status": -3},
"44": {"message": "ERROR Nilai Daya Tidak Valid", "status": -3},
"45": {"message": "ERROR Nilai Biaya Administrasi Tidak Valid", "status": -3},
"46": {"message": "ERROR Deposit Tidak Mencukupi", "status": -2},
"47": {"message": "ERROR Diluar Batas KWH", "status": -3},
"48": {"message": "ERROR Permintaan sudah kadaluarsa", "status": -3},
"51": {"message": "ERROR Transaksi Gagal dari Mesin Vending", "status": -3},
"52": {"message": "ERROR Transaksi dipending dari Mesin Vending", "status": -1},
"53": {"message": "ERROR Produk tidak ditemukan", "status": -1},
"54": {"message": "ERROR Jawaban dari Biller Tidak ditemukan", "status": -3},
"55": {"message": "ERROR Lainnya Mesin Vending", "status": -2},
"56": {"message": "ERROR Nomor Telpon Tidak diketahui", "status": -3},
"63": {"message": "ERROR Tidak ada Pembayaran", "status": -1},
"60": {"message": "ERROR Akun sudah didaftarkan", "status": -3},
"67": {"message": "ERROR CANNOT CONNECT", "status": -3},
"68": {"message": "ERROR Timeout", "status": -2},
"69": {"message": "ERROR Sertifikat tidak dikenal", "status": -2},
"70": {"message": "ERROR Timeout tidak refund", "status": -1},
"72": {"message": "ERROR Permintaan tidak mungkin dilayani", "status": -2},
"73": {"message": "ERROR Request dipending di Biller", "status": -1},
"77": {"message": "ERROR Id di suspend", "status": -2},
"88": {"message": "ERROR Tagihan sudah dibayar", "status": -3},
"89": {"message": "ERROR Tagihan tidak tersedia", "status": -3},
"90": {"message": "ERROR sedang proses CUT OFF", "status": -1},
"91": {"message": "ERROR Database", "status": -1},
"92": {"message": "ERROR Nomor Referensi Switching tidak ditemukan", "status": -2},
"93": {"message": "ERROR Nomor Referensi Switching tidak valid", "status": -2},
"94": {"message": "ERROR Pembatalan sudah dilakukan", "status": -3},
"95": {"message": "ERROR Kode Merchant tidak terdaftar", "status": -2},
"96": {"message": "ERROR Transaksi tidak ditemukan", "status": -3},
"97": {"message": "ERROR SW BANK Tidak identik", "status": -2},
"98": {"message": "ERROR Nomor Referensi Switching tidak valid", "status": -2},
"146": {"message": "ERROR di servis deposit", "status": -1},
"500": {"message": "ERROR Other Error", "status": -1},
"400": {"message": "ERROR Other Error", "status": -1},
"999": {"message": "ERROR Other Error", "status": -1},
}
"18": {"message": "ERROR Permintaan Sedang diproses", "status": -1, "code": 68},
"26": {"message": "Quota Transaksi Agen Tidak Mencukupi. Silahkan Kontak Agen.", "status": 0, "code": 68},
"29": {"message": "ERROR Kode Hash tidak valid", "status": -2, "code": 68},
"30": {"message": "ERROR Pesan tidak valid", "status": -2, "code": 68},
"46": {"message": "ERROR Deposit Tidak Mencukupi", "status": -2, "code": 68},
"52": {"message": "ERROR Transaksi dipending dari Mesin Vending", "status": -1, "code": 68 },
"68": {"message": "ERROR Timeout", "status": -1, "code": 68 },
"70": {"message": "ERROR Timeout tidak refund", "status": -1, "code": 68},
"73": {"message": "ERROR Request dipending di Biller", "status": -1, "code": 68},
"51": {"message": "ERROR Transaksi Gagal dari Mesin Vending", "status": -3, "code": 99},
"41": {"message": "ERROR Nilai Transaksi dibawah Nilai Minimum", "status": -3, "code": 99},
"42": {"message": "ERROR Nilai Transaksi diatas Nilai Maximum", "status": -3, "code": 99},
"43": {"message": "ERROR Daya Baru Lebih Kecil dari Daya Sekarang", "status": -3, "code": 99},
"44": {"message": "ERROR Nilai Daya Tidak Valid", "status": -3, "code": 99},
"45": {"message": "ERROR Nilai Biaya Administrasi Tidak Valid", "status": -3, "code": 99},
"47": {"message": "ERROR Diluar Batas KWH", "status": -3, "code": 99},
"48": {"message": "ERROR Permintaan sudah kadaluarsa", "status": -3, "code": 99},
"54": {"message": "ERROR Jawaban dari Biller Tidak ditemukan", "status": -3, "code": 99},
"55": {"message": "ERROR Lainnya Mesin Vending", "status": -3, "code": 99},
"63": {"message": "ERROR Tidak ada Pembayaran", "status": -3, "code": 99},
"60": {"message": "ERROR Akun sudah didaftarkan", "status": -3, "code": 99},
"67": {"message": "ERROR CANNOT CONNECT", "status": -3, "code": 99},
"69": {"message": "ERROR Sertifikat tidak dikenal", "status": -3, "code": 99},
"72": {"message": "ERROR Permintaan tidak mungkin dilayani", "status": -3, "code": 99},
"77": {"message": "ERROR Id di suspend", "status": -2, "code": 68},
"90": {"message": "ERROR sedang proses CUT OFF", "status": -3, "code": 99},
"91": {"message": "ERROR Database", "status": -3, "code": 99},
"92": {"message": "ERROR Nomor Referensi Switching tidak ditemukan", "status": -3, "code": 99},
"93": {"message": "ERROR Nomor Referensi Switching tidak valid", "status": -3, "code": 99},
"94": {"message": "ERROR Pembatalan sudah dilakukan", "status": -3, "code": 99},
"95": {"message": "ERROR Kode Merchant tidak terdaftar", "status": -3, "code": 99},
"96": {"message": "ERROR Transaksi tidak ditemukan", "status": -3, "code": 99},
"97": {"message": "ERROR SW BANK Tidak identik", "status": -3, "code": 99},
"98": {"message": "ERROR Nomor Referensi Switching tidak valid", "status": -3, "code": 99},
"146": {"message": "ERROR di servis deposit", "status": -3, "code": 99},
"500": {"message": "ERROR Other Error", "status": -2, "code": 68},
"400": {"message": "ERROR Other Error", "status": -2, "code": 68},
"999": {"message": "ERROR Other Error", "status": -2, "code": 68},
}
from ..vendor import VendorClass
class Vendor(VendorClass): class Vendor(VendorClass):
def __init__(self, vendor_produk, invoice_det, **kwargs): def __init__(self, vendor_produk, invoice_det, **kwargs):
......
...@@ -6,7 +6,6 @@ from opensipkd.base.tools import log ...@@ -6,7 +6,6 @@ from opensipkd.base.tools import log
class Vendor(VendorClass): class Vendor(VendorClass):
def pars_data(self, data): def pars_data(self, data):
product_id = self.invoice_det.produk.id product_id = self.invoice_det.produk.id
partner_id = self.invoice_det.h2h_ar_invoice.customer_id partner_id = self.invoice_det.h2h_ar_invoice.customer_id
...@@ -38,49 +37,7 @@ class Vendor(VendorClass): ...@@ -38,49 +37,7 @@ class Vendor(VendorClass):
else: else:
message = "PENDING" message = "PENDING"
meter = "startend" in data and data["startend"] or "" meter = "startend" in data and data["startend"] or ""
"""
<?xml version="1.0"?>
<root>
<status>SUCCESS</status>
<rc>0000</rc>
<rcm>[0] Cek Tagihan Sukses ke:51110000100 refnum:BE1D2979288141D595C19C2A2A8ADAA4</rcm>
<text>51110000100
Dmmy'Smltor.Name-511
1 BLN
AGU17
RP TAG PDAM RP 270.100
ADM RP 1.600
TOTAL RP 271.700
</text>
<refnum>BE1D2979288141D595C19C2A2A8ADAA4</refnum>
<idpel>51110000100</idpel>
<name>Dmmy'Smltor.Name51110000100</name>
<totalperiod>1 BLN</totalperiod>
<billperiod>AGU17</billperiod>
<admincharge>1600</admincharge>
<transamount>271700</transamount>
</root>
"""
"""
{
"data": [{
"nopel": "636289",
"nama": "SUBCRIBER NAME",
"refno": "25641544",
"rincian":{
"pokok": 68000,
"denda": 0,
"admin": 2500,
"period": "2016-07",
"jml_bulan": 1,
"meter": "140-162"
},
"subtotal": 70500,
"discount": 600,
"total": 69900
}]
"""
return { return {
"code": code, "code": code,
"status": message, "status": message,
...@@ -92,7 +49,7 @@ class Vendor(VendorClass): ...@@ -92,7 +49,7 @@ class Vendor(VendorClass):
"pokok": pokok, "pokok": pokok,
"denda": 0, "denda": 0,
"admin": admin, "admin": admin,
"periode": "billperiod" in data and data["billperiod"] or "", "period": "billperiod" in data and data["billperiod"] or "",
"jml_bulan": bulan, "jml_bulan": bulan,
# "tarif": "tarifdaya" in data and data["tarifdaya"] or "", # "tarif": "tarifdaya" in data and data["tarifdaya"] or "",
# "no_meter": "msn" in data and data["msn"] or "", # "no_meter": "msn" in data and data["msn"] or "",
...@@ -114,35 +71,26 @@ class Vendor(VendorClass): ...@@ -114,35 +71,26 @@ class Vendor(VendorClass):
params = self.get_params(cmd='INQ', modul='PDAM') params = self.get_params(cmd='INQ', modul='PDAM')
params["idpel"] = self.id_pel params["idpel"] = self.id_pel
params["biller"] = self.vendor_produk.kode params["biller"] = self.vendor_produk.kode
params['trxid'] = self.invoice_det.id
self.request = params self.request = params
self.save_log('inquiry') self.save_log('inquiry')
params['trxid'] = self.invoice_det.id log.info("Inquiry Request: %s", params)
log.info("Request: %s", params)
try: try:
resp = requests.get(self.url, params=params, timeout=15) resp = requests.get(self.url, params=params, timeout=15)
except requests.exceptions.RequestException as e: if resp and resp.ok:
data = dict(message = e.strerror, data = dict(xmltodict.parse(resp.text)["root"])
code = e.errno) self.response = data
return self.save_response(data) log.info("Inquiry Response: %s", data)
data = self.pars_data(data)
if resp and resp.ok: if data:
data = dict(xmltodict.parse(resp.text)["root"]) self.set_success(data, typ="inquiry")
log.info("Response: %s", data) except:
data = self.pars_data(data) return self.set_failed(typ="inquiry")
elif resp:
data = dict(message=resp.text,
code=resp.status_code)
else:
data = dict(message="No Response From Biller ",
code=500)
return self.save_response(data)
return self.save_response(data) return self.set_failed(typ="inquiry")
def payment(self): def payment(self):
params = self.get_params(cmd='PAY', modul='PDAM') params = self.get_params(cmd='PAY', modul='PDAM')
params["idpel"] = self.id_pel params["idpel"] = self.id_pel
self.request = params self.request = params
self.save_log('payment') self.save_log('payment')
...@@ -150,6 +98,9 @@ class Vendor(VendorClass): ...@@ -150,6 +98,9 @@ class Vendor(VendorClass):
resp = requests.get(self.url, params=params, timeout=15) resp = requests.get(self.url, params=params, timeout=15)
if resp.ok: if resp.ok:
data = dict(xmltodict.parse(resp.text)["root"]) data = dict(xmltodict.parse(resp.text)["root"])
self.response = data
data = self.pars_data(data)
return self.set_success(data)
else: else:
data = dict(code=resp.status_code, data = dict(code=resp.status_code,
message=resp.text) message=resp.text)
...@@ -157,11 +108,7 @@ class Vendor(VendorClass): ...@@ -157,11 +108,7 @@ class Vendor(VendorClass):
data = dict(code=500, data = dict(code=500,
message="No Response From Biller") message="No Response From Biller")
self.response = data return self.set_failed(data)
data = self.pars_data(data)
self.save_log('payment')
return data
def advice(self): def advice(self):
params = self.get_params(cmd='ADV', modul='pln') params = self.get_params(cmd='ADV', modul='pln')
......
...@@ -2,112 +2,29 @@ from opensipkd.pasar.models import PartnerProduk ...@@ -2,112 +2,29 @@ from opensipkd.pasar.models import PartnerProduk
import requests import requests
import xmltodict import xmltodict
from . import Vendor as VendorClass, vsi_status from . import Vendor as VendorClass, vsi_status
from opensipkd.base.tools import log import logging
log = logging.getLogger(__name__)
class Vendor(VendorClass): class Vendor(VendorClass):
def pars_data(self, data): def pars_data(self, data):
pokok = int(data["tagihan"])
""" self.amt_buy = int(data["total"])
<?xml version="1.0"?> tarif = "tarif" in data and data["tarif"] or ""
<root> p = tarif.split("/")
<status>SUCCESS</status> power = len(p)>1 and p[1] or ""
<rc>0000</rc>
<rcm>[0] CEK TAGIHAN SUKSES ke:532110000060 refnum:33ECE3543E62474AA0C6C3147D94A31D</rcm>
<text>532110000060
DU'MMY-VSI-532110000
1 BLN
JUN16
RP TAG PLN RP 887.817
ADM RP 1.600
TOTAL RP 890.929
</text>
<refnum>33ECE3543E62474AA0C6C3147D94A31D</refnum>
<idpel>532110000060</idpel>
<nama>DU'MMY-VSI-532110000060</nama>
<bulan>1 BLN</bulan>
<blntagihan>JUN16</blntagihan>
<admin>1600</admin>
<tagihan>889329</tagihan>
<total>890929</total>
</root>
"""
"""
<?xml version="1.0"?>
<root>
<status>SUCCESS</status>
<rc>0000</rc>
<rcm>[0] PEMBAYARAN SUKSES ke:532110000060 refnum:0506213515100D3399B27293E3DBC535</rcm>
<text>22/06/16 14:29
0506213515100D3399B27293E3DBC535
532110000060
3
DU'MMY-VSI-532110000
R1/450
BLN JUN16
RP 887.729
ADM RP 1.600
TOTAL RP 890.929
SUKSES</text>
<date>2016-06-22 14:29:25</date>
<refnum>0506213515100D3399B27293E3DBC535</refnum>
<idpel>532110000060</idpel>
<nama>DU'MMY-VSI-532110000060</nama>
<segmenpower>R1/450</segmenpower>
<startend>888800-889900</startend>
<blntagihan>JUN16</blntagihan>
<ppn>0</ppn>
<denda>0</denda>
<totaltagihanpln>887729</totaltagihanpln>
<admin>1600</admin>
<total>890929</total>
<info1>Informasi Hubungi Call Center: 123 Atau Hub. PLN Terdekat:</info1>
<info2>Terima Kasih</info2>
</root>
"""
power = "segmenpower" in data and data["segmenpower"].split("/") or [""]
power = len(power)>1 and power[-1:][0] or power[0]
product_id = self.invoice_det.produk.id product_id = self.invoice_det.produk.id
if hasattr(self.invoice_det,'customer_id'): if hasattr(self.invoice_det,'customer_id'):
customer_id = self.invoice_det.customer_id customer_id = self.invoice_det.customer_id
else: else:
customer_id = self.invoice_det.h2h_ar_invoice.customer_id customer_id = self.invoice_det.h2h_ar_invoice.customer_id
discount = PartnerProduk.get_discount(customer_id, product_id) bulan = "bulan" in data and data["bulan"].split()[0] or 1
admin = self.vendor_produk.produk.harga bulan = bulan and int(bulan) or 1
harga = "nominal" in data and data["nominal"] or 0 discount = int(PartnerProduk.get_discount(customer_id, product_id) * bulan)
subtotal = harga + admin admin = int(self.vendor_produk.produk.harga * bulan)
token = "token" in data and data["token"] or "" subtotal = pokok + admin
if "status" in data and data["status"] and data["status"] == "SUCCESS": meter = "standmeter" in data and data["standmeter"] or ""
self.status = 1
elif "status" in data and data["status"] and data["status"] == "ERROR":
self.status = -1
meter = "startend" in data and data["startend"] or ""
"""
{
"data": [{
"nopel": "530678910024",
"nama": "SUBCRIBER NAME",
"refno": "25641544",
"rincian":{
"pokok": 300000,
"denda": 0,
"admin": 2500,
"period": "2016-08",
"jml_bulan": 1,
"tarif": "R1\/1300VA",
"no_meter": "530678910012",
"meter": "567-756"
},
"subtotal": 302500,
"discount": 800,
"total": 301700
}]
"""
bulan = "bulan" in data and data["bulan"].split(" ")
bulan = bulan and bulan[0] or 0
if "rc" in data: if "rc" in data:
if data['rc']=='0000': if data['rc']=='0000':
code = 0 code = 0
...@@ -118,8 +35,27 @@ class Vendor(VendorClass): ...@@ -118,8 +35,27 @@ class Vendor(VendorClass):
# code = "rc" in data and data['rc']=='0000' and 0 or int(data["rc"]) or 500 # code = "rc" in data and data['rc']=='0000' and 0 or int(data["rc"]) or 500
if code == 0: if code == 0:
self.status = 1 return {
message = "SUCCESS" "code": 0,
"status": "SUCCESS",
"message": "rcm" in data and "Transaksi berhasil",
"nama": "nama" in data and data["nama"] or "NO-NAME",
"rincian": {
"pokok": pokok,
"denda": 0,
"admin": admin,
"total": subtotal,
"period": "blth" in data and data["blth"] or "",
"jml_bulan": bulan,
"tarif": tarif,
"no_meter": data["subid"] or "",
"power": power,
"meter": meter,
},
"subtotal": subtotal,
"discount": discount,
"total": subtotal - discount,
}
else: else:
self.status = vsi_status[str(code)]["status"] self.status = vsi_status[str(code)]["status"]
if self.status == -3: if self.status == -3:
...@@ -141,6 +77,7 @@ class Vendor(VendorClass): ...@@ -141,6 +77,7 @@ class Vendor(VendorClass):
"pokok": "tagihan" in data and int(data["tagihan"]) or 0, "pokok": "tagihan" in data and int(data["tagihan"]) or 0,
"denda": "denda" in data and int(data["denda"]) or 0, "denda": "denda" in data and int(data["denda"]) or 0,
"admin": admin, "admin": admin,
"total": subtotal,
"periode": "blntagihan" in data and data["blntagihan"] or "", "periode": "blntagihan" in data and data["blntagihan"] or "",
"jml_bulan": bulan, "jml_bulan": bulan,
"tarif": "tarifdaya" in data and data["tarifdaya"] or "", "tarif": "tarifdaya" in data and data["tarifdaya"] or "",
...@@ -171,7 +108,7 @@ class Vendor(VendorClass): ...@@ -171,7 +108,7 @@ class Vendor(VendorClass):
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
data = dict(message = e.strerror, data = dict(message = e.strerror,
code = e.errno) code = e.errno)
return self.set_pending(data) return self.set_failed(data)
if resp and resp.ok: if resp and resp.ok:
data = dict(xmltodict.parse(resp.text)["root"]) data = dict(xmltodict.parse(resp.text)["root"])
...@@ -181,6 +118,7 @@ class Vendor(VendorClass): ...@@ -181,6 +118,7 @@ class Vendor(VendorClass):
return self.set_failed() return self.set_failed()
self.result = data self.result = data
log.info(data)
return self.set_success(data) return self.set_success(data)
elif resp: elif resp:
...@@ -204,15 +142,15 @@ class Vendor(VendorClass): ...@@ -204,15 +142,15 @@ class Vendor(VendorClass):
# todo: apakah harus di cek dulu data inquirynya # todo: apakah harus di cek dulu data inquirynya
self.save_log('payment') self.save_log('payment')
params['trxid'] = self.invoice_det.id params['trxid'] = self.invoice_det.id
resp = requests.get(self.url, params=params, timeout=15)
try: try:
resp = requests.get(self.url, params=params, timeout=15)
if resp.ok: if resp.ok:
data = dict(xmltodict.parse(resp.text)["root"]) data = dict(xmltodict.parse(resp.text)["root"])
else: else:
data = dict(code=resp.status_code, data = dict(code=resp.status_code,
message=resp.text) message=resp.text)
self.response = data self.response = data
log.info("VSI Payment Result: {}".format(self.response))
# except requests.exceptions.Timeout as errt: # except requests.exceptions.Timeout as errt:
# message = "Biller Timeout Transaksi will be retry" # message = "Biller Timeout Transaksi will be retry"
# self.status = -1 # self.status = -1
...@@ -228,8 +166,8 @@ class Vendor(VendorClass): ...@@ -228,8 +166,8 @@ class Vendor(VendorClass):
log.info("Payment Response: %s" % (self.response)) log.info("Payment Response: %s" % (self.response))
return self.set_pending() return self.set_pending()
self.amt_buy = "harga" in data and data["harga"] or self.amt_buy #self.amt_buy = "harga" in data and data["harga"] or self.amt_buy
self.vend_inv_no = "ref_num" in data and data["ref_num"] or self.vend_inv_no self.vend_inv_no = str(self.invoice_det.id)
data = self.pars_data(self.response) data = self.pars_data(self.response)
return self.set_success(data) return self.set_success(data)
......
import re
from opensipkd.pasar.models import PartnerProduk from opensipkd.pasar.models import PartnerProduk
import requests import requests
import xmltodict import xmltodict
from . import Vendor as VendorClass, vsi_status from . import Vendor as VendorClass, vsi_status
from opensipkd.base.tools import log import logging
log = logging.getLogger(__name__)
class Vendor(VendorClass): class Vendor(VendorClass):
def pars_data(self, data): def pars_data(self, data):
""" """"""
<status>SUCCESS</status> tarif = "tarif" in data and data["tarif"] or ""
<rc>0000</rc> tarif = "tarifdaya" in data and data["tarifdaya"] or tarif
<rcm>[0] CEK TAGIHAN SUKSES ke:88888888888 refnum:D0EE65CAB0C04601878612867541EEA5</rcm> power = tarif.split("/") or [""]
<text>88888888888
TestDu''mmyP
R2/7000 VA
Token Unsold: 0
Adm 1.600,00
*Denom Belum Termasuk
Admin</text>
<refnum>D0EE65CAB0C04601878612867541EEA5</refnum>
<msn>88888888888</msn>
<idpel>885555555555</idpel>
<nama>TestDu''mmyPanjang8855555</nama>
<tarifdaya>R2/7000</tarifdaya>
<adm>1600</adm>
<jmltokenunsold>0</jmltokenunsold>
"""
"""
<status>SUCCESS</status>
<rc>0000</rc>
<rcm>[0] PEMBAYARAN SUKSES ke:88888888888 refnum:05062135116139A54A95CCC549DDA94C</rcm>
<text>08/06/16 11:50
05062135116139A54A95CCC549DDA94C
TestDu''mmyP
88888888888
881111111111
R2/6600 VA
RP 201.600
KWH352,0
STROOM/TOKEN 2593 0960 8106 1072 1376
ADM 1.600,00</text>
<tanggal>2016-06-08 11:50:22</tanggal>
<nama>TestDu''mmyPanjang8811111</nama>
<msn>88888888888</msn>
<idpel>881111111111</idpel>
<tarifdaya>R2/6600</tarifdaya>
<nominal>201600</nominal>
<jmlkwh>352</jmlkwh>
<token>2593-0960-8106-1072-51376</token>
<ppn>0</ppn>
<ppj>0</ppj>
<adm>1600</adm>
<angsuran>24000</angsuran>
<materai>0</materai>
"""
power = "tarifdaya" in data and data["tarifdaya"].split("/") or [""]
power = len(power)>1 and power[-1:][0] or power[0] power = len(power)>1 and power[-1:][0] or power[0]
product_id = self.invoice_det.produk.id product_id = self.invoice_det.produk.id
if hasattr(self.invoice_det,"customer_id"): if hasattr(self.invoice_det,"customer_id"):
...@@ -65,9 +23,9 @@ class Vendor(VendorClass): ...@@ -65,9 +23,9 @@ class Vendor(VendorClass):
discount = PartnerProduk.get_discount(partner_id, product_id) discount = PartnerProduk.get_discount(partner_id, product_id)
admin = int(self.vendor_produk.produk.harga) admin = int(self.vendor_produk.produk.harga)
harga = int(self.v_produk_kd) nominal = "nominal" in data and data["nominal"] and int(data["nominal"]) or 0
harga = nominal and int(re.sub("\D","",self.v_produk_kd))*1000 or 0
subtotal = harga + admin subtotal = harga + admin
token = "token" in data and data["token"] or ""
if "status" in data and data["status"] and data["status"] == "SUCCESS": if "status" in data and data["status"] and data["status"] == "SUCCESS":
self.status = 1 self.status = 1
...@@ -82,8 +40,6 @@ class Vendor(VendorClass): ...@@ -82,8 +40,6 @@ class Vendor(VendorClass):
else: else:
code = 500 code = 500
# code = "rc" in data and data['rc']=='0000' and 0 or int(data["rc"]) or 500
log.info("VSI Result Code: {} {}".format(code, data))
if code == 0: if code == 0:
self.status = 1 self.status = 1
message="SUCCESS" message="SUCCESS"
...@@ -95,29 +51,30 @@ class Vendor(VendorClass): ...@@ -95,29 +51,30 @@ class Vendor(VendorClass):
message = "PENDING" message = "PENDING"
return dict(code=code, return dict(code=code,
message=message) message=message)
self.vend_inv_no = str(self.invoice_det.id)
return { result = {
"code": code, "code": code,
"status": message, "status": message,
"message": "rcm" in data and "Transaksi %s" % message or "No Response From Biller", "message": "rcm" in data and "Transaksi %s" % message or "No Response From Biller",
"refno": "refnum" in data and data["refnum"] or "", "refno": "refnum" in data and data["refnum"] or "",
"nopel": "idpel" in data and data["idpel"] or self.id_pel, "nopel": "idpel" in data and data["idpel"] or self.id_pel,
"nama": "nama" in data and data["nama"] or "NO-NAME", "nama": "nama" in data and data["nama"] or "NO-NAME",
"rincian":{ "rincian": {
"pokok": int(self.v_produk_kd), "pokok": harga,
"denda": "denda" in data and int(data["denda"]) or 0, "denda": "denda" in data and int(data["denda"]) or 0,
"admin": admin, "admin": admin,
"tarif": "tarifdaya" in data and data["tarifdaya"] or "", "tarif": tarif,
# "ppn": "ppn" in data and data["ppn"] or 0, # "ppn": "ppn" in data and data["ppn"] or 0,
# "ref_no": "refnum" in data and data["refnum"] or "", # "ref_no": "refnum" in data and data["refnum"] or "",
"no_meter": "msn" in data and data["msn"] or "", "no_meter": "msn" in data and data["msn"] or "",
"power": power, "power": power,
"token": token, "total": subtotal,
"token": "token" in data and data["token"] or ""
}, },
"subtotal": subtotal,
"discount": discount, "discount": discount,
"total": subtotal-discount,
} }
return result
def save_result(self, data, typ="inquiry"): def save_result(self, data, typ="inquiry"):
self.result = data self.result = data
...@@ -128,7 +85,8 @@ class Vendor(VendorClass): ...@@ -128,7 +85,8 @@ class Vendor(VendorClass):
def inquiry(self): def inquiry(self):
params = self.get_params(cmd='INQ', modul='PRE') params = self.get_params(cmd='INQ', modul='PRE')
params["msn"] = self.id_pel params["msn"] = self.id_pel
params["nominal"] = self.v_produk_kd nominal = int(re.sub("\D","",self.v_produk_kd))*1000
params["nominal"] = nominal
self.request = params self.request = params
self.save_log('inquiry') self.save_log('inquiry')
params['trxid'] = self.invoice_det.id params['trxid'] = self.invoice_det.id
...@@ -136,6 +94,7 @@ class Vendor(VendorClass): ...@@ -136,6 +94,7 @@ class Vendor(VendorClass):
try: try:
resp = requests.get(self.url, params=params, timeout=15) resp = requests.get(self.url, params=params, timeout=15)
if resp and resp.ok: if resp and resp.ok:
log.info("XML Response: %s" % resp.text)
data = dict(xmltodict.parse(resp.text)["root"]) data = dict(xmltodict.parse(resp.text)["root"])
self.response = data self.response = data
...@@ -143,7 +102,7 @@ class Vendor(VendorClass): ...@@ -143,7 +102,7 @@ class Vendor(VendorClass):
data = dict(message=resp.text, data = dict(message=resp.text,
code=resp.status_code) code=resp.status_code)
self.response = data self.response = data
log.info("Response: %s" % data ) log.info("Response as JSON: %s" % data )
except requests.exceptions.RequestException as e: except requests.exceptions.RequestException as e:
data = dict(message = e.strerror, data = dict(message = e.strerror,
code = e.errno) code = e.errno)
...@@ -159,7 +118,8 @@ class Vendor(VendorClass): ...@@ -159,7 +118,8 @@ class Vendor(VendorClass):
def payment(self): def payment(self):
params = self.get_params(cmd='PAY', modul='PRE') params = self.get_params(cmd='PAY', modul='PRE')
params["msn"] = self.id_pel params["msn"] = self.id_pel
params["nominal"] = self.v_produk_kd nominal = int(re.sub("\D", "", self.v_produk_kd)) * 1000
params["nominal"] = nominal
self.request = params self.request = params
# todo: apakah harus di cek dulu data inquirynya # todo: apakah harus di cek dulu data inquirynya
self.save_log('payment') self.save_log('payment')
...@@ -188,7 +148,8 @@ class Vendor(VendorClass): ...@@ -188,7 +148,8 @@ class Vendor(VendorClass):
def advice(self): def advice(self):
params = self.get_params(cmd='ADV', modul='PRE') params = self.get_params(cmd='ADV', modul='PRE')
params["msn"] = self.id_pel params["msn"] = self.id_pel
params["nominal"] = self.v_produk_kd nominal = int(re.sub("\D", "", self.v_produk_kd)) * 1000
params["nominal"] = nominal
self.request = params self.request = params
# todo: apakah harus di cek dulu data inquirynya # todo: apakah harus di cek dulu data inquirynya
......
...@@ -10,81 +10,60 @@ log = logging.getLogger(__name__) ...@@ -10,81 +10,60 @@ log = logging.getLogger(__name__)
# todo: result harus distandarisasi # todo: result harus distandarisasi
class Vendor(VendorClass): class Vendor(VendorClass):
def pars_data(self, data): def pars_data(self, data):
""" if "rc" in data:
<status>SUCCESS</status> if data["rc"]=="0000":
<rc>0000</rc> code = 0
<rcm>0000</rcm> else:
<text>[0] Pembayaran Sukses</text> code = int(data["rc"])
<date>Isi pulsa TN10 berhasil untuk nomor 628527778889 sebesar 10.000, refnum F148919BB5F4093A0F40000000000000 pada tgl 17/04/17 15:32</date> else:
<refnum>2017-04-17 15:40:28</refnum> code = -1
<voucherid>4A61D574138A2D6B4B6 </voucherid> if code == 0: # sukses
<destnum>TN10</destnum>
<nominal>10000</nominal>
<serial>4A61D574138A2D6B4B6 </serial>
:return:
"""
code = "rc" in data and int(data["rc"]) or 0
self.status = code and vsi_status[str(code)]["status"] or 1
status = self.status == -3 and "FAILED" or "PENDING"
if status == "PENDING":
code = 68
if self.status>-3:
product_id = self.invoice_det.produk.id product_id = self.invoice_det.produk.id
partner_id = self.invoice_det.h2h_ar_invoice.customer_id partner_id = self.invoice_det.h2h_ar_invoice.customer_id
discount = PartnerProduk.get_discount(partner_id, product_id) self.discount = int(PartnerProduk.get_discount(partner_id, product_id))
harga = self.vendor_produk.produk.harga harga = int(self.vendor_produk.produk.harga)
self.status = 1 self.amt_buy = data["harga"]
status = "status" in data and data["status"] or "" self.amt_sell = harga - self.discount
if not harga: result = dict(
raise JsonRpcError() serial_number="serialnumber" in data and data["serialnumber"] or "",
subtotal=self.amt_sell,
discount=self.discount,
total=self.amt_sell)
return result
else: else:
discount = 0 self.status = code and vsi_status[str(code)]["status"] or 1
harga = 0 status = self.status == -3 and "FAILED" or "PENDING"
if status == "PENDING":
code = 68
if self.status>-3:
harga = self.vendor_produk.produk.harga
self.status = 1
status = "status" in data and data["status"] or ""
if not harga:
raise JsonRpcError()
else:
discount = 0
harga = 0
result = dict( result = dict(
status=status, status=status,
code=code, code=code,
message="rcm" in data \ message="rcm" in data\
and (data["rcm"] == "00000" and "SUCCESS" or data["rcm"]) \ and (data["rcm"] == "00000" and "SUCCESS" or data["rcm"])\
or status, or status,
serial_number="serialnumber" in data and data["serialnumber"] or "", serial_number="serialnumber" in data and data["serialnumber"] or "",
subtotal=int(harga), subtotal=int(harga),
discount=int(discount), discount=int(discount),
total = int(harga-discount) total=int(harga-discount)
) )
return result return result
# def inquiry(self):
# params = self.get_params(cmd='INQ', modul='ISI')
# params["tujuan"] = self.id_pel
# params["voucherid"] = self.vendor_produk.kode
# self.request = params
# self.save_log('inquiry')
# log.info("Request: %s %s" % (self.url, self.request))
# try:
# result = requests.get(self.url, params=params, timeout=15)
# if result.ok:
# data = dict(xmltodict.parse(result.text)["root"])
# else:
# data = dict(code=result.status_code,
# message=result.text)
# self.response = data
# log.info("Response: %s" % (data))
#
# except requests.exceptions.RequestException as e:
# data = dict(code=e.errno,
# message=e.strerror)
#
# self.result = self.pars_data(data)
# log.info("Result: %s" % (self.result))
# self.save_log('inquiry')
# return self.result
#
def payment(self): def payment(self):
params = self.get_params(cmd='PAY', modul='ISI') params = self.get_params(cmd='PAY', modul='ISI')
params["tujuan"] = self.id_pel params["tujuan"] = self.id_pel
params["voucherid"] = self.vendor_produk.kode params["voucherid"] = self.vendor_produk.kode
self.request = params self.request = params
log.info("Payment Request: %s" % (params)) log.info("Payment Request: %s" % (params))
data = self.get_price() data = self.get_price()
...@@ -98,16 +77,7 @@ class Vendor(VendorClass): ...@@ -98,16 +77,7 @@ class Vendor(VendorClass):
self.response = dict(code=result.status_code, message=result.text) self.response = dict(code=result.status_code, message=result.text)
log.info("Payment Response: %s" % (self.response)) log.info("Payment Response: %s" % (self.response))
return self.set_pending(data, message=result.text) return self.set_pending(data, message=result.text)
# except requests.exceptions.HTTPError as errh:
# message = "Http Error:"
# self.status = -2
# return self.set_pending(data, message=message)
#
# except requests.exceptions.ConnectionError as errc:
# message = "Error Connecting:"
# self.status = -2
# return self.set_pending(data, message=message)
#
except requests.exceptions.Timeout as errt: except requests.exceptions.Timeout as errt:
message = "Biller Timeout Transaksi will be retry" message = "Biller Timeout Transaksi will be retry"
self.status = -1 self.status = -1
...@@ -117,8 +87,8 @@ class Vendor(VendorClass): ...@@ -117,8 +87,8 @@ class Vendor(VendorClass):
self.status = -2 self.status = -2
return self.set_pending(data, message=message) return self.set_pending(data, message=message)
self.amt_buy = "harga" in data and data["harga"] or self.amt_buy # self.amt_buy = "harga" in data and data["harga"] or self.amt_buy
self.vend_inv_no = "ref_num" in data and data["ref_num"] or self.vend_inv_no self.vend_inv_no = str(self.invoice_det.id)
data = self.pars_data(self.response) data = self.pars_data(self.response)
return self.set_success(data) return self.set_success(data)
......
import base64
from datetime import datetime
from opensipkd.base.tools import ymdhms, dmyhms
from pyramid.view import view_config
import logging
log = logging.getLogger(__name__)
"""
odeo-purchase http://server/api/odeo/prepaid/purchase
"""
def validate_header(request, data):
# env = request.environ
# #http_header = env["HTTP_HEADER"]
# # log.info(env)
# if 'HTTP_AUTHORIZATION' not in env:
# log.info("HTTP_AUTHORIZATION tidak ditemukan")
# return
#
# auth = env['HTTP_AUTHORIZATION'].split()
# log.info(auth)
# if len(auth)<2 or auth[0] != "Bearer":
# log.info('Error Auth')
# return
#
# key = ":".join(['agratek', '4444444']).encode()
# key_encoded = base64.b64encode(key).decode()
# log.info(key_encoded)
# if auth[1]!= key_encoded:
# return
hash_string = "".join([self.mid, tanggal, self.key])
self.auth = hashlib.sha256(hash_string.encode()).hexdigest()
return True
def anauthorized(request):
request.response.status = 401
result = {
"status": "UNAUTHORIZED",
"data": {
"errors": [
"Unauthorized"
]
},
"message": ""
}
return result
def bad_request(request, message=None):
if not message:
message = "Paramter(s) Expected"
request.response.status = 400
result = {
"status": "BAD_REQUEST",
"data": {
"errors": [
"ERROR_MESSAGE_1",
"ERROR_MESSAGE_2",
"ERROR_MESSAGE_ETC"
]
},
"message": message
}
return result
def pulsa_result(request, params):
"""
:param request:
:param params:
cid={CLIENT_ID}
dt={DATE}
hc={HASHCODE}
modul=ISI
command=INQ
tujuan=nomor
voucherid={VOUCHERID}
trxid={TRXID}
resp=XML
:return:
"""
s = datetime.now()
tanggal = ymdhms(s)
tanggal2 = dmyhms(s)
result = """<?xml version="1.0" encoding="UTF-8"?>
<root>
<harga>5825</harga>
<nominal>5000</nominal>
<nomor>{tujuan}</nomor>
<rc>0000</rc>
<rcm>[0] Pembayaran Sukses ke:{tujuan}</rcm>
<refnum>2A076C6A1D6CB5E63E60000000000000</refnum>
<serialnumber>4A61D574138A2D6B4B6</serialnumber>
<status>SUCCESS</status>
<tanggal>{tanggal}</tanggal>
<text>Isi pulsa TN5 berhasil untuk nomor {tujuan} sebesar 5.000, refnum 2A076C6A1D6CB5E63E60000000000000 pada
tgl {tanggal2}</text>
<trxid>{trxid}</trxid>
<voucherid>{voucherid}</voucherid>
</root>
""".format(tujuan=params["tujuan"], tanggal=tanggal, tanggal2=tanggal2,
voucherid=params["voucherid"], trxid=params["trxid"])
request.response.text = result
return request.response
def pulsa_produk_not_found(request, params):
tanggal = datetime.now().strftime("%d-%m-%y %H:%M:%S")
result = """
<root>
<nomor>{tujuan}</nomor>
<rc>0033</rc>
<rcm>[33] Produk Tidak Terdaftar</rcm>
<status>FAILED</status>
<tanggal>{tanggal}</tanggal>
<text>Produk Tidak Terdaftar</text>
<trxid>{trxid}</trxid>
<voucherid>{voucherid}</voucherid>
</root>
""".format(tujuan=params["tujuan"], tanggal=tanggal, trxid=params["trxid"],
voucherid=params["voucherid"])
request.response.text = result
return request.response
def plnpre_inq_result(request, params):
"""
:param request:
:param params:
{'nominal': '20000',
'command': 'INQ',
'msn': '77777777777',
'cid': 'agratek8293-11e6-8325-002207194ks3s',
'hc': '5be201353753e353f5208741b3ace4a07773921183d241b65807a7a314bfbfce',
'trxid': 329,
'modul': 'PRE',
'resp': 'XML',
'dt': '20190901'}
:return:
"""
result = """<?xml version="1.0" encoding="UTF-8"?>
<root>
<admin>1600</admin>
<denomunsold></denomunsold>
<msn>{msn}</msn>
<nama>TestDu''mmy&amp;Panjang773333</nama>
<rc>0000</rc>
<rcm>[0] CEK TAGIHAN SUKSES ke:{msn} refnum:F59D2CA7352C4552BD318D15C31D6DA5</rcm>
<refnum>F59D2CA7352C4552BD318D15C31D6DA5</refnum>
<status>SUCCESS</status>
<subid>773333333333</subid>
<tarif>R3/6600</tarif>
<text>77777777777
TestDu''mmy&amp;
R3/6600 VA
Token Unsold: 0
Adm 1.600,00
*Denom Belum Termasuk Admin</text>
<trxid>{trxid}</trxid>
<unsold>0</unsold>
</root>
""".format(msn=params["msn"], trxid=params["trxid"])
request.response.text = result
return request.response
def plnpre_pay_result(request, params):
s = datetime.now()
tanggal = ymdhms(s)
tanggal2 = dmyhms(s)
result ="""<?xml version="1.0" encoding="UTF-8"?>
<root>
<admin>1600</admin>
<angsuran>2400</angsuran>
<idpel>776666666666</idpel>
<info>Informasi Hubungi Call Center 123 Atau hubungi PLN Terdekat</info>
<jmlkwh>35.2</jmlkwh>
<materai>0</materai>
<msn>{msn}</msn>
<nama>TestDu''mmy&amp;Panjang776666</nama>
<nominal>21600</nominal>
<ppj>0</ppj>
<ppn>0</ppn>
<rc>0000</rc>
<rcm>[0] PEMBAYARAN SUKSES ke:{msn} refnum:0BMS213515667BF970E3C2D532999FC7</rcm>
<rptoken>17600</rptoken>
<status>SUCCESS</status>
<tanggal>{tanggal}</tanggal>
<tarifdaya>R1/7000</tarifdaya>
<text>{tanggal2}
0BMS213515667BF970E3C2D532999FC7
TestDu''mmy&amp;
{msn}
776666666666
R1/7000 VA
RP 21.600
KWH35,2
STROOM/TOKEN 9536 6725 7956 8770 2361
ADM 1.600,00</text>
<token>9536-6725-7956-8770-2361</token>
<trxid>{trxid}</trxid>
</root>
""".format(msn=params["msn"], trxid=params["trxid"], tanggal=tanggal,
tanggal2=tanggal2)
request.response.text = result
return request.response
def pln_inq_result(request, params):
"""
:param request:
:param params:
{
'idpel': '532110000056',
'command': 'INQ',
'cid': 'agratek8293-11e6-8325-002207194ks3s',
'hc': '5be201353753e353f5208741b3ace4a07773921183d241b65807a7a314bfbfce',
'trxid': 332,
'modul': 'pln',
'resp': 'XML',
'dt': '20190901'
}
:return:
"""
result = """<?xml version="1.0" encoding="UTF-8"?>
<root>
<admin>1600</admin>
<blth>JAN19</blth>
<bulan>1 BLN</bulan>
<nama>DU'MMY-VSI-{idpel}</nama>
<rc>0000</rc>
<rcm>[0] CEK TAGIHAN SUKSES ke:{idpel} refnum:EEC3FC4A371C44628C75E7AFC3313316</rcm>
<refnum>EEC3FC4A371C44628C75E7AFC3313316</refnum>
<status>SUCCESS</status>
<subid>{idpel}</subid>
<tagihan>363129</tagihan>
<tarif>R1/450</tarif>
<text>{idpel}
DU'MMY-VSI-532110000
R1/450
1 BLN
JAN19
RP TAG PLN RP 363.129
ADM RP 1.600
TOTAL RP 364.729</text>
<total>364729</total>
<trxid>{trxid}</trxid>
</root>
""".format(idpel=params["idpel"], trxid=params["trxid"])
request.response.text = result
return request.response
def pln_pay_result(request, params):
s = datetime.now()
tanggal = ymdhms(s)
tanggal2 = dmyhms(s)
result ="""<?xml version="1.0" encoding="UTF-8"?>
<root>
<admin>1600</admin>
<blth>JAN19</blth>
<date>{tanggal}</date>
<denda>9000</denda>
<info1>Informasi Hubungi Call Center: 123 Atau Hub. PLN Terdekat:</info1>
<info2>Terima Kasih</info2>
<nama>DU'MMY-VSI-{idpel}</nama>
<ppn>0</ppn>
<rc>0000</rc>
<rcm>[0] PEMBAYARAN SUKSES ke:532110000056 refnum:0BMS2135132129A7020C73244C9FD70E</rcm>
<refnum>0BMS2135132129A7020C73244C9FD70E</refnum>
<standmeter>888800-889900</standmeter>
<status>SUCCESS</status>
<subid>{idpel}</subid>
<tagihan>363129</tagihan>
<tarif>R1/450</tarif>
<text>{tanggal2}
0BMS2135132129A7020C73244C9FD70E
{idpel}
DU'MMY-VSI-532110000
R1/450
BLN JAN19
RP 363.129
ADM RP 1.600
TOTAL RP 364.729
SUKSES</text>
<total>364729</total>
<trxid>trxid</trxid>
</root>
""".format(idpel=params["idpel"], trxid=params["trxid"], tanggal=tanggal,
tanggal2=tanggal2)
request.response.text = result
return request.response
@view_config(route_name='api-vsi', renderer='json', request_method="GET")
def view_vsi(request):
params = request.params
command = params["command"]
modul = params["modul"]
if modul=="ISI" :
voucherid = params["voucherid"]
if command == "PAY" and voucherid=="TN5":
return pulsa_result(request, params)
else:
return pulsa_produk_not_found(request, params)
elif modul=="PRE":
# PLN Prabayar
if command == "INQ":
return plnpre_inq_result(request, params)
elif command == "PAY":
return plnpre_pay_result(request, params)
elif modul=="pln":
# PLN Pasca
if command == "INQ":
return pln_inq_result(request, params)
elif command == "PAY":
return pln_pay_result(request, params)
# elif modul == "PDAM":
# # PDAM
# if command == "INQ":
# return pdam_inq_result(request, params)
# elif command == "PAY":
# return pdam_pay_result(request, params)
#
# elif modul == "gp":
# # BPJS Kesehatan
# if command == "INQ":
# return bpjs_inq_result(request, params)
# elif command == "PAY":
# return bpjs_pay_result(request, params)
tanggal = dmyhms(datetime.now())
tujuan = "tujuan" in params and "tujuan" or ""
tujuan = "msn" in params and "msn" or tujuan
tujuan = "idpel" in params and "idpel" or tujuan
voucherid = "voucherid" in params and params["voucherid"] or ""
result = """
<root>
<nomor>{tujuan}</nomor>
<rc>0500</rc>
<rcm>[500] Command Error {modul} command {command}</rcm>
<status>FAILED</status>
<tanggal>{tanggal}</tanggal>
<text>Command Error</text>
<trxid>{trxid}</trxid>
<voucherid>{voucherid}</voucherid>
<voucherid>{modul}</voucherid>
<voucherid>{command}</voucherid>
</root>
""".format(tujuan=params[tujuan], tanggal=tanggal,
trxid=params["trxid"], voucherid=voucherid,
modul=params["modul"], command=params["command"])
request.response.text = result
return request.response
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!