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

Last change on this file since 8700 was 8698, checked in by Henrik Bettermann, 13 years ago

Implement minimal webservice for demonstration purposes.

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