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

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

Application payment should work now.

  • Property svn:keywords set to Id
File size: 8.1 KB
Line 
1## $Id: helpers.py 15598 2019-09-20 13:14:07Z 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
27from zope.event import notify
28from waeup.kofa.utils.helpers import extract_formvars
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):
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), None
55    raw = response.read()
56    return raw, extract_formvars(raw)
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
81
82 # <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
83 #     "http://www.w3.org/TR/html4/loose.dtd">
84 # <script language='javascript'>
85 # var spanId = document.getElementById("message_container");
86 # spanId.textContent = 'Redirecting...';</script>
87 # <form method="GET" id="redirect_form" name="redirect_form"
88 # action="http://localhost:81/projects/Webconnect/response.php" target="_top">
89 # <input type="hidden" name = "LOGO_URL"
90 # value="http://localhost:81/projects/Webconnect/images/elogo.fw.png">
91 # <input type="hidden" name = "RESPONSE_URL"
92 # value="http://localhost:81/projects/Webconnect/response.php">
93 # <input type="hidden" name = "CURRENCY_CODE" value="NGN">
94 # <input type="hidden" name = "TERMINAL_ID" value="0000000001">
95 # <input type="hidden" name = "TRANSACTION_ID" value="etz1568638104web">
96 # <input type="hidden" name = "AMOUNT" value="100">
97 # <input type="hidden" name = "DESCRIPTION" value="Payment Description">
98 # <input type="hidden" name = "CHECKSUM"
99 # value="5be04064f4bb250f73650059a8e921cc">
100 # <input type="hidden" name = "MERCHANT_CODE" value="0339990001">
101 # <input type="hidden" name = "EMAIL" value="xyz@yahoo.com">
102 # <input type="hidden" name = "SUCCESS" value="0">
103 # <input type="hidden" name = "FINAL_CHECKSUM"
104 # value="FD67A4CCC39E2C8DEEEC78D6C64A61FE">
105 # <input type="hidden" name = "STATUS_REASON" value="Approved">
106 # <input type="hidden" name = "TRANS_NUM" value="01ESA20190916134824YA3YJ8">
107 # <input type="hidden" name = "CARD_NO" value="506066XXXXXXXXX6666">
108 # <input type="hidden" name = "CARD_TYPE" value="Verve">
109 # </form>
110 # <script language='javascript'>
111 # var fom = document.forms["redirect_form"];
112 # fom.submit();</script>
113
114 # A sample query response sent to the RESPONSE_URL after the browser has
115 # automatically executed the Javascript above (we don't use this response)
116
117 # http://salsa:8080/app/applicants/cbt2015/449072/p5686487280654/receive_etranzact?
118 # LOGO_URL=https%3A%2F%2Fiuokada.waeup.org%2Fstatic_custom%2Fiou_logo.png&
119 # RESPONSE_URL=http%3A%2F%2Fsalsa%3A8080%2Fapp%2Fapplicants%2Fcbt2015%2F449072%2Fp5686487280654%2Freceive_etranzact&
120 # CURRENCY_CODE=NGN&
121 # TERMINAL_ID=0000000001&
122 # TRANSACTION_ID=p5686487280654&
123 # AMOUNT=3333.0&
124 # DESCRIPTION=&
125 # CHECKSUM=3886118fcd91a376cc95c48c94dc499a&
126 # MERCHANT_CODE=0339990001&
127 # EMAIL=aa%40aa.de&
128 # SUCCESS=0&
129 # FINAL_CHECKSUM=EE105B703F84B1D67D0A4234622C03E8&
130 # STATUS_REASON=Approved&
131 # TRANS_NUM=01ESA20190916164636L2UTU7&
132 # CARD_NO=506066XXXXXXXXX6666&
133 # CARD_TYPE=Verve
134
135def process_response(payment, form, view, verify):
136    if not form or not form.get('SUCCESS', None):
137        msg = _('No valid response from eTranzact.')
138        log = 'No valid response from eTranzact for payment %s' % payment.p_id
139        payment.p_state = 'failed'
140        notify(grok.ObjectModifiedEvent(payment))
141        return False, msg, log
142    success = form.get('SUCCESS', None)
143    # Compute final checksum
144    transaction_id = payment.p_id
145    amount = "%.1f" % payment.amount_auth
146    responseurl = view.url(payment, 'receive_etranzact')
147    hashargs =  success + amount + view.terminal_id + transaction_id \
148        + responseurl + view.secret_key
149    final_checksum = hashlib.md5(hashargs).hexdigest().upper()
150    if form.get('FINAL_CHECKSUM', None) != final_checksum:
151        msg = _('Wrong checksum.')
152        log = 'wrong checksum for %s payment %s: %s' % (
153            payment.p_category, payment.p_id, str(form))
154        payment.p_state = 'failed'
155        notify(grok.ObjectModifiedEvent(payment))
156        return False, msg, log
157    payment.r_code = form.get('SUCCESS', None)
158    payment.r_desc = form.get('STATUS_REASON', None) # MESSAGE also available
159    payment.r_amount_approved = float(form.get('AMOUNT', None))
160    payment.r_pay_reference = form.get('TRANS_NUM', None)
161    payment.r_card_num = "%s %s" % (form.get('CARD_TYPE', None),
162                                    form.get('CARD_NO', None))
163    payment.r_company = u'etranzact'
164    if payment.r_code != '0':
165        msg = _('Unsuccessful response: ${a}', mapping = {'a': payment.r_desc})
166        log = 'unsuccessful response for %s payment %s: %s' % (
167            payment.p_category, payment.p_id, payment.r_desc)
168        payment.p_state = 'failed'
169        notify(grok.ObjectModifiedEvent(payment))
170        return False, msg, log
171    if round(payment.r_amount_approved/10.0, 0) != round(
172        payment.amount_auth/10.0, 0):
173        msg = _('Response amount does not match.')
174        log = 'wrong response for %s payment %s: %s' % (
175            payment.p_category, payment.p_id, str(form))
176        payment.p_state = 'failed'
177        notify(grok.ObjectModifiedEvent(payment))
178        return False, msg, log
179    transaction_id = form.get('TRANSACTION_ID', None)
180    if transaction_id != payment.p_id:
181        msg = _('Response transaction id does not match.')
182        log = 'wrong response for %s payment %s: %s' % (
183            payment.p_category, payment.p_id, str(form))
184        payment.p_state = 'failed'
185        notify(grok.ObjectModifiedEvent(payment))
186        return False, msg, log
187    payment.p_state = 'paid'
188    if not verify:
189        payment.payment_date = datetime.utcnow()
190    msg = _('Successful response received')
191    log = 'valid response for %s payment %s: %s' % (
192        payment.p_category, payment.p_id, str(form))
193    notify(grok.ObjectModifiedEvent(payment))
194    return True, msg, log
Note: See TracBrowser for help on using the repository browser.