source: main/waeup.aaue/trunk/src/waeup/aaue/etranzact/browser.py @ 8682

Last change on this file since 8682 was 8682, checked in by Henrik Bettermann, 12 years ago

Add confirmation number field. Change live terminal id.

  • Property svn:keywords set to Id
File size: 7.0 KB
Line 
1## $Id: browser.py 8682 2012-06-11 14:39:30Z henrik $
2##
3## Copyright (C) 2012 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##
18from datetime import datetime
19import httplib
20import urllib
21from xml.dom.minidom import parseString
22import grok
23from waeup.kofa.browser.layout import KofaPage, UtilityView
24from waeup.kofa.students.viewlets import ApprovePaymentActionButton as APABStudent
25from waeup.kofa.applicants.viewlets import ApprovePaymentActionButton as APABApplicant
26from waeup.aaue.interfaces import MessageFactory as _
27from waeup.aaue.students.interfaces import ICustomStudentOnlinePayment
28from waeup.aaue.applicants.interfaces import ICustomApplicantOnlinePayment
29
30#TERMINAL_ID = '0330000046'
31#QUERY_URL =   'https://www.etranzact.net/Query/queryPayoutletTransaction.jsp'
32
33# Test environment
34QUERY_URL =   'http://demo.etranzact.com:8080/WebConnect/queryPayoutletTransaction.jsp'
35TERMINAL_ID = '5009892287'
36
37def query_etranzact(confirmation_number, payment):
38   
39    postdict = {}
40    postdict['TERMINAL_ID'] = TERMINAL_ID
41    #postdict['RESPONSE_URL'] = 'http://dummy'
42    postdict['CONFIRMATION_NO'] = confirmation_number
43    data = urllib.urlencode(postdict)
44    payment.conf_number = confirmation_number
45    try:
46        f = urllib.urlopen(url=QUERY_URL, data=data)
47        success = f.read()
48        success = success.replace('\r\n','')
49        if 'COL1' not in success:
50            msg = _('Invalid or unsuccessful callback: ${a}',
51                mapping = {'a': success})
52            log = 'invalid callback for payment %s: %s' % (payment.p_id, success)
53            payment.p_state = 'failed'
54            return False, msg, log
55        success = success.replace('%20',' ').split('&')
56        # We expect at least two parameters
57        if len(success) < 2:
58            msg = _('Invalid callback: ${a}', mapping = {'a': success})
59            log = 'invalid callback for payment %s: %s' % (payment.p_id, success)
60            payment.p_state = 'failed'
61            return False, msg, log
62        try:
63            success_dict = dict([tuple(i.split('=')) for i in success])
64        except ValueError:
65            msg = _('Invalid callback: ${a}', mapping = {'a': success})
66            log = 'invalid callback for payment %s: %s' % (payment.p_id, success)
67            payment.p_state = 'failed'
68            return False, msg, log
69    except IOError:
70        msg = _('eTranzact IOError')
71        log = 'eTranzact IOError'
72        return False, msg, log
73    payment.r_code = u'ET'
74    payment.r_desc = u'%s' % success_dict.get('TRANS_DESCR')
75    payment.r_amount_approved = float(success_dict.get('TRANS_AMOUNT',0.0))
76    payment.r_card_num = None
77    payment.r_pay_reference = u'%s' % success_dict.get('RECEIPT_NO')
78    if payment.r_amount_approved != payment.amount_auth:
79        msg = _('Wrong amount')
80        log = 'wrong callback for payment %s: %s' % (payment.p_id, success)
81        payment.p_state = 'failed'
82        return False, msg, log
83    tcode = payment.p_id
84    tcode = tcode[len(tcode)-8:len(tcode)]
85    col1 = success_dict.get('COL1')
86    col1 = col1[len(col1)-8:len(col1)]
87    if tcode != col1:
88        msg = _('Wrong transaction code')
89        log = 'wrong callback for payment %s: %s' % (payment.p_id, success)
90        payment.p_state = 'failed'
91        return False, msg, log
92    log = 'valid callback for payment %s: %s' % (payment.p_id, success)
93    msg = _('Successful callback received')
94    payment.p_state = 'paid'
95    payment.payment_date = datetime.utcnow()
96    return True, msg, log
97
98class EtranzactEnterPinActionButtonApplicant(APABApplicant):
99    grok.context(ICustomApplicantOnlinePayment)
100    grok.require('waeup.payApplicant')
101    grok.order(3)
102    icon = 'actionicon_call.png'
103    text = _('Query eTranzact History')
104    target = 'enterpin'
105
106class EtranzactEnterPinActionButtonStudent(APABStudent):
107    grok.context(ICustomStudentOnlinePayment)
108    grok.require('waeup.payStudent')
109    grok.order(3)
110    icon = 'actionicon_call.png'
111    text = _('Query eTranzact History')
112    target = 'enterpin'
113
114class EtranzactEnterPinPageStudent(KofaPage):
115    """
116    """
117    grok.context(ICustomStudentOnlinePayment)
118    grok.name('enterpin')
119    grok.template('enterpin')
120    grok.require('waeup.payStudent')
121
122    buttonname = _('Submit to eTranzact')
123    label = _('Requery eTranzact History')
124    action = 'query_history'
125
126class EtranzactEnterPinPageApplicant(EtranzactEnterPinPageStudent):
127    """
128    """
129    grok.require('waeup.payApplicant')
130    grok.context(ICustomApplicantOnlinePayment)
131
132class EtranzactQueryHistoryPageStudent(UtilityView, grok.View):
133    """ Query history of eTranzact payments
134    """
135    grok.context(ICustomStudentOnlinePayment)
136    grok.name('query_history')
137    grok.require('waeup.payStudent')
138
139    def update(self, confirmation_number=None):
140        ob_class = self.__implemented__.__name__
141        if self.context.p_state == 'paid':
142            self.flash(_('This ticket has already been paid.'))
143            return
144        student = self.context.getStudent()
145        success, msg, log = query_etranzact(confirmation_number,self.context)
146        student.loggerInfo(ob_class, log)
147        if not success:
148            self.flash(msg)
149            return
150        success, msg, log = self.context.doAfterStudentPayment()
151        if log is not None:
152            student.loggerInfo(ob_class, log)
153        self.flash(msg)
154        return
155
156    def render(self):
157        self.redirect(self.url(self.context, '@@index'))
158        return
159
160class EtranzactQueryHistoryPageApplicant(UtilityView, grok.View):
161    """ Query history of eTranzact payments
162    """
163    grok.context(ICustomApplicantOnlinePayment)
164    grok.name('query_history')
165    grok.require('waeup.payApplicant')
166
167    def update(self, confirmation_number=None):
168        ob_class = self.__implemented__.__name__
169        if self.context.p_state == 'paid':
170            self.flash(_('This ticket has already been paid.'))
171            return
172        applicant = self.context.__parent__
173        success, msg, log = query_etranzact(confirmation_number,self.context)
174        applicant.loggerInfo(ob_class, log)
175        if not success:
176            self.flash(msg)
177            return
178        success, msg, log = self.context.doAfterApplicantPayment()
179        if log is not None:
180            applicant.loggerInfo(ob_class, log)
181        self.flash(msg)
182        return
183
184    def render(self):
185        self.redirect(self.url(self.context, '@@index'))
186        return
Note: See TracBrowser for help on using the repository browser.