source: main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/etranzact/helpers.py @ 15589

Last change on this file since 15589 was 15589, checked in by Henrik Bettermann, 5 years ago

Backup work. Waiting for answers from eTranzact.

  • Property svn:keywords set to Id
File size: 6.3 KB
Line 
1## $Id: helpers.py 15589 2019-09-17 18:31:10Z henrik $
2##
3## Copyright (C) 2017 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18"""General helper functions for the etranzact module in custom packages.
19"""
20import grok
21import re
22from datetime import datetime
23from urllib import urlencode
24import httplib
25import hashlib
26import json
27
28from zope.event import notify
29from kofacustom.nigeria.interfaces import MessageFactory as _
30
31def write_payments_log(id, payment):
32    payment.logger.info(
33        '%s,%s,%s,%s,%s,%s,%s,%s,,,' % (
34        id, payment.p_id, payment.p_category,
35        payment.amount_auth, payment.r_code,
36        payment.provider_amt, payment.gateway_amt,
37        payment.thirdparty_amt))
38
39def query_history(host, terminal_id, transaction_id, https, responseurl):
40    headers={"Content-type": "application/x-www-form-urlencoded",
41             "Accept": "text/plain"}
42    url = "/webconnect/v3/query.jsp"
43    if https:
44        h = httplib.HTTPSConnection(host)
45    else:
46        h = httplib.HTTPConnection(host)
47    args = {'TERMINAL_ID': terminal_id,
48            'TRANSACTION_ID': transaction_id,
49            }
50    #args['RESPONSE_URL'] = responseurl
51    h.request('POST', url, urlencode(args), headers)
52    response = h.getresponse()
53    if response.status!=200:
54        return 'Connection error (%s, %s)' % (response.status, response.reason)
55    resp = response.read()
56    resp = resp.replace('\r\n','')
57    # eTranzact sends strange HTML tags which must be removed.
58    resp = re.sub("<.*?>", "", resp)
59    return resp
60
61 # A sample caller response sent to the RESPONSE_URL
62
63 # http://salsa:8080/app/applicants/cbt2015/449072/p5679522929425/receive_etranzact?
64 # AMOUNT=3333.0&
65 # DESCRIPTION=&
66 # CHECKSUM=8aab3904652f8ba69ebed42d3bae80a2&
67 # EMAIL=aa%40aa.de&
68 # SUCCESS=C&
69 # MESSAGE=Cancel&
70 # LOGO_URL=https%3A%2F%2Fiuokada.waeup.org%2Fstatic_custom%2Fiou_logo.png&
71 # RESPONSE_URL=http%3A%2F%2Fsalsa%3A8080%2Fapp%2Fapplicants%2Fcbt2015%2F449072%2Fp5679522929425%2Freceive_etranzact&
72 # CURRENCY_CODE=NGN&
73 # TERMINAL_ID=0000000001&
74 # TRANSACTION_ID=p5679522929425&
75 # MERCHANT_CODE=0339990001&
76 # RESPONSE_CODE=C&
77 # FINAL_CHECKSUM=E524590DBFAB719EEE428C778FFF1650&
78 # STATUS_REASON=Cancel&
79 # TRANS_NUM=01ESA20190913062149AHGUHQ&
80 # CARD_NO=null&
81 # CARD_TYPE=null
82
83  # A sample query response sent to the RESPONSE_URL
84
85 # http://salsa:8080/app/applicants/cbt2015/449072/p5686487280654/receive_etranzact?
86 # LOGO_URL=https%3A%2F%2Fiuokada.waeup.org%2Fstatic_custom%2Fiou_logo.png&
87 # RESPONSE_URL=http%3A%2F%2Fsalsa%3A8080%2Fapp%2Fapplicants%2Fcbt2015%2F449072%2Fp5686487280654%2Freceive_etranzact&
88 # CURRENCY_CODE=NGN&
89 # TERMINAL_ID=0000000001&
90 # TRANSACTION_ID=p5686487280654&
91 # AMOUNT=3333.0&
92 # DESCRIPTION=&
93 # CHECKSUM=3886118fcd91a376cc95c48c94dc499a&
94 # MERCHANT_CODE=0339990001&
95 # EMAIL=aa%40aa.de&
96 # SUCCESS=0&
97 # FINAL_CHECKSUM=EE105B703F84B1D67D0A4234622C03E8&
98 # STATUS_REASON=Approved&
99 # TRANS_NUM=01ESA20190916164636L2UTU7&
100 # CARD_NO=506066XXXXXXXXX6666&
101 # CARD_TYPE=Verve
102
103def process_response(payment, form, view, verify):
104    success = form.get('RESPONSE_CODE', None)
105    if not success:
106        msg = _('No valid response from eTranzact.')
107        log = 'No valid response from eTranzact for payment %s' % payment.p_id
108        payment.p_state = 'failed'
109        notify(grok.ObjectModifiedEvent(payment))
110        return False, msg, log
111    # Compute final checksum
112    transaction_id = payment.p_id
113    amount = "%.1f" % payment.amount_auth
114    responseurl = view.url(payment, 'receive_etranzact')
115    hashargs =  success + amount + view.terminal_id + transaction_id \
116        + responseurl + view.secret_key
117    final_checksum = hashlib.md5(hashargs).hexdigest().upper()
118    if form.get('FINAL_CHECKSUM', None) != final_checksum:
119        msg = _('Wrong checksum.')
120        log = 'wrong checksum for %s payment %s: %s' % (
121            payment.p_category, payment.p_id, str(form))
122        return False, msg, log
123    payment.r_code = form.get('RESPONSE_CODE', None)
124    payment.r_desc = form.get('STATUS_REASON', None) # MESSAGE also available
125    payment.r_amount_approved = float(form.get('AMOUNT', None))
126    payment.r_pay_reference = form.get('TRANS_NUM', None)
127    payment.r_card_num = "%s %s" % (form.get('CARD_TYPE', None),
128                                    form.get('CARD_NO', None))
129    payment.r_company = u'etranzact'
130    if payment.r_code != '0':
131        msg = _('Unsuccessful response: ${a}', mapping = {'a': payment.r_desc})
132        log = 'unsuccessful response for %s payment %s: %s' % (
133            payment.p_category, payment.p_id, payment.r_desc)
134        payment.p_state = 'failed'
135        notify(grok.ObjectModifiedEvent(payment))
136        return False, msg, log
137    if round(payment.r_amount_approved/10.0, 0) != round(
138        payment.amount_auth/10.0, 0):
139        msg = _('Response amount does not match.')
140        log = 'wrong response for %s payment %s: %s' % (
141            payment.p_category, payment.p_id, str(form))
142        payment.p_state = 'failed'
143        notify(grok.ObjectModifiedEvent(payment))
144        return False, msg, log
145    transaction_id = form.get('TRANSACTION_ID', None)
146    if transaction_id != payment.p_id:
147        msg = _('Response transaction id does not match.')
148        log = 'wrong response for %s payment %s: %s' % (
149            payment.p_category, payment.p_id, str(form))
150        payment.p_state = 'failed'
151        notify(grok.ObjectModifiedEvent(payment))
152        return False, msg, log
153    payment.p_state = 'paid'
154    if not verify:
155        payment.payment_date = datetime.utcnow()
156    msg = _('Successful response received')
157    log = 'valid response for %s payment %s: %s' % (
158        payment.p_category, payment.p_id, str(form))
159    notify(grok.ObjectModifiedEvent(payment))
160    return True, msg, log
Note: See TracBrowser for help on using the repository browser.