pay.py
21.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
import colander
from deform import widget, Form
from opensipkd.base.views import BaseView
from pyramid.view import view_config
from pyramid.httpexceptions import HTTPFound
from opensipkd.pasar.models.produk import H2hArInvoice, H2hArInvoiceDet, PartnerLog, PartnerPay, Partner
from opensipkd.pasar.models import DBSession, flush_row
from .api_payment import set_register_values, build_register
from .api_merchant import get_vendor_produk
from datetime import datetime, timedelta
from opensipkd.base import get_settings
from ..tools import json_rpc_header
import requests
import json
from ..pay_request_tools import methods, vacs, cvss, loans, cps, ems, get_str_hari, get_str_bulan, VA_IMG_SRC
class VaSchema(colander.Schema):
va_opt = colander.SchemaNode(colander.String(), title = "Pilih Layanan", missing=colander.drop)
va_valid_date = colander.SchemaNode(colander.String(), title = "Tanggal Valid", missing=colander.drop, widget=widget.HiddenWidget())
va_valid_time = colander.SchemaNode(colander.String(), title = "Jam Valid", missing=colander.drop, widget=widget.HiddenWidget())
class CcSchema(colander.Schema):
cc_instmnt_type = colander.SchemaNode(colander.String(), title = "Installment type", missing=colander.drop)
cc_instmnt_mon = colander.SchemaNode(colander.String(), title = "Installment month", missing=colander.drop)
cc_recurr_opt = colander.SchemaNode(colander.String(), title = "Recurring Option", missing=colander.drop)
class CvsSchema(colander.Schema):
cvs_opt = colander.SchemaNode(colander.String(), title = "Pilih Layanan", missing=colander.drop)
cvs_valid_date = colander.SchemaNode(colander.String(), title = "Tanggal Valid", missing=colander.drop)
cvs_valid_time = colander.SchemaNode(colander.String(), title = "Jam Valid", missing=colander.drop)
class LoanSchema(colander.Schema):
loan_opt = colander.SchemaNode(colander.String(), title = "Pilih Layanan", missing=colander.drop)
loan_instmnt_type = colander.SchemaNode(colander.String(), title = "Installment type", missing=colander.drop)
loan_instmnt_mon = colander.SchemaNode(colander.String(), title = "Installment month", missing=colander.drop)
loan_recurr_opt= colander.SchemaNode(colander.String(), title = "Recurring option", missing=colander.drop)
loan_valid_date = colander.SchemaNode(colander.String(), title = "Expiry date", missing=colander.drop)
loan_valid_time = colander.SchemaNode(colander.String(), title = "Expiry Time", missing=colander.drop)
class CpSchema(colander.Schema):
cp_opt = colander.SchemaNode(colander.String(), title = "Pilih Layanan", missing=colander.drop)
cp_merc_ref_no = colander.SchemaNode(colander.String(), title = "Merc. Ref. No.", missing=colander.drop)
class EmSchema(colander.Schema):
em_opt = colander.SchemaNode(colander.String(), title = "Pilih Layanan", missing=colander.drop)
class FormSchema(colander.Schema):
pay_method = colander.SchemaNode(colander.String(), title = "Metode Pembayaran", missing=colander.drop, widget=widget.HiddenWidget())
biller_name = colander.SchemaNode(colander.String(), title = "Biller", missing=colander.drop, widget=widget.HiddenWidget())
amount_tot = colander.SchemaNode(colander.String(), title = "Amount", missing=colander.drop, widget=widget.HiddenWidget())
customer_name = colander.SchemaNode(colander.String(), title = "Customer", missing=colander.drop, widget=widget.HiddenWidget())
def encode_to_json(form_request_data, parsed_produks):
decoded_dict = {}
print('isi form_request_data dalam encode_to_json >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
print(form_request_data)
customer_req = {}
deliver_to = {}
server = {}
for key in form_request_data:
if key[-5:] == '_cust':
customer_req[key.replace('_cust', '')] = form_request_data[key]
elif key[-8:] == '_deliver':
deliver_to[key.replace('_deliver', '')] = form_request_data[key]
elif key[-8:] == '_server':
server[key.replace('_server', '')] = form_request_data[key]
else:
decoded_dict[key] = form_request_data[key]
produks = parsed_produks
decoded_dict['customer'] = customer_req
decoded_dict['deliver_to'] = deliver_to
decoded_dict['server'] = server
decoded_dict['produk'] = produks
return decoded_dict
def whatisthis(s):
if isinstance(s, str):
print("ordinary string")
elif isinstance(s, unicode):
print("unicode string")
else:
print("not a string")
class view_pay(BaseView):
@view_config(route_name = 'pay-form', renderer = 'templates/pay.pt')#permission = 'pay-form',
@view_config(route_name = 'pay-form', renderer = 'json', request_param='pay=pay')#permission = 'pay-form',
# class view_pay():
def the_form(self):
request = self.req
session = self.ses
url_dict = request.matchdict
data_form = {}
post_data = request.POST
items = dict(post_data)
produks = []
if post_data:
if 'bayar' in post_data:
#getting saved data from pay_request
row_pay = DBSession.query(PartnerPay).filter(PartnerPay.token_pay_req == url_dict['pay_token']).first()
#target to send the register response
merchant_url = row_pay.response_url
#getting the merchant data
customer = Partner.query().filter(Partner.id == row_pay.customer_id).first()
#getting the merchant authentication data
registered_user = customer.users
produk_kd = ''
#parsing payment method from pay Form
mth = post_data['pay_method']
denom = ''
if mth == 'VA':
denom = items['va_opt']
elif mth == 'CC':
denom = mth
elif mth == 'CVS':
denom = items['cvs_opt']
elif mth == 'EM':
denom = items['em_opt']
elif mth == 'loan':
denom = items['loan_opt']
elif mth == 'CP':
denom = items['cp_opt']
#getting saved cart json
# building register json request
basic_json = build_request_json(denom, row_pay, produks)
if mth == 'VA':
# row.inv_valid_date='va_valid_date' in items and items['va_valid_date'] or dt
# row.inv_valid_time='va_valid_time' in items and items['va_valid_time'] or tm
# row.inv_cust_va='va_fix_acct_id' in items and items['va_fix_acct_id'] or ''
# ccard = None
#adding additional packed element based on payment method
hours_24_from_now = datetime.now() + timedelta(hours=24)
dt = format(hours_24_from_now, '%Y%m%d')
tm = format(hours_24_from_now, '%H%M%S')
adt_va = {}
adt_va['va'] = dict(
valid_date = dt,
valid_time = tm,
fix_acct_id = ""
)
set_pay_detail(basic_json, adt_va)
elif mth == 'CC':
# row.instmnt_mon='cc_instmnt_mon' in items and items['cc_instmnt_mon'] or ''
# row.instmnt_type='cc_instmnt_type' in items and items['cc_instmnt_type'] or ''
# row.recurr_opt='cc_recurr_opt' in items and items['cc_recurr_opt'] or 0
adt_cc = {}
adt_cc['credit_card'] = dict(
instmnt_type = '2',
instmnt_mon = '1',
recurr_opt = '2'
)
set_pay_detail(basic_json, adt_cc)
ccard = None
agratek_api_url = get_api_url()
headers_register = json_rpc_header(registered_user.user_name, registered_user.api_key)
result_request = {}
try:
result_request = requests.post(agratek_api_url, data=json.dumps(basic_json), headers = headers_register, timeout=20)
except Exception as e:
print('error request register >')
print(e)
err_param = ''
# info params:
subject = ''
content = ''
amount = 0
dt_tm_str = ''
img_src = ''
meth_str = ''
# >>>>>>>>>>>>>
if result_request:
dict_results = json.loads(result_request.text)
if 'result' in dict_results:
state = int(dict_results['result']['code'])
# vacct_no
if state == 0:
# updating additional necessary datas to partner_pay after done and succeed register method
# getting new mapped data
# populating datas for info
subject = 'No. Virtual Account'
content = dict_results['result']['va']['vacct_no']
print('isi dict_results>>')
print(dict_results['result'])
# amount = dict_results['result']['amount'] + dict_results['result']['fee']
amount = dict_results['result']['amount']
amount = format(int(amount), ',d').replace(',', '.')
va_dt = dict_results['result']['va']['valid_date']
va_tm = dict_results['result']['va']['valid_time']
va_dt = datetime.strptime(va_dt, "%Y%m%d").date()
hari_str = get_str_hari(va_dt.day, va_dt.month, va_dt.year)
bulan_str = get_str_bulan(va_dt.month)
va_tm = datetime.strptime(va_tm, "%H%M%S").time()
jam_str = str(va_tm.hour) + str(va_tm.minute)
# Jum'at, 27 Desember 2019, Pukul 04:44 WIB
dt_tm_str = hari_str + ', ' + str(va_dt.day) + ' ' + bulan_str + ' ' + str(va_dt.year) + ', Pukul ' + str(va_tm) + ' WIB'
denom_str = denom
layanan = denom_str.split('-')[1]
img_src = VA_IMG_SRC[layanan]
meth = mth
meth_str = dict(methods)[meth] + ', ' + dict(vacs)[denom_str]
# populating datas for info >>>>>> end >>>>>>>>>.
produks = row_pay.cart
produks_items = []
for item in produks['item']:
produk_item = {}
produk_item['goods_name'] = item['goods_name']
produk_item['goods_detail'] = item['goods_detail']
produk_item['goods_amt'] = item['goods_amt']
produk_item['img_url'] = item['img_url']
produks_items.extend([produk_item])
row_pay_payed = DBSession.query(PartnerPay).filter(PartnerPay.token_pay_req == url_dict['pay_token']).first()
values_update = dict(
cart = {'count': produks['count'], 'item': tuple(produks['item'])},
pay_token_date_exp = dt,
pay_token_time_exp = tm,
pay_req_mth = mth,
pay_denom = denom,
)
row_pay_payed.from_dict(values_update)
flush_row(row_pay_payed)
else:
err_param = '?adt=fail'
elif 'error' in dict_results:
state = int(dict_results['error']['code'])
err_param = '?adt=fail'
else:
state = 999999
err_param = '?adt=fail'
route_to = request.route_url(route_name='pay-info', pay_token = url_dict['pay_token'], state = state)
route_to = route_to + err_param
if merchant_url and merchant_url != '':
headers_merchant = {}
headers_merchant['Content-Type'] = 'application/json'
headers_merchant = headers_merchant
try:
requests.post(merchant_url, data=result_request.text, headers = headers_merchant, timeout=10)
except Exception as e:
pass
print('at last >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>')
return dict(
state = state,
subject = subject,
content = content,
amount = amount,
dt_tm_str = dt_tm_str,
img_src = img_src,
meth_str = meth_str
)
# return HTTPFound(route_to)
elif 'batal' in post_data:
return HTTPFound(location=request.route_url('api-merchant-home'))
formSchema = FormSchema()
formSchema.request = request
form = Form(formSchema)
row = DBSession.query(
PartnerPay.biller_name,
PartnerPay.amt_sell,
PartnerPay.inv_cust_nm,
PartnerPay.cart,
).filter(PartnerPay.token_pay_req == url_dict['pay_token']).first()
data_form['biller_name'] = row.biller_name
data_form['amount_tot'] = row.amt_sell
data_form['amount_tot_th'] = format(int(data_form['amount_tot']), ',d').replace(',', '.')
data_form['customer_name'] = row.inv_cust_nm
produks = row.cart['item']
for trans in produks:
trans['goods_amt'] = format(int(trans['goods_amt']), ',d').replace(',', '.')
trans['subtotal'] = format(int(trans['subtotal']), ',d').replace(',', '.')
form.render(data_form)
vaSchema = VaSchema()
vaSchema.request = request
formVa = Form(vaSchema)
formCC = CcSchema()
formCC.request = request
formCC = Form(formCC)
formCvs = CvsSchema()
formCvs.request = request
formCvs = Form(formCvs)
formCp = CpSchema()
formCp.request = request
formCp = Form(formCp)
formLoan = LoanSchema()
formLoan.request = request
formLoan = Form(formLoan)
formEm = EmSchema()
formEm.request = request
formEm = Form(formEm)
return dict(
pay_info = False,
form = form,
formVa = formVa,
formCC = formCC,
formCvs = formCvs,
formCp = formCp,
formLoan = formLoan,
formEm = formEm,
meth = methods,
vacs = vacs,
cvss = cvss,
loans = loans,
cps = cps,
ems = ems,
formData = data_form,
produks = produks,
)
def get_api_url():
settings = get_settings()
hostnya = settings['_host']
# hostnya = 'https://devel.agratek.id'
url = hostnya + "/api/merchant"
return url
def set_pay_detail(the_basic_json, pay_method_json):
data = the_basic_json['params']['data']
data.update(pay_method_json)
def build_request_json(denom, row, produks):
time_stamp = datetime.now().strftime('%Y%m%d%H%M%S')
req_dt = datetime.now().strftime('%Y%m%d')
req_tm = datetime.now().strftime('%H%M%S')
body = {
"jsonrpc": "2.0",
"id": "1",
"method": "register",
"params": {
"data": {
"denom": denom,
"time_stamp": time_stamp,
"currency": "IDR",
"amount": row.amt_sell,
"invoice_no": row.cust_inv_no,
"description": row.description,
"fee": row.fee,
"vat": row.vat,
"notax_amt": row.notax_amt or 0,
"req_dt": req_dt,
"req_tm": req_tm,
"biller": {
"name": row.biller_name or "",
"phone": row.biller_phone or "",
"email": row.biller_email or "",
"address": row.biller_address or "",
"city": row.biller_city or "",
"state": row.biller_state or "",
"post_code": row.biller_post_code or "",
"country": row.biller_country or ""
},
"customer": {
"name": row.inv_cust_nm or "",
"phone": row.inv_cust_phone or "",
"email": row.inv_cust_email or "",
"address": row.inv_cust_addr or "",
"city": row.inv_cust_city or "",
"state": row.inv_cust_state or "",
"post_code": row.inv_cust_pos or "",
"country": row.inv_cust_country or "",
"ip": row.server_ip or "",
"session_id": row.inv_cust_session or "",
"agent": row.inv_cust_agent or "",
"language": "en-US"
},
"deliver_to": {
"name": row.delivery_nm or "",
"phone": row.delivery_phone or "",
"email": row.delivery_email or "",
"address": row.delivery_addr or "",
"city": row.delivery_city or "",
"state": row.delivery_state or "",
"post_code": row.delivery_pos or "",
"country": row.delivery_country or ""
},
"cart": produks,
"server": {
"domain": row.domain or "",
"ip": row.server_ip or ""
}
}
}
}
return body
# {
# "error": {
# "code": -32600,
# "message": "invalid request"
# },
# "id": null,
# "jsonrpc": "2.0"
# }
# {
# "result": {
# "time_stamp": "20200116155500",
# "deliver_to": {
# "state": "",
# "post_code": "",
# "phone": "",
# "city": "",
# "name": "safasf",
# "email": "",
# "country": "Indonesia",
# "address": ""
# },
# "description": "Test Transaction Pasarqu",
# "amount": "35000",
# "trans_time": "155501",
# "customer": {
# "state": "",
# "post_code": "",
# "phone": "",
# "agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
# "session_id": "697D6922C961070967D3BA1BA5699C2C",
# "city": "",
# "country": "Indonesia",
# "email": "",
# "name": "ffsdfsfsf",
# "language": "en-US",
# "ip": "127.0.0.1",
# "address": ""
# },
# "code": 0,
# "notax_amt": 0,
# "trans_date": "20200116",
# "va": {
# "valid_time": "155500",
# "valid_date": "20200117",
# "vacct_no": "70014000091555018516"
# },
# "message": "SUCCESS",
# "fee": 0,
# "biller": {
# "state": "",
# "post_code": "",
# "phone": "",
# "city": "",
# "name": "dsafsfa",
# "email": "",
# "country": "",
# "address": ""
# },
# "currency": "IDR",
# "denom": "VA-MANDIRI",
# "invoice_no": "300bssx5t",
# "server": {
# "ip": "127.0.0.1",
# "domain": "merchant.com"
# },
# "vat": 0,
# "cart": {
# "count": 3,
# "item": [
# {
# "goods_detail": "E-Pulsa",
# "goods_amt": "25225",
# "goods_name": "Pulsa Telkomsel 25.000",
# "img_url": "https://i1.wp.com/resepkoki.id/wp-content/uploads/2017/09/Jeruk-mandarin.jpg"
# },
# {
# "goods_detail": "E-Pulsa",
# "goods_amt": "149575",
# "goods_name": "Pulsa Telkomsel 150.000",
# "img_url": "https://www.bantennews.co.id/wp-content/uploads/2019/09/Screenshot_2019-09-24-23-48-36-251_org.detikcom.rss_.jpg"
# },
# {
# "goods_detail": "E-Pulsa",
# "goods_amt": "50050",
# "goods_name": "Pulsa Telkomsel 50.000",
# "img_url": "https://blog.regopantes.com/wp-content/uploads/2019/02/apel-fuji-via-pixabay.jpg"
# }
# ]
# },
# "req_tm": "155500",
# "tx_id": "adminc8e2905791584c97548b360bc4adac577544bc4c5df41e01fa97d26add2fe90f",
# "req_dt": "20200116"
# },
# "id": "1",
# "jsonrpc": "2.0"
# }