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

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

Update tests.

  • Property svn:keywords set to Id
File size: 6.2 KB
Line 
1## $Id: helpers.py 15593 2019-09-19 10:12:53Z 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    return resp
57
58 # A sample caller response sent to the RESPONSE_URL
59
60 # http://salsa:8080/app/applicants/cbt2015/449072/p5679522929425/receive_etranzact?
61 # AMOUNT=3333.0&
62 # DESCRIPTION=&
63 # CHECKSUM=8aab3904652f8ba69ebed42d3bae80a2&
64 # EMAIL=aa%40aa.de&
65 # SUCCESS=C&
66 # MESSAGE=Cancel&
67 # LOGO_URL=https%3A%2F%2Fiuokada.waeup.org%2Fstatic_custom%2Fiou_logo.png&
68 # RESPONSE_URL=http%3A%2F%2Fsalsa%3A8080%2Fapp%2Fapplicants%2Fcbt2015%2F449072%2Fp5679522929425%2Freceive_etranzact&
69 # CURRENCY_CODE=NGN&
70 # TERMINAL_ID=0000000001&
71 # TRANSACTION_ID=p5679522929425&
72 # MERCHANT_CODE=0339990001&
73 # RESPONSE_CODE=C&
74 # FINAL_CHECKSUM=E524590DBFAB719EEE428C778FFF1650&
75 # STATUS_REASON=Cancel&
76 # TRANS_NUM=01ESA20190913062149AHGUHQ&
77 # CARD_NO=null&
78 # CARD_TYPE=null
79
80  # A sample query response sent to the RESPONSE_URL
81
82 # http://salsa:8080/app/applicants/cbt2015/449072/p5686487280654/receive_etranzact?
83 # LOGO_URL=https%3A%2F%2Fiuokada.waeup.org%2Fstatic_custom%2Fiou_logo.png&
84 # RESPONSE_URL=http%3A%2F%2Fsalsa%3A8080%2Fapp%2Fapplicants%2Fcbt2015%2F449072%2Fp5686487280654%2Freceive_etranzact&
85 # CURRENCY_CODE=NGN&
86 # TERMINAL_ID=0000000001&
87 # TRANSACTION_ID=p5686487280654&
88 # AMOUNT=3333.0&
89 # DESCRIPTION=&
90 # CHECKSUM=3886118fcd91a376cc95c48c94dc499a&
91 # MERCHANT_CODE=0339990001&
92 # EMAIL=aa%40aa.de&
93 # SUCCESS=0&
94 # FINAL_CHECKSUM=EE105B703F84B1D67D0A4234622C03E8&
95 # STATUS_REASON=Approved&
96 # TRANS_NUM=01ESA20190916164636L2UTU7&
97 # CARD_NO=506066XXXXXXXXX6666&
98 # CARD_TYPE=Verve
99
100def process_response(payment, form, view, verify):
101    success = form.get('RESPONSE_CODE', None)
102    if not success:
103        msg = _('No valid response from eTranzact.')
104        log = 'No valid response from eTranzact for payment %s' % payment.p_id
105        payment.p_state = 'failed'
106        notify(grok.ObjectModifiedEvent(payment))
107        return False, msg, log
108    # Compute final checksum
109    transaction_id = payment.p_id
110    amount = "%.1f" % payment.amount_auth
111    responseurl = view.url(payment, 'receive_etranzact')
112    hashargs =  success + amount + view.terminal_id + transaction_id \
113        + responseurl + view.secret_key
114    final_checksum = hashlib.md5(hashargs).hexdigest().upper()
115    if form.get('FINAL_CHECKSUM', None) != final_checksum:
116        msg = _('Wrong checksum.')
117        log = 'wrong checksum for %s payment %s: %s' % (
118            payment.p_category, payment.p_id, str(form))
119        return False, msg, log
120    payment.r_code = form.get('RESPONSE_CODE', None)
121    payment.r_desc = form.get('STATUS_REASON', None) # MESSAGE also available
122    payment.r_amount_approved = float(form.get('AMOUNT', None))
123    payment.r_pay_reference = form.get('TRANS_NUM', None)
124    payment.r_card_num = "%s %s" % (form.get('CARD_TYPE', None),
125                                    form.get('CARD_NO', None))
126    payment.r_company = u'etranzact'
127    if payment.r_code != '0':
128        msg = _('Unsuccessful response: ${a}', mapping = {'a': payment.r_desc})
129        log = 'unsuccessful response for %s payment %s: %s' % (
130            payment.p_category, payment.p_id, payment.r_desc)
131        payment.p_state = 'failed'
132        notify(grok.ObjectModifiedEvent(payment))
133        return False, msg, log
134    if round(payment.r_amount_approved/10.0, 0) != round(
135        payment.amount_auth/10.0, 0):
136        msg = _('Response amount does not match.')
137        log = 'wrong response for %s payment %s: %s' % (
138            payment.p_category, payment.p_id, str(form))
139        payment.p_state = 'failed'
140        notify(grok.ObjectModifiedEvent(payment))
141        return False, msg, log
142    transaction_id = form.get('TRANSACTION_ID', None)
143    if transaction_id != payment.p_id:
144        msg = _('Response transaction id does not match.')
145        log = 'wrong response for %s payment %s: %s' % (
146            payment.p_category, payment.p_id, str(form))
147        payment.p_state = 'failed'
148        notify(grok.ObjectModifiedEvent(payment))
149        return False, msg, log
150    payment.p_state = 'paid'
151    if not verify:
152        payment.payment_date = datetime.utcnow()
153    msg = _('Successful response received')
154    log = 'valid response for %s payment %s: %s' % (
155        payment.p_category, payment.p_id, str(form))
156    notify(grok.ObjectModifiedEvent(payment))
157    return True, msg, log
Note: See TracBrowser for help on using the repository browser.