Commit e02d3541 by Solo Group

va

1 parent 1685e45b
......@@ -2,6 +2,8 @@ kode,path,nama,status,type
api-merchant-home,/api/merchant/home,Api Merchant Home,1,0
api-merchant,/api/merchant,Api Merchant,1,1
api-merchant-register,/api/merchant/register,Api Merchant Payment,1,0
api-merchant-register-callback,/api/merchant/register/callback,Api Merchant Payment Callback,1,0
api-merchant-payment,/api/merchant/payment,Api Merchant Payment,1,0
api-vendor-notify,/api/vendor/{name}/notify,Api Vendor Notify,1,0
api-vendor-callback,/api/vendor/{name}/callback,Api Vendor Callback,1,0
......
from opensipkd.base.tools.api import *
from opensipkd.base.tools.buttons import *
from opensipkd.base.tools import *
from pyramid.compat import string_types
from pyramid.encode import url_quote, urlencode
from pyramid.url import QUERY_SAFE
def get_qs(_query):
if isinstance(_query, string_types):
qs = '?' + url_quote(_query, QUERY_SAFE)
else:
qs = '?' + urlencode(_query, doseq=True)
return qs
\ No newline at end of file
import logging
from importlib import import_module
from agratek.api.merchant.views.api_merchant import get_vendor_produk, build_request
import colander
from agratek.api.merchant.views.api_merchant import get_vendor_produk
from deform import widget, Form
from opensipkd.base.models import Partner, flush_row
from opensipkd.base.tools.api import (auth_from_rpc,
JsonRpcProdukNotFoundError, JsonRpcCustomerNotFoundError,
......@@ -12,11 +14,39 @@ from opensipkd.pasar.models.produk import H2hArInvoice, H2hArInvoiceDet, Partner
from pyramid.httpexceptions import HTTPFound
from pyramid.view import view_config
from pyramid_rpc.jsonrpc import jsonrpc_method
from ..tools import JsonRpcInvoiceFoundError, JsonRpcError, get_settings
from ..tools import JsonRpcInvoiceFoundError, JsonRpcError, get_settings, get_qs
log = logging.getLogger(__name__)
def build_request(typ, vendor_produk, partner_log=None, **kwargs):
# produk_id = values['produk_id']
# vendor_id = values['vendor_id']
# bill_no = values['destination']
# customer_id = 'customer_id' in values and values['customer_id'] or None
# cust_trx_id = 'cust_trx_id' in values and values['cust_trx_id'] or None
pckgs = 'agratek.api.merchant.views'
moduls = vendor_produk.modules.split('.')
if len(moduls) > 1:
pckg = ".".join(moduls[:-1])
pckgs = ".".join([pckgs, pckg])
moduls = moduls[-1:]
modul = moduls[0]
log.info("Module: %s Pckgs: %s" % (modul, pckgs))
modul = '.' + modul
modules = import_module(modul, pckgs)
cls_module = modules.Vendor(vendor_produk, partner_log, **kwargs)
cls = hasattr(cls_module, typ) and getattr(cls_module, typ) or None
if cls:
result = cls()
else:
message = "Module %s Not Found" % vendor_produk.modules
log.info(message)
result = dict(message=message,
code=9999)
return result
def save_partner_pay(values, vendor_produk, row=None):
if not row:
row = PartnerPay()
......@@ -28,8 +58,12 @@ def save_partner_pay(values, vendor_produk, row=None):
return row
def build_register(vendor_produk, partner_log=None, **kwargs):
return build_request('register', vendor_produk, partner_log, **kwargs)
def build_register(vendor_produk, partner_pay=None, **kwargs):
return build_request('register', vendor_produk, partner_pay, **kwargs)
def build_payment(vendor_produk, partner_pay=None, **kwargs):
return build_request('payment', vendor_produk, partner_pay, **kwargs)
def set_register_values(dat, customer):
......@@ -40,7 +74,7 @@ def set_register_values(dat, customer):
values = dict(
customer_id=customer.id,
# id_pel=dat['id_pel'],
cart=produk or '{}',
cart=produk or {},
cust_inv_no=dat["invoice_no"],
amt_sell=dat['amount'],
notes=dat['description'],
......@@ -92,30 +126,6 @@ def set_register_values(dat, customer):
@jsonrpc_method(method='register', endpoint='api-merchant')
def register(request, data, **kwargs):
"""
Digunakan untuk mendapatkan daftar produk
:param request:
:param data:
{
denom: string,
id_pel:string
inv_no: string optional
}
:param token:
user_token
:return:
{
product_nm:string,
denom: string,
id_pel:string
inv_no: string optional
denom:string,
harga:integer,
admin:integer,
discount:integer,
total:integer,
status:success/pending/failed
"""
user = auth_from_rpc(request)
i = 0
if not data:
......@@ -138,29 +148,26 @@ def register(request, data, **kwargs):
else:
inv_no = dat["invoice_no"]
row = PartnerPay.query().filter_by(cust_inv_no=inv_no).first()
if row and row.status>0:
if row and row.status > 0:
raise JsonRpcInvoiceFoundError()
vendor_kd = "vendor_kd" in dat and dat["vendor_kd"] or None
produk_kd = 'denom' in dat and dat['denom'] or None
print(produk_kd, vendor_kd)
vendor_produk = get_vendor_produk(produk_kd, vendor_kd=vendor_kd)
if not vendor_produk:
raise JsonRpcProdukNotFoundError
values = set_register_values(dat, customer)
credit_card = "credit_card" in dat and dat["credit_card"] or {}
if credit_card:
values.update(dict(
instmnt_mon = 'instmnt_mon' in credit_card and credit_card['instmnt_mon'] or '',
instmnt_type = 'instmnt_type' in credit_card and credit_card['instmnt_type'] or '',
recurr_opt = 'recurr_opt' in credit_card and credit_card['recurr_opt'] or 0,
card_no = 'card_no' in credit_card and credit_card['card_no'] or 0,
))
ccard = (dict(
card_cvv=credit_card["card_cvv"],
card_exp=credit_card["card_exp"],
card_name=credit_card["card_name"]
instmnt_mon='instmnt_mon' in credit_card and credit_card['instmnt_mon'] or '',
instmnt_type='instmnt_type' in credit_card and credit_card['instmnt_type'] or '',
recurr_opt='recurr_opt' in credit_card and credit_card['recurr_opt'] or 0,
))
ccard = None
else:
ccard = None
......@@ -173,15 +180,13 @@ def register(request, data, **kwargs):
))
ar_invoice = save_partner_pay(values, vendor_produk, row)
result = build_register(vendor_produk, ar_invoice, ccard=ccard)
#table payment di update lagi
dat.update(result["f_result"])
if "form" in result:
dat.update(dict(form=result["form"]))
# request.environ["application"]="text/html"
# request.response()
# return request.response
build_register(vendor_produk, ar_invoice, ccard=ccard)
dat.update(ar_invoice.inquiry["result"])
# if "form" in result:
# dat.update(dict(form=result["form"]))
# # request.environ["application"]="text/html"
# # request.response()
# # return request.response
r_data.append(dat)
......@@ -190,283 +195,95 @@ def register(request, data, **kwargs):
return data
class ResultSchema(colander.Schema):
code = colander.SchemaNode(
colander.String(),
widget=widget.TextInputWidget(readonly=True)
)
message = colander.SchemaNode(
colander.String(),
widget=widget.TextInputWidget(readonly=True)
)
def form_result(request, values):
schema = ResultSchema()
schema.request = request
buttons = ('ok',)
form = Form(schema, buttons=buttons)
form.render(values)
return dict(form=form, params=dict(scripts=""))
class ViewData(BaseView):
@view_config(route_name='api-merchant-payment',
renderer='templates/form-clean.pt')
def view_form(self):
# request = self.req
# flash = request.session.flash
# print(">>>>>", request.environ)
# print(">>>>", request.POST, request)
# if request.POST:
# data = dict(request.POST.items())
# if "tXid" in "data":
# row = PartnerPay.query_id(data["tXid"]).first()
# if not row:
# flash('Pembayaran tidak ditemukan', "error")
# return dict()
# vendor = row.vendor
# produk_vendor = PartnerProduk.query()\
# .filter_by(partner_id=row.vendor_id,
# produk_id = row.produk_id,)\
# .first()
#
# else:
# flash('Method POST Required', "error")
# return dict()
settings = get_settings()
url = settings["np_url"]+'/payment'
return HTTPFound(url)
# @jsonrpc_method(method='advice', endpoint='api-merchant')
# def advice(request, data):
# """
# Digunakan untuk mendapatkan daftar produk
# :param request:
# :param data:
# {
# denom: string,
# id_pel:string
# inv_no: string optional
# }
# :param token:
# user_token
# :return:
# {
# product_nm:string,
# denom: string,
# id_pel:string
# inv_no: string optional
# denom:string,
# harga:integer,
# admin:integer,
# discount:integer,
# total:integer,
# status:success/pending/failed
# """
# user = auth_from_rpc(request)
# i = 0
# is_list = type(data) == list
# data = is_list and data or [data]
# customer = Partner.query_user(user).first()
# if not customer:
# raise JsonRpcCustomerNotFoundError
# r_data = []
# for dat in data:
# if "invoice_no" not in dat:
# dat["status"] = "FAILED"
# dat["message"] = "Parameter tidak lengkap"
# else:
# inv_no = dat["invoice_no"]
# invoice = H2hArInvoice.query() \
# .filter_by(cust_inv_no=inv_no,
# customer_id=customer.id).first()
# if not invoice:
# dat["status"] = "FAILED"
# dat["message"] = "Invoice %s Tidak Ditemukan" % inv_no
# else:
# qry = H2hArInvoiceDet.query().filter_by(ar_invoice_id=invoice.id)
# r_prod = []
# if "produk" in dat:
# prods = []
# for p in dat["produk"]:
# row = qry.join(Produk, Produk.id == H2hArInvoiceDet.produk_id) \
# .filter(Produk.kode == p["denom"],
# H2hArInvoiceDet.id_pel == p["id_pel"]).first()
# if not row:
# status = "FAILED"
# message = "Produk tidak ada"
# p.update(dict(status=status,
# message=message))
# else:
# status = row.status == -1 and 'PENDING' or row.status == 1 and 'SUCCESS' \
# or row.status == -2 and 'PENDING' or "FAILED"
# p.update(dict(
# subtotal=(row.amt_sell or 0) + (row.discount or 0),
# discount=row.discount or 0,
# total=row.amt_sell,
# status=status,
# serial_number=row.serial_number or "", )
# )
# r_prod.append(p)
# else:
# for p in qry.all():
# produk = Produk.query(). \
# filter(Produk.id == p.produk_id).first()
# status = p.status == -1 and 'PENDING' or p.status == 1 and 'SUCCESS' \
# or p.status == -2 and 'PENDING' or "FAILED"
# r_prod.append(dict(denom=produk.kode,
# id_pel=p.id_pel,
# subtotal=(p.amt_sell or 0) + (p.discount or 0),
# discount=p.discount or 0,
# total=p.amt_sell,
# status=status,
# serial_number=p.serial_number or "", )
# )
# dat["produk"] = r_prod
# r_data.append(dat)
# i += 1
# data = is_list and r_data or r_data[0]
# return data
#
# @jsonrpc_method(method='payment', endpoint='api-merchant')
# def payment(request, token, data):
# """
# Digunakan untuk mendapatkan daftar produk
# :param request:
# :param data:
# {
# denom: string,
# id_pel:string
# inv_no: string optional
# }
# :param token:
# user_token
# :return:
# {
# product_nm:string,
#
# denom: string,
# id_pel:string
# inv_no: string optional
# denom:string,
# harga:integer,
# admin:integer,
# discount:integer,
# total:integer,
# status:success/pending/failed 00/01/02
# """
# user = auth_from_rpc(request, token)
# i = 0
# dat = data is list and data or [data]
# costumer = Partner.query_user(user)
# for dat in data:
# produk_kd = 'denom' in dat and dat['denom'] or None
# if not produk_kd :
# raise JsonRpcProdukNotFound(message="Produk harus diisi")
#
# produk = Produk.query_kode(produk_kd).first()
# if not produk:
# raise JsonRpcProdukNotFound(message="Produk %s tidak ditemukan" % produk_kd)
#
# # todo: search product lowest price
# vend_kd = 'ODEO'
#
# qry = PartnerProduk.query() \
# .filter(Partner.kode == vend_kd) \
# .filter(Produk.kode == produk_kd).first()
#
# r_data = dat
# r_data.update(dict(data=result))
# data[i] = r_data
# i += 1
# return data
#
#
# @jsonrpc_method(method='get_product', endpoint='api-merchant')
# def get_product(request, token, data ):
# """
# Digunakan untuk mendapatkan daftar produk
# :param request:
# :param data:
# {
# product_kd: string, //optional
# page:integer, //optional
# length:integer, //optional
# category:string, //optional
# search:string //optional
# }
# :return: [
# {
# product_kd:string,
# product_nm:string,
# harga:integer
# }
#
# ]
# """
# auth_from_rpc(request)
# i =0
# qry = DepartemenProduk.query() \
# .filter(Departemen.kode == '100000')
# for dat in data:
# page = 'page' in dat and dat['page'] or 1
# length = 'length' in dat and dat['length'] or 5
# product_kd = 'product_kd' in dat and dat['product_kd'] or None
# search = 'search' in dat and dat['search'] or None
# category = 'category' in dat and dat['category'] or None
# if product_kd :
# rst = qry.join(Produk).filter(Produk.kode == product_kd)
# elif search:
# rst = qry.join(Produk).filter(Produk.nama.ilike("".join(['%',search,'%' ])))
# elif category:
# rst = qry.join(Produk).join(ProdukKategori) \
# .filter(ProdukKategori.nama.ilike("".join(['%', category, '%'])))
# else:
# rst = qry
#
# rst = rst.limit(length).offset((page-1)*length)
# result = []
# for row in rst.all():
# result.append(dict(product_kd=row.produk.kode,
# produk_nm=row.produk.nama,
# harga=row.harga ))
# r_data = dat
# r_data.update(dict(data=result))
# data[i]=r_data
# i += 1
# return data
#
# @jsonrpc_method(method='get_biaya', endpoint='api-merchant')
# def get_biaya(request, data, token=None):
# """
# Digunakan untuk mencari methode pembayaran dan biaya layanan
# :param request:
# :param data:
# {
# biaya_kd: string,
# harga:integer,
# cname:string,
# cid:string,
# cvv:string, optional
# }
# :param token:
# user_token
# :return:
# {
# product_kd:string,
# product_nm:string,
# harga:integer
# }
# """
#
# user = auth_from_rpc(request, token)
# i =0
# qry = DepartemenProduk.query() \
# .filter(Departemen.kode == '100000')
# for dat in data:
# product_kd = 'biaya_kd' in dat and dat['biaya_kd'] or None
# cid = 'cid' in dat and dat['cid'] or None
# if not product_kd :
# raise JsonRpcParameterNotFound(message='Paramter product_kd wajib di isi')
#
# rst = qry.join(Produk).filter(Produk.kode == product_kd)
# result = []
# for row in rst.all():
# if row.is_cid and not cid:
# raise JsonRpcParameterNotFound(message="Parameter cid wajib di isi")
# if row.produk.fixed:
# harga = row.harga
# else:
# harga = dat['harga']*row.harga
#
# result.append(dict(biaya_kd=row.produk.kode,
# produk_nm=row.produk.nama,
# harga=harga))
#
# r_data = dat
# r_data.update(dict(data=result))
# data[i]=r_data
# i += 1
# return data
def view_api_merchant_payment(self):
request = self.req
data = request.POST and dict(request.POST.items()) or dict(request.GET.items())
log.info("Merchant payment request: {}".format(data))
tx_id = data["tx_id"]
cust_inv_no = data["invoice_no"]
invoice_det = PartnerPay.query_txid(tx_id) \
.filter_by(cust_inv_no=cust_inv_no).first()
if not invoice_det:
code = 55
values = dict(code=code,
message="Payment Not Found")
return form_result(request, values)
vendor_produk = PartnerProduk.get_produk(invoice_det.vendor_id,
invoice_det.produk_id).first()
pckgs = 'agratek.api.merchant.views'
moduls = vendor_produk.modules.split('.')
if len(moduls) > 1:
pckg = ".".join(moduls[:-1])
pckgs = ".".join([pckgs, pckg])
moduls = moduls[-1:]
modul = moduls[0]
log.info("Payment Module: %s Pckgs: %s" % (modul, pckgs))
modul = '.' + modul
modules = import_module(modul, pckgs)
cls_module = modules.Vendor(vendor_produk, invoice_det)
typ = "payment"
cls = hasattr(cls_module, typ) and getattr(cls_module, typ) or None
if cls:
result = cls(data)
# headers = {"Content-type": "application/x-www-form-urlencoded"}
if result:
return dict(form=result["form"])
# qs = get_qs(result['_query'])
# url = "{}{}".format(result['url'], qs)
# headers = result["headers"]
# # return form_result(request, result)
# return HTTPFound(url, headers=headers)
else:
code = 55
values = dict(code=code,
message="Payment Not Found")
return form_result(request, values)
code = 99
values = dict(code=code,
message="Parameter Expected")
return form_result(request, values)
@view_config(route_name='api-vendor-callback', renderer="templates/form-clean.pt")
def api_vendor_callback(request):
data = request.POST and dict(request.POST.items()) or dict(request.GET.items())
print(data)
vendor_nm = request.matchdict['name']
modul = '.callback'
pckgs = 'agratek.api.merchant.views.{}'.format(vendor_nm)
moduls = import_module(modul, pckgs)
typ = 'proses'
log.info("Pckgs: {} Modul:{} typ {}".format(pckgs, modul, typ))
cls = hasattr(moduls, typ) and getattr(moduls, typ) or None
print(dir(cls))
if cls:
result = cls(data)
if result:
return dict(form=result["form"])
qs =get_qs(data)
return HTTPFound(location=request.route_url("api-merchant-register-callback", _query=qs))
return dict(form="<h1>ERROR</h1>")
\ No newline at end of file
......@@ -3,6 +3,7 @@ import socket
from datetime import datetime, timedelta
import colander
from colander import string_types
from deform import widget, Form, ValidationFailure, Button
from opensipkd.base import get_host
from opensipkd.base.models import Partner, flush_row
......@@ -10,11 +11,13 @@ from opensipkd.base.views import BaseView
from opensipkd.pasar.models import Produk, PartnerLog, PartnerProduk, H2hArInvoice, H2hArInvoiceDet
from opensipkd.pasar.models.views import (deferred_produk, deferred_vendor,
deferred_customer)
from pyramid.encode import url_quote, urlencode
from pyramid.httpexceptions import HTTPFound
from pyramid.url import QUERY_SAFE
from pyramid.view import view_config
from requests import Response
from ..tools import get_settings, btn_purchase, ymd, hms, json_rpc_header, get_random_number
from ..tools import get_settings, btn_purchase, ymd, hms, json_rpc_header, get_random_number, get_qs
from ..tools import btn_inquiry, btn_reset, btn_payment, btn_advice, btn_next, btn_register, btn_cancel
from .api_merchant import build_request, qry_vendor_produk, save_partner_log
......@@ -132,7 +135,6 @@ pay_valid_dt Y N 8 20170313 expiry date (YYYYMMDD) (Payloan)
pay_valid_tm Y N 6 135959 expiry time (HH24MISS) (Payloan)
"""
payment_methods = [
('01', 'Credit Card'),
('02', 'Virtual Account (VA)'),
......@@ -203,26 +205,6 @@ $(document).ready(function(){
class RegisterSchema(colander.Schema):
# time_stamp Y N 14 API Request Date
# i_mid Y AN 10 Merchant Id
# currency Y AN 3 currency
# merchant_token Y AN 255 merchantToken
# pay_method = colander.SchemaNode(
# colander.String(),
# widget=widget.SelectWidget(values=payment_methods)
# )
# denom = colander.SchemaNode(
# colander.String(),
# default='CRC',
# widget=widget.TextInputWidget(attributes={'maxlength': 100})
# )
# id_pel = colander.SchemaNode(
# colander.String(),
# default='123456789',
# widget=widget.TextInputWidget(attributes={'maxlength': 100})
# )
produk_id = colander.SchemaNode(
colander.Integer(), title='Produk',
oid="produk_id", widget=deferred_produk)
......@@ -325,12 +307,6 @@ class RegisterSchema(colander.Schema):
missing=colander.drop,
widget=widget.TextInputWidget(attributes={'maxlength': 50})
)
# db_process_url Y AN 255 Payment Notification url (Async notification)
# db_proses_url = colander.SchemaNode(
# colander.String(),
# default='https://merchant.com/notification',
# widget=widget.TextInputWidget(attributes={'maxlength': 255})
# )
vat = colander.SchemaNode(
colander.Integer(),
default=0,
......@@ -351,38 +327,6 @@ class RegisterSchema(colander.Schema):
default='Transaction Description',
widget=widget.TextInputWidget(attributes={'maxlength': 255})
)
# req_domain = colander.SchemaNode(
# colander.String(),
# missing=colander.drop,
# widget=widget.TextInputWidget(attributes={'maxlength': 100})
# )
# req_server_ip = colander.SchemaNode(
# colander.String(),
# missing=colander.drop,
# widget=widget.TextInputWidget(attributes={'maxlength': 128})
# )
# req_client_ver = colander.SchemaNode(
# colander.String(),
# missing=colander.drop,
# widget=widget.TextInputWidget(attributes={'maxlength': 50})
# )
# user_ip = colander.SchemaNode(
# colander.String(),
# missing=colander.drop,
# default='127.0.0.1',
# widget=widget.TextInputWidget(attributes={'maxlength': 128})
# )
# user_session_id = colander.SchemaNode(
# colander.String(),
# missing=colander.drop,
# widget=widget.TextInputWidget(attributes={'maxlength': 255})
# )
# user_agent = colander.SchemaNode(
# colander.String(),
# missing=colander.drop,
# widget=widget.TextInputWidget(attributes={'maxlength': 255})
# )
user_language = colander.SchemaNode(
colander.String(),
missing=colander.drop,
......@@ -391,55 +335,26 @@ class RegisterSchema(colander.Schema):
)
cart_data = colander.SchemaNode(
colander.String(),
# default="""{
# "count": "2",
# "item": [
# {
# "img_url": "http://img.aaa.com/ima1.jpg",
# "goods_name": "Item 1 Name",
# "goods_detail": "Item 1 Detail",
# "goods_amt": "700"
# },
# {
# "img_url": "http://img.aaa.com/ima2.jpg",
# "goods_name": "Item 2 Name",
# "goods_detail": "Item 2 Detail",
# "goods_amt": "300"
# }
# ]
# }""",
default="{}",
default="""{
"count": "2",
"item": [
{
"img_url": "http://img.aaa.com/ima1.jpg",
"goods_name": "Item 1 Name",
"goods_detail": "Item 1 Detail",
"goods_amt": "700"
},
{
"img_url": "http://img.aaa.com/ima2.jpg",
"goods_name": "Item 2 Name",
"goods_detail": "Item 2 Detail",
"goods_amt": "300"
}
]
}""",
# default="{}",
widget=widget.TextAreaWidget(attributes={'maxlength': 4000})
)
# CC
# VA
# bank_cd = colander.SchemaNode(
# colander.String(),
# default='CENA',
# widget=widget.TextInputWidget(attributes={'maxlength': 4})
# )
# # (E - Wallet, CVS, Payloan)
# mitra_cd = colander.SchemaNode(
# colander.String(),
# widget=widget.TextInputWidget()
# )
# m_ref_no = colander.SchemaNode(
# colander.String(),
# widget=widget.TextInputWidget(attributes={'maxlength': 18})
# )
# pay_valid_dt = colander.SchemaNode(
# colander.String(),
# widget=widget.TextInputWidget(attributes={'maxlength': 8})
# )
# # expire date(YYYYMMDD)(Payloan)
# pay_valid_tm = colander.SchemaNode(
# colander.String(),
# widget=widget.TextInputWidget(attributes={'maxlength': 6})
# )
# expiry time(HH24MISS)(Payloan)
class EditSchema(RegisterSchema):
id = colander.SchemaNode(
......@@ -509,18 +424,18 @@ class CCardPayment(colander.Schema):
callback_url = colander.SchemaNode(
colander.String(),
#default = "{}/api/merchant/agratek/callback".format(get_host()),
default="http://merchant.com/callback",
default="{}/api/merchant/register/callback".format("https://server"),
widget=widget.TextInputWidget(max_len=255)
)
class VAPayment(colander.Schema):
valid_date = colander.SchemaNode(
colander.String(),
default=(datetime.now() + timedelta(days=1)).strftime('%Y%m%d'),
widget=widget.TextInputWidget(attributes={'maxlength': 8})
)
valid_time= colander.SchemaNode(
valid_time = colander.SchemaNode(
colander.String(),
default=datetime.now().strftime('%H%M%S'),
widget=widget.TextInputWidget(attributes={'maxlength': 6})
......@@ -531,6 +446,7 @@ class VAPayment(colander.Schema):
widget=widget.TextInputWidget(attributes={'maxlength': 40})
)
class VAResult(colander.Schema):
vacct_no = colander.SchemaNode(
colander.String(),
......@@ -545,6 +461,7 @@ class VAResult(colander.Schema):
widget=widget.TextInputWidget(readonly=True)
)
class CPPayment(colander.Schema):
"""
clickPayNo Y N 16 ClickPay number
......@@ -552,30 +469,32 @@ class CPPayment(colander.Schema):
clickPayToken Y N 6 Code response from token
merchantToken Y AN 255 merchantToken
callBackUrl Y AN 255 Payment result forward url (on browser)
"""
click_pay_no = colander.SchemaNode(
cp_no = colander.SchemaNode(
colander.String(),
missing=colander.drop,
default="1234567890123456",
widget=widget.TextInputWidget(max_len=16)
)
item3 = colander.SchemaNode(
colander.String(),
default="1234567890123456",
missing=colander.drop,
widget=widget.TextInputWidget(max_len=3)
)
click_pay_token = colander.SchemaNode(
cp_token = colander.SchemaNode(
colander.String(),
default="123456",
missing=colander.drop,
widget=widget.TextInputWidget(max_len=6)
)
callback_url = colander.SchemaNode(
colander.String(),
#default = "{}/api/merchant/agratek/callback".format(get_host()),
default="http://merchant.com/callback",
default="{}/api/merchant/register/callback".format("https://server"),
widget=widget.TextInputWidget(max_len=255)
)
class WLPayment(colander.Schema):
m_ref_no = colander.SchemaNode(
colander.String(),
......@@ -584,23 +503,24 @@ class WLPayment(colander.Schema):
)
callback_url = colander.SchemaNode(
colander.String(),
#default = "{}/api/merchant/agratek/callback".format(get_host()),
default="http://merchant.com/callback",
default="{}/api/merchant/register/callback".format("https://server"),
widget=widget.TextInputWidget(max_len=255)
)
class CVSPayment(colander.Schema):
valid_date = colander.SchemaNode(
colander.String(),
default=(datetime.now() + timedelta(days=1)).strftime('%Y%m%d'),
widget=widget.TextInputWidget(attributes={'maxlength': 8})
)
valid_time= colander.SchemaNode(
valid_time = colander.SchemaNode(
colander.String(),
default=datetime.now().strftime('%H%M%S'),
widget=widget.TextInputWidget(attributes={'maxlength': 6})
)
class CVSResult(colander.Schema):
pay_no = colander.SchemaNode(
colander.String(),
......@@ -619,11 +539,11 @@ class CVSResult(colander.Schema):
class PLPayment(colander.Schema):
callback_url = colander.SchemaNode(
colander.String(),
#default = "{}/api/merchant/agratek/callback".format(get_host()),
default="http://merchant.com/callback",
default="{}/api/merchant/register/callback".format("https://server"),
widget=widget.TextInputWidget(max_len=255)
)
def form_validator(form, value):
pass
......@@ -645,8 +565,13 @@ def route_register(request):
btn_proses = Button('proses', title='Proses', css_class="btn-warning")
def set_data(request, denom, dat):
env = request.environ
produk = json.loads(dat['cart_data'])
if type(produk)!=dict:
produk = {}
return dict(
time_stamp=datetime.now().strftime('%Y%m%d%H%M%S'),
denom=denom,
......@@ -686,9 +611,10 @@ def set_data(request, denom, dat):
post_code=dat['billing_post_cd'],
country=dat['billing_country'],
),
produk=json.loads(dat['cart_data']),
produk=produk,
)
def payment(request, data, form=None):
row = Produk.query_id(data['produk_id']).first()
denom = row and row.kode or ''
......@@ -697,21 +623,23 @@ def payment(request, data, form=None):
elif denom[:2] == 'VA':
form = get_form(request, VAPayment, (btn_cancel, btn_proses))
elif denom[:2] == 'CP':
form = get_form(request, CPPayment, (btn_cancel,))
form = get_form(request, CPPayment, (btn_cancel, btn_proses))
elif denom[:2] == 'WL':
form = get_form(request, WLPayment, (btn_cancel,))
form = get_form(request, WLPayment, (btn_cancel, btn_proses))
elif denom[:3] == 'CVS':
form = get_form(request, CVSPayment, (btn_cancel, btn_proses))
elif denom[:2] == 'PL':
form = get_form(request, PLPayment, (btn_cancel, btn_proses))
return form
def proses(request):
values = dict(request.POST.items())
session = request.session
dat = session['payment']
log.info("Request From Merchant: {}".format(dat))
row = Produk.query_id(dat['produk_id']).first()
denom = row and row.kode or ''
data = set_data(request, denom, dat)
......@@ -726,27 +654,65 @@ def proses(request):
instmnt_type=values["instmnt_type"],
instmnt_mon=values["instmnt_mon"],
recurr_opt=values["recurr_opt"],
card_no=values["card_no"],
card_exp=values["card_exp"],
card_cvv=values["card_cvv"],
card_name=values["card_name"],
)))
result = register(request, data=data)
if result['code'] != 0:
form = get_form(request, RegisterSchema, (btn_cancel, btn_payment))
form = get_form(request, CCardPayment, (btn_cancel, btn_payment))
form.render(dat)
session.flash(result['message'], "error")
return dict(form=form, params=dict(scripts=""))
session.flash("Proses data berhasil")
if "form" in result:
response = request.response
response.text = result["form"]
response.content_type = 'text/html'
return response
_query = (
("tx_id", result["tx_id"]),
("invoice_no", dat["invoice_no"]),
("card_no", values["card_no"]),
("card_exp", values["card_exp"]),
("card_cvv", values["card_cvv"]),
("card_name", values["card_name"]),
("callback_url", values["callback_url"]),
)
url = request.route_url("api-merchant-payment", _query=_query)
return HTTPFound(url)
elif denom[:2] in ["WL","PL"]:
result = register(request, data=data)
if result['code'] != 0:
form = get_form(request, WLPayment, (btn_cancel, btn_payment))
form.render(dat)
session.flash(result['message'], "error")
return dict(form=form, params=dict(scripts=""))
_query = (
("tx_id",result["tx_id"]),
("invoice_no",dat["invoice_no"]),
("callback_url",values["callback_url"]),
)
url = request.route_url("api-merchant-payment", _query=_query)
# url = request.route_url("api-merchant-payment", _query=_query)
return HTTPFound(url)
elif denom[:2] == "CP":
data.update(dict(va=dict(
cp_no=values["cp_no"],
item3=values["item3"],
cp_token=values["cp_token"],
)))
result = register(request, data=data)
if result['code'] != 0:
form = get_form(request, CPPayment, (btn_cancel, btn_payment))
form.render(dat)
session.flash(result['message'], "error")
return dict(form=form, params=dict(scripts=""))
_query = (
("tx_id",result["tx_id"]),
("invoice_no",dat["invoice_no"]),
("cp_no",values["cp_no"]),
("item3",values["item3"]),
("cp_token",values["cp_token"]),
("callback_url",values["callback_url"]),
)
url = request.route_url("api-merchant-payment", _query=_query)
# url = request.route_url("api-merchant-payment", _query=_query)
return HTTPFound(url)
# Virtual Account
elif denom[:2] == "VA":
data.update(dict(va=dict(
valid_date=values['valid_date'],
......@@ -781,7 +747,7 @@ def proses(request):
request.session.flash(result['message'], "error")
return dict(form=form, params=dict(scripts=""))
form = get_form(request, CVSResult, (btn_cancel, ))
form = get_form(request, CVSResult, (btn_cancel,))
session.flash("Proses data berhasil")
values = result["cvs"]
form.render(values)
......@@ -803,21 +769,24 @@ class ViewHome(BaseView):
c = form.validate(controls)
except ValidationFailure as e:
form.set_appstruct(e.cstruct)
return dict(form=form)
return dict(form=form, params=dict(scripts=""))
data = dict(request.POST.items())
vendor = Partner.query_id(data["vendor_id"]).first()
if vendor:
data.update({"vendor_kd": vendor.kode})
log.info("Data Requested server: {}".format(data))
session['payment'] = data
form = payment(request, data, form)
values = dict(callback_url="{}/api/merchant/register/callback".format(request._host))
form.render(values)
return dict(form=form, params=dict(scripts=""))
elif 'proses' in request.POST:
if 'payment' not in session:
form = get_form(request, RegisterSchema, (btn_cancel, btn_payment))
session.flash("Payment Tidak Ditemukan")
return dict(form=form, params=dict(scripts="") )
return dict(form=form, params=dict(scripts=""))
result = proses(request)
if result:
......@@ -832,6 +801,28 @@ class ViewHome(BaseView):
form.render(values)
return dict(form=form, params=dict(scripts=""))
@view_config(route_name='api-merchant-register-callback',
# permission="api-merchant-register-callback",
renderer='templates/form.pt')
def form_merchant_register_callback(self):
request = self.req
if request.POST:
if 'cancel' in request.POST:
return route_register(request)
values = request.POST.items() and dict(request.POST.items()) or dict(request.GET.items())
# sm = colander.SchemaNode(colander.Tuple())
sm = colander.Schema()
for v in values:
sm.add(colander.SchemaNode(
colander.String(),
default=values[v], name=v,
widget=widget.TextInputWidget(readonly=True)
))
#form.render(values)
form = Form(sm, buttons=(btn_cancel,))
return dict(form=form, params=dict(scripts=""))
def get_row(id):
return PartnerLog.query().filter_by(id=id).first()
......
......@@ -13,7 +13,7 @@ from pyramid.view import view_config
from ..tools import get_settings, get_jsonrpc
log = logging.Logger(__name__)
log = logging.getLogger(__name__)
def update_harga(p, k, v):
......@@ -73,6 +73,7 @@ def purchase_notify(order):
except:
pass
def payment_notify(order):
customer = order.customer
if customer and customer.website:
......@@ -93,7 +94,7 @@ def payment_notify(order):
requests.post(url, data=js, timeout=20)
except:
pass
return
def proses_np(data):
# todo:
......@@ -104,7 +105,6 @@ def proses_np(data):
def api_vendor_notify(request):
vendor_nm = request.matchdict['name']
data = json.loads(request.text)
modul = '.notify'
pckgs = 'agratek.api.merchant.views.{}'.format(vendor_nm)
moduls = import_module(modul, pckgs)
......@@ -114,18 +114,6 @@ def api_vendor_notify(request):
order = cls(data)
@view_config(route_name='api-vendor-callback')
def api_vendor_callback(request):
vendor_nm = request.matchdict['name']
modul = '.callback'
pckgs = 'agratek.api.merchant.views.{}'.format(vendor_nm)
moduls = import_module(modul, pckgs)
typ = 'callback'
cls = hasattr(moduls, typ) and getattr(moduls, typ) or None
if cls:
cb = cls(request)
return HTTPFound(cb)
@view_config(route_name='api-vendor-test', renderer="string")
def vendor_test(request):
params = request.params
......
import json
import base64
import logging
from opensipkd.base import get_settings
from datetime import datetime
from opensipkd.base import get_settings, is_devel, get_host
from opensipkd.base.models import flush_row
from pyramid.httpexceptions import HTTPFound
from . import Nicepay
from ..vendor import VendorClass
from ..vendor import VendorClass, sha256
log = logging.getLogger(__name__)
class Vendor(VendorClass): #VendorClass
class Vendor(VendorClass): # VendorClass
def __init__(self, vendor_produk, invoice_det, **kwargs):
VendorClass.__init__(self, vendor_produk, invoice_det=invoice_det, **kwargs)
settings = get_settings()
self.mid = 'np_mid' in settings and settings['np_mid'] or None
self.key = 'np_key' in settings and settings['np_key'] or None
self.url = 'np_url' in settings and settings['np_url'] or None
self.callback_url = 'np_callback' in settings and settings['np_callback'] or \
'https://www.merchant.com/Notification'
self.notify_url = 'np_notify' in settings and settings['np_notify'] or \
'https://www.merchant.com/Notification'
self.callback_url = "{}/api/vendor/np/callback".format(get_host())
self.notify_url = "{}/api/vendor/np/notify".format(get_host())
key = ":".join([self.mid, self.key]).encode()
self.auth = base64.b64encode(key).decode()
self.v_produk_kd = vendor_produk.kode
if "ccard" in kwargs:
ccard = kwargs["ccard"]
if ccard:
self.card_cvv = ccard["card_cvv"]
self.card_exp = ccard["card_exp"]
self.card_name = ccard["card_name"]
self.ccard = "ccard" in kwargs and kwargs["ccard"] or None
self.cp = "cp" in kwargs and kwargs["cp"] or None
self.cvs = "cvs" in kwargs and kwargs["cvs"] or None
self.va = "va" in kwargs and kwargs["va"] or None
self.pl = "pl" in kwargs and kwargs["pl"] or None
customer = self.invoice_det.customer
if customer:
self.cust_kd = customer.kode
self.cust_inv_no = self.invoice_det.cust_inv_no
self.bank_cd, self.pay_method = self.v_produk_kd.split('-')
if self.pay_method=="02":
self.mid="VACTFOPEND"
if self.pay_method == "02" and is_devel():
self.mid = "VACTFOPEND"
key = ":".join([self.mid, self.key]).encode()
self.auth = base64.b64encode(key).decode()
......@@ -46,45 +45,44 @@ class Vendor(VendorClass): #VendorClass
self.amt = str(self.invoice_det.amt_sell)
# setMandatoryParameter
def request_payment(self, response):
Nicepay.requestData={}
Nicepay.set('timeStamp', self.invoice_det.time_stamp)
Nicepay.set('referenceNo', self.cust_inv_no)
Nicepay.set('tXid', response["tXid"])
Nicepay.set('cardNo', self.invoice_det.card_no)
Nicepay.set('cardExpYymm', self.invoice_det.card_exp) # format Yymm '2012'
Nicepay.set('cardCvv', self.invoice_det.card_cvv)
Nicepay.set('recurringToken', '')
Nicepay.set('preauthToken', '')
Nicepay.set('clickPayNo', '')
Nicepay.set('dataField3', '')
Nicepay.set('clickPayToken', '')
Nicepay.set('callBackUrl', self.callback_url)
result = Nicepay.nicePayment()
return result
# def request_payment(self, response):
# Nicepay.requestData={}
# Nicepay.set('timeStamp', self.invoice_det.time_stamp)
# Nicepay.set('referenceNo', self.cust_inv_no)
# Nicepay.set('tXid', response["tXid"])
# Nicepay.set('cardNo', self.invoice_det.card_no)
# Nicepay.set('cardExpYymm', self.invoice_det.card_exp) # format Yymm '2012'
# Nicepay.set('cardCvv', self.invoice_det.card_cvv)
# Nicepay.set('recurringToken', '')
# Nicepay.set('preauthToken', '')
# Nicepay.set('clickPayNo', '')
# Nicepay.set('dataField3', '')
# Nicepay.set('clickPayToken', '')
# Nicepay.set('callBackUrl', self.callback_url)
# result = Nicepay.nicePayment()
# return result
def set_static_params(self):
if not self.cust_inv_no:
return
Nicepay.set('timeStamp', self.invoice_det.inv_time_stamp) #
Nicepay.set('iMid', self.mid)
Nicepay.set('payMethod', self.pay_method)
Nicepay.set('currency', 'IDR')
# Nicepay.set('amt', self.amt)
Nicepay.set('referenceNo', self.cust_inv_no)
Nicepay.set('userIP', self.invoice_det.inv_cust_ip)
Nicepay.set('dbProcessUrl', self.notify_url)
# Nicepay.set('merchantKey', self.key)
Nicepay.set('amt', str(self.invoice_det.amt_sell))
Nicepay.merchantKey = self.key
Nicepay.set('merchantToken', Nicepay.merchantToken())
# Nicepay.set("userLanguage", "en-US")
Nicepay.set("userLanguage", "")
Nicepay.set('reqClientVer', '2.0')
return True
def set_billing_param(self):
if not self.invoice_det:
return
Nicepay.set('payMethod', self.pay_method)
Nicepay.set('currency', 'IDR')
Nicepay.set('userIP', self.invoice_det.inv_cust_ip)
Nicepay.set('dbProcessUrl', self.notify_url)
Nicepay.set("userLanguage", "")
Nicepay.set('reqClientVer', '')
Nicepay.set('goodsNm', self.invoice_det.notes)
Nicepay.set('billingNm', self.invoice_det.inv_cust_nm)
Nicepay.set('billingPhone', self.invoice_det.inv_cust_phone)
......@@ -106,8 +104,6 @@ class Vendor(VendorClass): #VendorClass
return True
def set_optional_param(self):
# pass
# setOptionalParameter
Nicepay.set('deliveryNm', self.invoice_det.delivery_nm)
Nicepay.set('deliveryPhone', self.invoice_det.delivery_phone)
Nicepay.set('deliveryAddr', self.invoice_det.delivery_addr)
......@@ -115,40 +111,33 @@ class Vendor(VendorClass): #VendorClass
Nicepay.set('deliveryState', self.invoice_det.delivery_state)
Nicepay.set('deliveryPostCd', self.invoice_det.delivery_pos)
Nicepay.set('deliveryCountry', self.invoice_det.delivery_country)
# print('>>> INVOICE DET:', self.invoice_det.vat, type(self.invoice_det.vat),
# self.invoice_det.fee, type(self.invoice_det.fee),
# self.invoice_det.notax_amt, type(self.invoice_det.notax_amt))
Nicepay.set('vat', self.invoice_det.vat and int(self.invoice_det.vat) > 0 and \
str(self.invoice_det.vat) or '')
Nicepay.set('fee', self.invoice_det.fee and int(self.invoice_det.fee) > 0 and \
str(self.invoice_det.fee) or '')
no_tax_amt = self.invoice_det.notax_amt and int(self.invoice_det.notax_amt) > 0 and\
str(self.invoice_det.notax_amt) or ''
Nicepay.set('notaxAmt', no_tax_amt)
# Nicepay.set('reqDt', self.invoice_det.req_dt) # Format (YYYYMMDD)
# Nicepay.set('reqTm', self.invoice_det.req_tm) # Format (HHiiss)
Nicepay.set('reqDt', '') # Format (YYYYMMDD)
Nicepay.set('reqTm', '') # Format (HHiiss)
Nicepay.set('reqClientVer', '')
Nicepay.set('instmntType', '')
Nicepay.set('instmntMon', '')
Nicepay.set('mRefNo', '')
Nicepay.set('reqDt', self.invoice_det.req_dt) # Format (YYYYMMDD)
Nicepay.set('reqTm', self.invoice_det.req_tm) # Format (HHiiss)
# Nicepay.set('reqDt', '') # Format (YYYYMMDD)
# Nicepay.set('reqTm', '') # Format (HHiiss)
# Nicepay.set('instmntType', '')
# Nicepay.set('instmntMon', '')
# Nicepay.set('mRefNo', '')
# result dari nicepay
# Nicepay.set('tXid', '')
# Nicepay.set('transDt', '')
# Nicepay.set('transTm', '')
Nicepay.set('payValidDt', '')
Nicepay.set('payValidTm', '')
Nicepay.set('recurrOpt', '')
# Nicepay.set('payValidDt', '')
# Nicepay.set('payValidTm', '')
# Nicepay.set('recurrOpt', '')
def register(self):
Nicepay.requestData = {}
if not self.set_billing_param() or not self.set_static_params():
return
data = str(json.dumps(self.invoice_det.cart))
cart_data = data and '{}'.format(data) or '{}'
data = self.invoice_det.cart
cart_data = data or {}
Nicepay.set('cartData', cart_data)
self.set_optional_param()
# For Credit Card (Don't forgot change payMethod to '01')
......@@ -156,7 +145,17 @@ class Vendor(VendorClass): #VendorClass
Nicepay.set('recurrOpt', str(self.invoice_det.recurr_opt))
Nicepay.set('instmntMon', str(self.invoice_det.instmnt_mon) or '')
Nicepay.set('instmntType', str(self.invoice_det.instmnt_type) or '')
vat = self.invoice_det.vat and int(self.invoice_det.vat) > 0 and \
str(self.invoice_det.vat) or ''
fee = self.invoice_det.fee and int(self.invoice_det.fee) > 0 and \
str(self.invoice_det.fee) or ''
Nicepay.set('vat', vat)
Nicepay.set('fee', fee)
no_tax_amt = self.invoice_det.notax_amt and \
int(self.invoice_det.notax_amt) > 0 and \
str(self.invoice_det.notax_amt) or ''
Nicepay.set('notaxAmt', no_tax_amt)
# For Virtual Account (Don't forgot change payMethod to '02')
elif self.pay_method == '02':
Nicepay.set('bankCd', self.bank_cd)
......@@ -174,17 +173,18 @@ class Vendor(VendorClass): #VendorClass
# (Don't forgot change payMethod to '03'/'04'/'05')
elif self.pay_method in ['03']:
Nicepay.set('mitraCd', self.bank_cd)
# For CVS Only
Nicepay.set('payValidDt', self.invoice_det.inv_valid_date) # Format (YYYYMMDD)
Nicepay.set('payValidTm', self.invoice_det.inv_valid_time) # Format (HHiiss)
# For Click Pay
elif self.pay_method == '04':
Nicepay.set('mRefNo', self.cust_inv_no)
Nicepay.set('bankCd', self.bank_cd)
Nicepay.set('mitraCd', self.bank_cd)
# E-Wallet
elif self.pay_method == '05':
Nicepay.set('mitraCd', self.bank_cd)
# For Pay Loan
elif self.pay_method == '06':
Nicepay.set('recurrOpt', str(self.invoice_det.recurr_opt))
Nicepay.set('instmntMon', str(self.invoice_det.instmnt_mon) or '')
......@@ -195,14 +195,19 @@ class Vendor(VendorClass): #VendorClass
# Process to nice pay register
self.request = Nicepay.requestData
log.info("NP REQUEST: {}".format(json.dumps(self.request)))
np_request=self.request
np_request["cartData"]=json.dumps(np_request["cartData"])
log.info("NP PRE REQUEST: {}".format(np_request))
log.info("NP REQUEST: {}".format(json.dumps(np_request)))
self.save_log('inquiry')
result_data = Nicepay.niceRegister()
response = json.loads(result_data)
self.response = response
log.info("NP RESPONSE: {}".format(json.dumps(self.response)))
self.response = response
# # Payment Response String Format
self.save_log("inquiry")
# Register Response String Format
if 'resultCd' not in response:
self.result = dict(
error="Connection Timeout. Please Try Again!"
......@@ -212,74 +217,72 @@ class Vendor(VendorClass): #VendorClass
else:
result = dict()
try:
result_code = int(response['resultCd'])
except:
result_code = 999
result["code"] = result_code
result["message"] = response['resultMsg']
if result_code == 0: # or self.pay_method == '01':
result["currency"] = response['currency']
# result["tx_id"] = response['tXid']
# result['trans_dt'] = response['transDt']
# result['trans_tm'] = response['transTm']
result["amount"] = response['amt']
result["invoice_no"] = response['referenceNo']
result["description"] = response['description']
# result['pay_method'] = self.pay_method
if self.pay_method == "01":
result["code"] = 0
result["message"] = 'SUCCESS'
request_data = Nicepay.requestData
settings = get_settings()
call_back_url = settings['switcher_call_back_url']
result.update(dict(
time_stamp=request_data['timeStamp'],
tx_id=self.invoice_det.tx_id,
merchant_token=request_data['merchantToken'],
call_back_url=call_back_url,
))
# todo result harus html
settings = get_settings()
form = """<!DOCTYPE html>
<html lang="en-us">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Payment</title>
</head>
<body>
<form action="{url}/api/merchant/payment" method="post" name="payment">
<input type="text" name="timeStamp" value="{time_stamp}">
<input type="text" name="tXid" value="{tx_id}">
<input type="text" name="merchantToken" value="{merchant_token}">
<input type="text" name="cardNo" value="{card_no}">
<input type="text" name="cardExpYymm" value="{card_exp}">
<input type="text" name="cardCvv" value="{card_cvv}">
<input type="text" name="cardHolderNm" value="{card_holder_nm}">
<input type="text" name="callBackUrl" value="{call_back_url}">
<button type="submit" value="Submit" name="submit">Submit</button>
</form>
<script>
//document.write("Hello World!")
</script>
<noscript>Your browser does not support JavaScript!</noscript>
</body>
</html>
""".format(
url=settings["_host"],
time_stamp=request_data['timeStamp'],
tx_id=result['tx_id'],
merchant_token=request_data['merchantToken'],
card_no=self.invoice_det.card_no,
card_exp=self.card_exp,
card_cvv=self.card_cvv,
card_holder_nm=self.card_name,
call_back_url=call_back_url,
)
result['form'] = form
elif self.pay_method == "02":
time_stamp = datetime.now().strftime('%Y%m%d%H%M%S')
key = sha256("{}{}".format(self.cust_inv_no, time_stamp))
tx_id = "{}{}".format(self.invoice_det.customer.users.user_name, key)
result["tx_id"] = tx_id
result["invoice_no"] = response['referenceNo']
result["amount"] = response['amt']
result["trans_date"] = response['transDt']
result["trans_time"] = response['transTm']
result["description"] = response['description']
self.invoice_det.trans_dt = response["transDt"]
self.invoice_det.trans_tm = response["transTm"]
self.invoice_det.tx_id = tx_id
self.vend_inv_no = response["tXid"]
# if self.pay_method == "01":
# request_data = Nicepay.requestData
# settings = get_settings()
# call_back_url = settings['switcher_call_back_url']
# result.update(dict(
# time_stamp=request_data['timeStamp'],
# tx_id=self.invoice_det.tx_id,
# merchant_token=request_data['merchantToken'],
# call_back_url=call_back_url,
# ))
# todok result harus html
# settings = get_settings()
# form = """<!DOCTYPE html>
# <html lang="en-us">
# <head>
# <meta http-equiv="content-type" content="text/html; charset=utf-8">
# <title>Payment</title>
# </head>
# <body>
# <script>
# //document.write("Hello World!")
# </script>
# <noscript>Your browser does not support JavaScript!</noscript>
# </body>
# </html>
# """.format(
# url=settings["_host"],
# time_stamp=request_data['timeStamp'],
# tx_id=result['tx_id'],
# merchant_token=request_data['merchantToken'],
# card_no=self.invoice_det.card_no,
# card_exp=self.card_exp,
# card_cvv=self.card_cvv,
# card_holder_nm=self.card_name,
# call_back_url=call_back_url,
# )
# result['form'] = form
if self.pay_method == "02":
result["va"] = dict(
vacct_no=response['vacctNo'],
valid_date=response['vacctValidDt'],
valid_time=response['vacctValidTm'],
)
self.invoice_det.card_no = response['vacctNo']
......@@ -289,103 +292,338 @@ class Vendor(VendorClass): #VendorClass
pay_no=response['payNo'],
valid_date=response['payValidDt'],
valid_time=response['payValidTm'],
)
self.invoice_det.card_no = response['payNo']
elif self.pay_method == "04":
# clickpay
result["receipt_code"]=response['receiptCode']
elif self.pay_method == "05":
# e-wallet
result["receipt_code"]='receiptCode' in response and response['receiptCode'] or ''
elif self.pay_method == "06":
# akulaku
pass
# elif self.pay_method == "04":
# # clickpay
# result["receipt_code"]=response['receiptCode']
# elif self.pay_method == "05":
# # e-wallet
# result["receipt_code"]='receiptCode' in response and response['receiptCode'] or ''
# elif self.pay_method == "06":
# # akulaku
# pass
self.result = result
# self.save_log('inquiry')
self.invoice_det.tx_id=response["tXid"]
self.invoice_det.trans_dt=response["transDt"]
self.invoice_det.trans_tm=response["transTm"]
self.save_log(typ="inquiry")
return dict(data=result)
def payment(self):
def payment(self, data):
Nicepay.requestData = {}
Nicepay.merchantKey = self.key
self.set_static_params()
# Nicepay.set('referenceNo', self.invoice_det.cust_inv_no)
# Nicepay.set('amt', self.invoice_det.amt_sell)
# Nicepay.set('merchantToken', Nicepay.merchantToken())
# Nicepay.set('callBackUrl', self.callback_url)
# Nicepay.set('tXid', str(self.invoice_det.vend_inv_no) or '')
url = "{}/payment".format(self.url)
return HTTPFound(url)
# https://api.nicepay.co.id/nicepay/direct/v2/registration
# Request Body
"""
{
"deliveryPhone": "62-21-0000-0000",
"mitraCd": "ALMA",
"fee": "0",
"amt": "1000",
"description": "this is test transaction!!",
"notaxAmt": "0",
"reqDomain": "localhost",
"userLanguage": "ko-KR,en-US;q=0.8,ko;q=0.6,en;q=0.4",
"vacctValidDt": "",
"billingEmail": "no-reply@ionpay.net",
"merFixAcctId": "",
"payMethod": "01",
"deliveryAddr": "Jalan Jenderal Gatot Subroto Kav.57",
"billingCountry": "ID",
"userIP": "0:0:0:0:0:0:0:1",
"instmntMon": "1",
"currency": "IDR",
"payValidDt": "",
"deliveryCity": "Jakarta",
"merchantToken": "b5149659e1a2f1271fb0833f8ea20e174b6fd389db26bc6ad036cc0dae6fa797",
"goodsNm": "T-1000",
"referenceNo": "OrdNo2017717942577",
"vat": "0",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/60.0.3112.101 Safari/537.36",
"billingState": "Jakarta",
"userSessionID": "697D6922C961070967D3BA1BA5699C2C",
"instmntType": "1",
"deliveryNm": "HongGilDong",
"deliveryPostCd": "12950",
"reqClientVer": "",
"iMid": "IONPAYTEST",
"billingNm": "HongGilDong",
"timeStamp": "20170822170942",
"dbProcessUrl": "http://127.0.0.1:8080/nicepay/test3/dbProcess.do",
"payValidTm": "",
"cartData": "{“count”: “1”,
“item”: [{“img_url”: “https://www.lecs.com/image/introduction/img_vmd020101.jpg”,
“goods_name”: “Jam Tangan Army - Strap Kulit - Hitam”,
“goods_detail”: “jumlah 1”,
“goods_amt”: “400”}]}",
"deliveryState": "Jakarta",
"deliveryCountry": "ID",
"bankCd": "",
"billingPostCd": "12950",
"billingAddr": "Jalan Jenderal Gatot Subroto Kav.57",
"reqServerIP": "172.29.2.178",
"vacctValidTm": "",
"billingPhone": "021-579-00000",
"billingCity": "Jakarta"
if self.pay_method == '01':
if not req_fields(data, ["card_no", "callback_url", "card_exp",
"card_name", "card_cvv"]):
return
self.invoice_det.card_no = data["card_no"]
self.invoice_det.callback_url = data["callback_url"]
flush_row(self.invoice_det)
#
# Nicepay.set('cardNo', str(self.invoice_det.card_no) or '')
# Nicepay.set('cardExpYymm', str(data["card_exp"]) or '')
# Nicepay.set('cardCvv', str(data["card_cvv"]) or '')
# Nicepay.set('cardHolderNm', str(data["card_name"]) or '')
request_data = Nicepay.requestData
script = """
function submit_form(){
$("form[name='payment']").submit();
}
$(window).load(function(){
submit_form();
});
"""
#/api/merchant/payment
form = """
<form action="{url}" method="post" name="payment">
<input type="hidden" name="timeStamp" value="{time_stamp}">
<input type="hidden" name="tXid" value="{tx_id}">
<input type="hidden" name="merchantToken" value="{merchant_token}">
<input type="hidden" name="cardNo" value="{card_no}">
<input type="hidden" name="cardExpYymm" value="{card_exp}">
<input type="hidden" name="cardCvv" value="{card_cvv}">
<input type="hidden" name="cardHolderNm" value="{card_holder_nm}">
<input type="hidden" name="callBackUrl" value="{call_back_url}">
</form>
<script>
{script}
</script>
<noscript>Your browser does not support JavaScript!</noscript>
""".format(
url=url,
time_stamp=self.invoice_det.inv_time_stamp,
tx_id=self.invoice_det.vend_inv_no,
merchant_token=request_data['merchantToken'],
card_no=self.invoice_det.card_no,
card_exp=str(data["card_exp"]),
card_cvv=str(data["card_cvv"]),
card_holder_nm=str(data["card_name"]),
call_back_url=self.callback_url,
script=script
)
elif self.pay_method == '04':
if not req_fields(data, ["cp_no", "item3", "cp_token",
"callback_url"]):
return
self.invoice_det.card_no = data["cp_no"]
self.invoice_det.callback_url = data["callback_url"]
flush_row(self.invoice_det)
request_data = Nicepay.requestData
script = """
function submit_form(){
$("form[name='payment']").submit();
}
// Response Body
{
"resultCd": "0000",
"resultMsg": "SUCCESS",
"tXid": "IONPAYTEST01201708221510237472",
"referenceNo": "OrdNo2017717942577",
"payMethod": "01",
"amt": "1000",
"transDt": "20170822",
"transTm": "171029",
"description": "this is test transaction!!",
"bankCd": null,
"vacctNo": null,
"mitraCd": null,
"payNo": null
….
$(window).load(function(){
submit_form();
});
"""
# /api/merchant/payment
form = """
<form action="{url}" method="post" name="payment">
<input type="hidden" name="timeStamp" value="{time_stamp}">
<input type="hidden" name="tXid" value="{tx_id}">
<input type="hidden" name="clickPayNo" value="{cp_no}">
<input type="hidden" name="dataField3" value="{item3}">
<input type="hidden" name="clickPayToken" value="{cp_token}">
<input type="hidden" name="merchantToken" value="{merchant_token}">
<input type="hidden" name="callBackUrl" value="{call_back_url}">
</form>
<script>
{script}
</script>
<noscript>Your browser does not support JavaScript!</noscript>
""".format(
url=url,
time_stamp=self.invoice_det.inv_time_stamp,
tx_id=self.invoice_det.vend_inv_no,
merchant_token=request_data['merchantToken'],
cp_no=self.invoice_det.card_no,
item3=str(data["item3"]),
cp_token=str(data["cp_token"]),
call_back_url=self.callback_url,
script=script
)
elif self.pay_method == '05':
if not req_fields(data, ["callback_url"]):
return
self.invoice_det.callback_url = data["callback_url"]
flush_row(self.invoice_det)
request_data = Nicepay.requestData
script = """
function submit_form(){
$("form[name='payment']").submit();
}
$(window).load(function(){
submit_form();
});
"""
# /api/merchant/payment
form = """
<form action="{url}" method="post" name="payment">
<input type="hidden" name="timeStamp" value="{time_stamp}">
<input type="hidden" name="tXid" value="{tx_id}">
<input type="hidden" name="merchantToken" value="{merchant_token}">
<input type="hidden" name="callBackUrl" value="{call_back_url}">
</form>
<script>
{script}
</script>
<noscript>Your browser does not support JavaScript!</noscript>
""".format(
url=url,
time_stamp=self.invoice_det.inv_time_stamp,
tx_id=self.invoice_det.vend_inv_no,
merchant_token=request_data['merchantToken'],
call_back_url=self.callback_url,
script=script
)
self.request = data
self.save_log("payment")
return dict(form=form)
def callback(self, data):
self.response = data
log.info("Payment Result: {}".format(data))
self.result = get_result(self.response, self.pay_method)
self.save_log("payment")
script = """
function submit_form(){
$("form[name='callback']").submit();
}
$(window).load(function(){
submit_form();
});
"""
# /api/merchant/payment
f = ""
result = self.result
for r in result:
if r and type(result[r])==dict:
rs = result[r]
for s in rs:
f += '<input type="hidden" name="{k}" value="{v}">'.format(k=s, v=rs[s])
else:
f += '<input type="hidden" name="{k}" value="{v}">'.format(k=r, v=result[r])
form = """
<form action="{url}" method="post" name="callback">
{f}
<button type="button" value="Submit" name="submit2">Submit</button>
</form>
<script>
{script}
</script>
<noscript>Your browser does not support JavaScript!</noscript>
""".format(
url=self.invoice_det.callback_url,
script=script,
f=f
)
return dict(form=form)
def advice(self):
Nicepay.requestData = {}
self.set_static_params()
Nicepay.set("tXid", self.invoice_det.vend_inv_no)
self.request = Nicepay.requestData
self.save_log("advice")
self.response = Nicepay.niceInquiry()
self.save_log("advice")
self.result = get_result(self.response, self.pay_method)
self.save_log("advice")
def notify(self, data):
amount = self.invoice_det.amt_sell
vend_inv_no = self.invoice_det.vend_inv_no
merchant_token = data["merchantToken"]
signature = sha256("{mid}{vend_inv_no}{amount}{key}" \
.format(mid=self.mid, key=self.key, amount=str(amount),
vend_inv_no=vend_inv_no))
if merchant_token != signature:
return
self.response = data
self.result = get_result(self.response, self.pay_method)
self.save_log("notify")
return self.result
"""
def get_result(response, pay_method):
result = dict(
code=int(response["resultCd"]),
message=response["resultMsg"],
# cancel_amt=response["cancelAmt"],
# deposit_date=response["depositDt"],
# deposit_time=response["depositTm"],
)
if pay_method == "01":
result.update(dict(
cc=dict(
auth_no=response["authNo"],
issue_bank=response["issuBankCd"],
issue_bank_nm='issuBankNm' in response and response["issuBankNm"] or "",
acqu_bank=response["acquBankCd"],
acqu_bank_nm='acquBankNm' in response and response["acquBankNm"] or "",
acqu_status='acquStatus' in response and response["acquStatus"] or "",
card_no=response["cardNo"],
card_exp=response["cardExpYymm"],
instmnt_mon=response["instmntMon"],
instmnt_tpe=response["instmntType"],
preauth_token=response["preauthToken"],
recurring_token=response["recurringToken"],
cc_trans_type=response["ccTransType"],
vat="vat" in response and int(response["vat"]) or 0,
fee="fee" in response and int(response["fee"]) or 0,
no_tax_amt="notaxAmt" in response and int(response["notaxAmt"]) or 0,
)
))
"""
Additional Credit Card Response Json Object
Parameter Type Size Description
authNo N 10 Approval Number
issuBankCd A 4 Issue Bank Code, refer Code at Here
acquBankCd A 4 Acquire Bank Code, refer Code at Here
cardNo AN 20 Card No with masking
cardExpYymm N 4 card expiry(YYMM)
instmntMon N 2 Installment month
instmntType N 2 Installment Type, refer Code at Here
preauthToken AN 255 Pre-Auth Token (need for capture)
recurringToken AN 255 Recurring Token (Can use next payment)
ccTransType AN 2 Credit Card Transaction Type
acquStatus AN 2 Purchase Status
1: Normal
2: Recurring
3: Pre-auth
4: Capture
vat N 12 Vat
fee N 12 service fee
notaxAmt N 12 tax free amount
"""
elif pay_method == "02":
"""
Additional Virtual Account Response Json Object
Parameter Type Size Description
bankCd AN 4 Bank Code, refer Code at Here
vacctNo N 16 Bank Virtual Account number
vacctValidDt N 8 VA expiry date (YYYYMMDD)
vacctValidTm N 6 VA expiry time (HH24MISS)
"""
result.update(dict(
va=dict(
vaacct_no=response["vacctNo"],
valid_date=response["vacctValidDt"],
valid_time=response["vacctValidTm"]
)
))
else:
"""
Additional Others Response Json Object
Parameter Type Size Description
mitraCd A 4 Mitra code, refer Code at Here
(CVS, ClickPay, E-Wallet)
payNo N 12 CVS number (CVS)
payValidDt N 8 CVS expiry date (YYYYMMDD) (CVS)
payValidTm N 6 CVS expiry time (HH24MISS) (CVS)
mRefNo AN 20 Bank reference No (CVS)
receiptCode ANS 18 Authorization code (CVS)
"""
other = dict(
pay_no="payNo" in response and response["payNo"] or "",
valid_date="payValidDt" in response and response["payValidDt"] or "",
valid_time="payValidTm" in response and response["payValidTm"] or "",
m_ref_no="mRefNo" in response and response["mRefNo"] or "",
receipt_code="receiptCode" in response and response["receiptCode"] or ""
)
if pay_method == "03":
result.update({"cvs": other})
elif pay_method == "04":
result.update({"cp": other})
elif pay_method == "05":
result.update({"wl": other})
else:
result.update({"pl": other})
return result
def req_fields(data, fields):
for f in fields:
if f not in data or not data[f]:
return
return True
from _sha256 import sha256
import logging
from agratek.api.merchant.views.notify_vendor import purchase_notify, update_harga
from opensipkd.base import get_settings
from opensipkd.base.models import Partner, flush_row
from opensipkd.pasar.models import H2hArInvoiceDet
from opensipkd.pasar.models.produk import PartnerPay
from opensipkd.pasar.models.produk import PartnerPay, PartnerProduk
log = logging.getLogger(__name__)
from . import Vendor
def callback(request):
data = dict(request.POST.items())
tx_id = data["tXid"]
if tx_id:
row = PartnerPay.query_txid(tx_id).first()
return row.callback_url
def proses(data):
code = "resultCd" in data and data["resultCd"] and int(data["resultCd"]) or 0
message = "resultMsg" in data and data["resultMsg"] or ""
if code!=0:
return dict(form="Error in NV CALLBACK {}, {}".format(code, message), code=code, message=message)
vend_inv_no = data["tXid"]
cus_inv_no = data["referenceNo"]
invoice_det = PartnerPay.query_vend_inv_no(vend_inv_no)\
.filter_by(cust_inv_no=cus_inv_no).first()
if not invoice_det:
return
vendor_produk = PartnerProduk.query()\
.filter_by(partner_id=invoice_det.vendor_id,
produk_id=invoice_det.produk_id).first()
vendor = Vendor(vendor_produk, invoice_det)
result = vendor.callback(data)
print("callback.py", result)
return result
from _sha256 import sha256
import logging
from agratek.api.merchant.views.notify_vendor import purchase_notify, update_harga, payment_notify
from opensipkd.base import get_settings
from opensipkd.base.models import Partner, flush_row
from opensipkd.pasar.models import H2hArInvoiceDet
from opensipkd.pasar.models.produk import PartnerPay
from agratek.api.merchant.views.notify_vendor import payment_notify
from opensipkd.pasar.models.produk import PartnerPay, PartnerProduk
log = logging.getLogger(__name__)
from . import Vendor
def proses(data):
settings = get_settings()
mid = 'np_mid' in settings and settings["np_mid"] or None
key = 'np_key' in settings and settings["np_key"] or None
partner = Partner.query_kode("NP").first()
status = str(data["status"])
amount = data["amt"]
tx_id = data["tXid"]
merchant_token = data["merchantToken"]
ref_no = data["referenceNo"]
signature = sha256("{mid}{tx_id}{amount}{key}"\
.format(mid=mid, key=key, amount=str(amount),
tx_id=tx_id))
if merchant_token!=signature:
return
pay = PartnerPay.query_txid(tx_id).filter(cust_inv_no=ref_no).first()
if not pay:
return
result=dict()
pay.notify= dict(response=data,
result=result)
pay.status = 1
flush_row(pay)
payment_notify(pay)
return pay
"""
Common Parameter for Notification
Parameter Type Size Description
tXid N 30 Transaction ID
merchantToken AN 255 Merchant Token
referenceNo N 40 Merchant Order No
payMethod N 2 Payment method. Refer Code at Here
amt N 12 Payment amount
transDt N 8 Transaction date
transTm N 6 Transaction time
currency N 3 Currency
goodsNm N 100 Goods name
billingNm N 30 Billing name
matchCl N 1 Payment amount match flag. Refer Code at Here
status AN 1 Deposit Status
0: Deposit
1: Reversal
Additional Parameter for Credit Card Notification
Parameter Type Size Description
authNo N 10 Approval number
IssueBankCd A 4 Issue bank code. Refer Code at Here
IssueBankNm A Issue bank name.
acquBankCd A Acquire bank code. Refer Code at Here
acquBankNm A Acquire bank name.
cardNo AN 20 Card no with masking
cardExpYymm N Card expiry (YYMM)
instmntMon N 2 Installment month
instmntType N 2 Installment Type. Refer Code at Here
preauthToken AN 255 Preauth Token
recurringToken AN 255 Recurring token
ccTransType AN 2 Credit card transaction type
1: Normal
2: Recurring
3: Pre-auth
4: Captured
vat N 12 Vat number
fee N 12 service fee
notaxAmt N 12 tax free amount
Additional Parameter for Virtual Account Notification
Parameter Type Size Description
bankCd N 4 Bank Code. Refer Code at Here
vacctNo N 16 Bank Virtual Account number
vacctValidDt N 8 VA expiry date
vacctValidTm N 6 VA expiry time
depositDt N Deposit date
depositTm N Deposit time
Additional Parameter for Others Payment Method Notification
vend_inv_no = data["tXid"]
cus_inv_no = data["referenceNo"]
invoice_det = PartnerPay.query_vend_inv_no(vend_inv_no)\
.filter(cust_inv_no=cus_inv_no)
vendor_produk = PartnerProduk.query()\
.filter_by(partner_id=invoice_det.vendor_id,
produk_id=invoice_det.produk_id)
vendor = Vendor(vendor_produk, invoice_det)
vendor.notify(data)
return payment_notify(invoice_det)
Parameter Type Size Description
mitraCd A 4 Mitra Code. Refer Code at Here
payNo N 12 Pay number to mitra
payValidDt N 8 CVS expiry date
payValidTm N 6 CVS expiry time
receiptCode ANS 20 Authorization number
mRefNo AN 18 Bank reference No
depositDt N Deposit date
depositTm N Deposit time
"""
......@@ -70,7 +70,7 @@ def form_validator(form, value):
def get_form(request, class_form, buttons=None, row=None):
schema = class_form(validator=form_validator)
schema = schema.bind(produk=Produk.get_e_list(),
schema = schema.bind(produk=Produk.get_list(),
vendor=Partner.get_vendor_list(),
departemen=Departemen.get_list())
schema.request = request
......
<html metal:use-macro="load: base-no-menu.pt">
<html metal:use-macro="load: opensipkd.base:views/templates/base3-clean.pt">
<div metal:fill-slot="scripts">
${structure:form}
</div>
</html>
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!