source: main/waeup.aaue/trunk/src/waeup/aaue/interswitch/browser.py @ 17492

Last change on this file since 17492 was 17491, checked in by Henrik Bettermann, 19 months ago

Split hostel maintenance fee.

  • Property svn:executable set to *
File size: 22.6 KB
RevLine 
[17431]1    # -*- coding: utf-8 -*-
2## $Id: browser.py 17429 2023-06-05 04:34:30Z henrik $
3##
4## Copyright (C) 2012 Uli Fouquet & Henrik Bettermann
5## This program is free software; you can redistribute it and/or modify
6## it under the terms of the GNU General Public License as published by
7## the Free Software Foundation; either version 2 of the License, or
8## (at your option) any later version.
9##
10## This program is distributed in the hope that it will be useful,
11## but WITHOUT ANY WARRANTY; without even the implied warranty ofself.context.amount_auth
12## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13## GNU General Public License for more details.
14##
15## You should have received a copy of the GNU General Public License
16## along with this program; if not, write to the Free Software
17## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18##
19import httplib
20import hashlib
21import grok
22import os
23import csv
24from xml.dom import minidom
25from zope.interface import Interface
26from zope.component import queryAdapter
27from waeup.kofa.interfaces import CLEARED
28from kofacustom.nigeria.interswitch.browser import (
29    InterswitchPaymentRequestWebservicePageStudent,
30    InterswitchPaymentRequestWebservicePageApplicant,
31    InterswitchPaymentVerifyWebservicePageApplicant,
32    InterswitchPaymentVerifyWebservicePageStudent,
33    InterswitchPageStudent, InterswitchPageApplicant,
34    module_activated,
35    )
36from waeup.aaue.students.interfaces import ICustomStudentOnlinePayment
37from waeup.aaue.applicants.interfaces import ICustomApplicantOnlinePayment
[17447]38from waeup.aaue.students.utils import SFEECHANGES
[17431]39from waeup.aaue.interfaces import MessageFactory as _
40
41PRODUCT_ID = '5845'
42SITE_NAME = 'aaue.waeup.org'
43PROVIDER_ACCT = '0200244434'
44PROVIDER_BANK_ID = '11'
[17441]45PROVIDER_ITEM_NAME = 'WAeAC Portal Fee'
[17431]46INSTITUTION_NAME = 'AAU Ekpoma'
47CURRENCY = '566'
48GATEWAY_AMT = 200.0
49POST_ACTION = 'https://webpay.interswitchng.com/paydirect/pay'
50
51HOST = 'webpay.interswitchng.com'
52URL = '/paydirect/api/v1/gettransaction.json'
53HTTPS = True
54MAC = '9718FA00B0F5070B388A9896ADCED9B2FB02D30F71E12E68BDADC63F6852A3496FF97D8A0F9DA9F753B911A49BB09BB87B55FD02046BD325C74C46C0123CF023'
55
56httplib.HTTPSConnection.debuglevel = 0
57
58BANK_ACCOUNTS = {
[17437]59    'edohis':   ('1222577132', '117'),
60    'union':    ('1019763348', '7'),
61    'sport':    ('1021941220', '7'),
62    'access':   ('1012688013', '123'),
63    'notebook': ('4011210501', '51'),
[17490]64    'accredit': ('5060023412', '51'),
[17437]65    'library':  ('2000122995', '8'),
66    'fac1':     ('1022438743', '7'),
67    'fac2':     ('2000249757', '8'),
68    'fac3':     ('1012678566', '123'),
69    'matricgown': ('2000249757', '8'),
70    'lapel':      ('2000249757', '8'),
[17456]71
[17468]72    'acceptance': ('2000249757', '8'),
73
[17456]74    'hostel_maintenance': ('1006406795', '123'),
[17468]75    'bed_allocation':     ('1006406795', '123'),
[17456]76    'late_registration':  ('5210006575', '51'),
77    'ent_combined':       ('6220029828', '51'),
78    'ent_registration_0': ('6220029828', '51'),
79    'ent_registration_1': ('6220029828', '51'),
80    'ent_registration_2': ('6220029828', '51'),
81    'ent_text_book_0':    ('6220029828', '51'),
82    'ent_text_book_1':    ('6220029828', '51'),
83    'ent_text_book_2':    ('6220029828', '51'),
84    'gst_registration_1': ('1010893123', '117'),
85    'gst_registration_2': ('1010893123', '117'),
86    'gst_text_book_0':    ('1010893123', '117'),
87    'gst_text_book_1':    ('1010893123', '117'),
88    'gst_text_book_2':    ('1010893123', '117'),
89    'gst_text_book_3':    ('1010893123', '117'),
[17468]90
91    'postgrad': ('1010827641', '117'),
[17431]92    }
93
[17437]94FEE_NAMES = {
95    'edohis':     'Edo State Health Insurance Scheme',
96    'union':      'Student Union Dues',
97    'sport':      'Sport Development Fee',
98    'access':     'Access Card Fee',
99    'notebook':   'Branded Notebook',
[17490]100    'accredit':   'Accreditation Fee',
[17437]101    'library':    'Library Development Fee',
102    'tuition':    'Tuition',
103    'acceptance': 'Acceptance Fee',
104    'matricgown': 'Matriculation Gown Fee',
[17439]105    'lapel':      'File/Lapel Fee',
[17437]106    'lmsplus':    'LMS Plus Fee',
107    'nuga':       'NUGA Fee',
108    }
109
[17431]110
[17447]111SCHOOLFEES = dict()
[17444]112
[17447]113for year in SFEECHANGES:
114    schoolfees_path = os.path.join(
115        os.path.dirname(__file__), '../students/schoolfees_%s.csv' %year)
116    reader = csv.DictReader(open(schoolfees_path, 'rb'))
117    SCHOOLFEES[year] = {item['code']:item for item in reader}
[17445]118
[17431]119acceptancefees_path = os.path.join(
120    os.path.dirname(__file__), '../students/acceptancefees.csv')
121reader = csv.DictReader(open(acceptancefees_path, 'rb'))
122ACCEPTANCEFEES = {item['code']:item for item in reader}
123
124class CustomInterswitchPageApplicant(InterswitchPageApplicant):
125    """ View which sends a POST request to the Interswitch
126    CollegePAY payment gateway.
127
128    So far only PT application has been configured.
129    """
130    grok.context(ICustomApplicantOnlinePayment)
131    action = POST_ACTION
132    site_name = SITE_NAME
133    currency = CURRENCY
134    provider_bank_id = PROVIDER_BANK_ID
135    provider_acct = PROVIDER_ACCT
136    pay_item_id = '101'
[17433]137    product_id = PRODUCT_ID
[17431]138
139    def update(self):
140        if not module_activated(
141            self.context.__parent__.__parent__.year, self.context):
142            self.flash(_('Forbidden'), type='danger')
143            self.redirect(self.url(self.context, '@@index'))
144            return
145        error = self.init_update()
146        if error:
147            self.flash(error, type='danger')
148            self.redirect(self.url(self.context, '@@index'))
149            return
150        # Already now it becomes an Interswitch payment. We set the net amount
151        # and add the gateway amount.
152        if not self.context.r_company:
153            self.context.net_amt = self.context.amount_auth
154            self.context.amount_auth += GATEWAY_AMT
155            self.context.gateway_amt = GATEWAY_AMT
156            self.context.r_company = u'interswitch'
157        xmldict = {}
[17477]158        provider_amt = 2000.0
[17469]159        if self.applicant.__parent__.code in ('ver2019', 'send2019'):
160            provider_amt = 0.0
[17477]161        elif self.applicant.__parent__.code.startswith('cert'):
162            provider_amt = 3000.0
163        elif self.applicant.__parent__.code.startswith('trans'):
164            provider_amt = 3000.0
[17468]165        xmldict['institution_acct'] = '1012332141'
166        xmldict['institution_bank_id'] = '123'
167        if self.applicant.applicant_id.startswith('dsh'):
168            xmldict['institution_acct'] = '1014847058'
169            xmldict['institution_bank_id'] = '7'
170        if self.applicant.applicant_id.startswith('ijmbe'):
171            xmldict['institution_acct'] = '1012278272'
172            xmldict['institution_bank_id'] = '123'
[17431]173        xmldict['detail_ref'] = self.context.p_id
174        xmldict['provider_amt'] = 100 * provider_amt
175        xmldict['provider_acct'] = PROVIDER_ACCT
176        xmldict['provider_bank_id'] = PROVIDER_BANK_ID
[17490]177        if 'alumni' in self.application_url():
178            xmldict['provider_acct'] = '0427773399'
179            xmldict['provider_bank_id'] = '10'
[17431]180        xmldict['provider_item_name'] = PROVIDER_ITEM_NAME
181        xmldict['institution_item_name'] = self.context.category
182        xmldict['institution_name'] = INSTITUTION_NAME
183        xmldict['institution_amt'] = 100 * self.context.net_amt
184        if not self.context.provider_amt:
185            self.context.provider_amt = provider_amt
186            self.context.amount_auth += provider_amt
[17469]187        if provider_amt:
188            xmltext = """<payment_item_detail>
[17431]189<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s">
190<item_detail item_id="1" item_name="%(institution_item_name)s" item_amt="%(institution_amt)d" bank_id="%(institution_bank_id)s" acct_num="%(institution_acct)s" />
191<item_detail item_id="2" item_name="%(provider_item_name)s" item_amt="%(provider_amt)d" bank_id="%(provider_bank_id)s" acct_num="%(provider_acct)s" />
192</item_details>
193</payment_item_detail>""" % xmldict
[17469]194        else:
195            xmltext = """<payment_item_detail>
196<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s">
197<item_detail item_id="1" item_name="%(institution_item_name)s" item_amt="%(institution_amt)d" bank_id="%(institution_bank_id)s" acct_num="%(institution_acct)s" />
198</item_details>
199</payment_item_detail>""" % xmldict
[17485]200
201        # Overwrite above configuration
202        if self.applicant.__parent__.code in ('cert1', 'cert2', 'cert6', 'cert9'):
203            xmldict['institution_amt'] = 100 * self.context.net_amt - 100000
204            xmltext = """<payment_item_detail>
205<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s">
206<item_detail item_id="1" item_name="%(institution_item_name)s" item_amt="%(institution_amt)d" bank_id="%(institution_bank_id)s" acct_num="%(institution_acct)s" />
207<item_detail item_id="2" item_name="%(provider_item_name)s" item_amt="%(provider_amt)d" bank_id="%(provider_bank_id)s" acct_num="%(provider_acct)s" />
208<item_detail item_id="3" item_name="Ambrose Alli Foundation" item_amt="100000" bank_id="117" acct_num="1015567975" />
209</item_details>
210</payment_item_detail>""" % xmldict
211
[17431]212        self.xml_data = """<input type="hidden" name="xml_data" value='%s'  />""" % xmltext
213        xmlitems = ''
214        xmldoc = minidom.parseString(xmltext)
215        itemlist = xmldoc.getElementsByTagName('item_detail')
216        for s in itemlist:
[17442]217            xmlitems += "%s (%s %s, %s (%s)),  " % (
[17431]218                s.attributes['item_name'].value,
[17442]219                u'\u20a6',
[17431]220                int(s.attributes['item_amt'].value)/100,
221                s.attributes['acct_num'].value,
222                s.attributes['bank_id'].value,
223                )
224        self.context.p_split_data = xmlitems
225        self.amount_auth = int(100 * self.context.amount_auth)
226        hashargs = (
227            self.context.p_id +
228            PRODUCT_ID +
229            self.pay_item_id +
230            str(int(self.amount_auth)) +
231            self.site_redirect_url +
232            MAC)
233        self.hashvalue = hashlib.sha512(hashargs).hexdigest()
234        return
235
236class CustomInterswitchPageStudent(InterswitchPageStudent):
237    """ View which sends a POST request to the Interswitch
238    CollegePAY payment gateway.
239    """
240    grok.context(ICustomStudentOnlinePayment)
241    action = POST_ACTION
242    site_name = SITE_NAME
243    currency = CURRENCY
244    pay_item_id = '101'
[17433]245    product_id = PRODUCT_ID
[17431]246
247    def update(self):
248        if not module_activated(
249            self.context.student.current_session, self.context):
250            self.flash(_('Forbidden'), type='danger')
251            self.redirect(self.url(self.context, '@@index'))
252            return
253        error = self.init_update()
254        if error:
255            self.flash(error, type='danger')
256            self.redirect(self.url(self.context, '@@index'))
257            return
[17434]258        student = self.student
[17431]259        category = self.context.p_category
[17434]260        # To guarantee that cleared students pay both acceptance fee
261        # and school fees, the page can only be accessed
262        # for school fee payments if acceptance/clearance fee has
263        # been successfully queried/paid beforehand. This
264        # requirement applies to students in state 'cleared' and
265        # entry_session greater than 2012 only.
266        if self.context.p_category.startswith('schoolfee') and \
267            student.state == CLEARED and \
268            student.entry_session > 2012:
269            acceptance_fee_paid = False
270            for ticket in student['payments'].values():
271                if ticket.p_state == 'paid' and \
272                    ticket.p_category.startswith('clearance'):
273                    acceptance_fee_paid = True
274                    break
275            if not acceptance_fee_paid:
276                self.flash(
277                    _('Please pay acceptance fee first.'), type="danger")
278                self.redirect(self.url(self.context, '@@index'))
279                return
[17431]280        # Already now it becomes an Interswitch payment. We set the net amount
281        # and add the gateway amount.
282        if not self.context.r_company:
283            self.context.net_amt = self.context.amount_auth
284            self.context.amount_auth += GATEWAY_AMT
285            self.context.gateway_amt = GATEWAY_AMT
286            self.context.r_company = u'interswitch'
287        xmldict = self.xmldict
288        # Provider data
289        xmldict['detail_ref'] = self.context.p_id
290        xmldict['provider_acct'] = PROVIDER_ACCT
291        xmldict['provider_bank_id'] = PROVIDER_BANK_ID
292        xmldict['provider_item_name'] = PROVIDER_ITEM_NAME
293        # Institution data
294        xmldict['institution_acct'] = '00000000'
295        xmldict['institution_bank_id'] = '00'
296        provider_amt = 0.0
297        if category.startswith('clearance'):
298            provider_amt = 1500.0
299        elif category.startswith('hostel_maintenance'):
300            provider_amt = 1000.0
301        elif category in ('schoolfee', 'schoolfee_1', 'schoolfee_incl'):
302            provider_amt = 2500.0
303        xmldict['provider_amt'] = 100 * provider_amt
304        xmldict['institution_item_name'] = self.context.category
305        xmldict['institution_name'] = INSTITUTION_NAME
306        xmldict['institution_amt'] = 100 * self.context.net_amt
307        if not self.context.provider_amt:
308            self.context.provider_amt = provider_amt
309            self.context.amount_auth += provider_amt
310        xmltext = ''
311
312        # School fee
313        if category.startswith('schoolfee'):
314            # collect additional fees
315            if self.context.p_category in ('schoolfee_1', 'schoolfee_incl'):
316                xmltext = """<payment_item_detail>
317<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s" department="%(department)s" faculty="%(faculty)s">""" % xmldict
318                item_id = 1
[17446]319
320                if student.entry_session < 2013:
[17447]321                    sorted_items = SCHOOLFEES[12][student.certcode].items()
[17446]322                elif student.entry_session < 2014:
[17447]323                    sorted_items = SCHOOLFEES[13][student.certcode].items()
[17455]324                elif student.entry_session < 2015:
[17447]325                    sorted_items = SCHOOLFEES[14][student.certcode].items()
[17446]326                elif student.entry_session < 2020:
[17455]327                    sorted_items = SCHOOLFEES[15][student.certcode].items()
[17445]328                elif student.entry_session < 2021:
[17447]329                    sorted_items = SCHOOLFEES[20][student.certcode].items()
[17445]330                elif student.entry_session < 2022:
[17447]331                    sorted_items = SCHOOLFEES[21][student.certcode].items()
[17444]332                else:
[17447]333                    sorted_items = SCHOOLFEES[22][student.certcode].items()
[17439]334                sorted_items.insert(0, sorted_items.pop(4))
335                for item in sorted_items:
[17431]336                    try:
337                        item_amt = 100 * int(item[1])
338                        if self.context.p_category == 'schoolfee_1' and item[0] == 'tuition':
339                            item_amt /= 2
340                        acct_num = ''
341                        bank_id = ''
342                        item_name = ''
343                        # Find appropriate bank
344                        try:
345                            bank = BANK_ACCOUNTS[item[0]]
346                        except: # transfer to faculty account
347                            if student.faccode in ('FAG', 'FAT', 'FBM', 'FMLS', 'fac1'):
348                                bank = BANK_ACCOUNTS['fac1']
349                            elif student.faccode in ('FCS', 'FED', 'FES', 'FET'):
350                                bank = BANK_ACCOUNTS['fac2']
351                            elif student.faccode in ('FLS', 'FLW', 'FMS', 'FPS', 'FSS'):
352                                bank = BANK_ACCOUNTS['fac3']
353                        acct_num = bank[0]
354                        bank_id = bank[1]
[17437]355                        item_name = FEE_NAMES[item[0]]
[17431]356                        xmltext += """
357<item_detail item_id="%s" item_name="%s" item_amt="%d" bank_id="%s" acct_num="%s" />""" % (item_id, item_name, item_amt, bank_id, acct_num)
358                        item_id += 1
359                    except:
360                        pass
361                xmldict['item_id'] = item_id
362                xmltext += """
363<item_detail item_id="%(item_id)d" item_name="%(provider_item_name)s" item_amt="%(provider_amt)d" bank_id="%(provider_bank_id)s" acct_num="%(provider_acct)s" />
364</item_details>
365</payment_item_detail>""" % xmldict
366            # no additional charges, determine faculty bank only
367            else:
[17468]368                if student.is_postgrad:
369                    bank = BANK_ACCOUNTS['postgrad']
370                elif student.faccode in ('FAG', 'FAT', 'FBM', 'FMLS', 'fac1'):
[17431]371                    bank = BANK_ACCOUNTS['fac1']
372                elif student.faccode in ('FCS', 'FED', 'FES', 'FET'):
373                    bank = BANK_ACCOUNTS['fac2']
374                elif student.faccode in ('FLS', 'FLW', 'FMS', 'FPS', 'FSS'):
375                    bank = BANK_ACCOUNTS['fac3']
376                xmldict['institution_acct'] = bank[0]
377                xmldict['institution_bank_id'] = bank[1]
378
379
380        # Clearance (acceptance) fee
381
[17456]382        elif category.startswith('clearance'):
[17431]383            # collect additional fees
384            if self.context.p_category == 'clearance_incl':
385                xmltext = """<payment_item_detail>
386<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s" department="%(department)s" faculty="%(faculty)s">""" % xmldict
387                item_id = 1
388                for item in ACCEPTANCEFEES[student.certcode].items():
389                    try:
390                        item_amt = 100 * int(item[1])
391                        bank = BANK_ACCOUNTS[item[0]]
392                        acct_num = bank[0]
393                        bank_id = bank[1]
[17437]394                        item_name = FEE_NAMES[item[0]]
[17431]395                        xmltext += """
396<item_detail item_id="%s" item_name="%s" item_amt="%d" bank_id="%s" acct_num="%s" />""" % (item_id, item_name, item_amt, bank_id, acct_num)
397                        item_id += 1
398                    except:
399                        pass
400                xmldict['item_id'] = item_id
401                xmltext += """
402<item_detail item_id="%(item_id)d" item_name="%(provider_item_name)s" item_amt="%(provider_amt)d" bank_id="%(provider_bank_id)s" acct_num="%(provider_acct)s" />
403</item_details>
404</payment_item_detail>""" % xmldict
405            # no additional charges, determine faculty bank only
406            else:
[17468]407                if student.is_postgrad:
408                    bank = BANK_ACCOUNTS['postgrad']
409                else:
410                    bank = BANK_ACCOUNTS['acceptance']
[17431]411                xmldict['institution_acct'] = bank[0]
412                xmldict['institution_bank_id'] = bank[1]
413
[17491]414        # Hostel Maintenance
415
416        elif category == 'hostel_maintenance':
417            xmldict['institution_amt'] = 100 * self.context.net_amt - 1000000
418            bank = BANK_ACCOUNTS[category]
419            xmldict['institution_acct'] = bank[0]
420            xmldict['institution_bank_id'] = bank[1]
421            xmltext = """<payment_item_detail>
422<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s" department="%(department)s" faculty="%(faculty)s">
423<item_detail item_id="1" item_name="%(institution_item_name)s" item_amt="%(institution_amt)d" bank_id="%(institution_bank_id)s" acct_num="%(institution_acct)s" />
424<item_detail item_id="2" item_name="%(provider_item_name)s" item_amt="%(provider_amt)d" bank_id="%(provider_bank_id)s" acct_num="%(provider_acct)s" />
425<item_detail item_id="3" item_name="Hostel Consumable Fee" item_amt="1000000" bank_id="123" acct_num="1012332141" />
426</item_details>
427</payment_item_detail>""" % xmldict
428
[17431]429        # Other fees
[17491]430
[17456]431        elif category in BANK_ACCOUNTS.keys():
432            bank = BANK_ACCOUNTS[category]
433            xmldict['institution_acct'] = bank[0]
434            xmldict['institution_bank_id'] = bank[1]
[17431]435
436        if not xmltext and provider_amt == 0:
437            xmltext = """<payment_item_detail>
438<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s" department="%(department)s" faculty="%(faculty)s">
439<item_detail item_id="1" item_name="%(institution_item_name)s" item_amt="%(institution_amt)d" bank_id="%(institution_bank_id)s" acct_num="%(institution_acct)s" />
440</item_details>
441</payment_item_detail>""" % xmldict
442        elif not xmltext:
443            xmltext = """<payment_item_detail>
444<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s" department="%(department)s" faculty="%(faculty)s">
445<item_detail item_id="1" item_name="%(institution_item_name)s" item_amt="%(institution_amt)d" bank_id="%(institution_bank_id)s" acct_num="%(institution_acct)s" />
446<item_detail item_id="2" item_name="%(provider_item_name)s" item_amt="%(provider_amt)d" bank_id="%(provider_bank_id)s" acct_num="%(provider_acct)s" />
447</item_details>
448</payment_item_detail>""" % xmldict
449        self.xml_data = """<input type="hidden" name="xml_data" value='%s'  />""" % xmltext
450        xmlitems = ''
451        xmldoc = minidom.parseString(xmltext)
452        itemlist = xmldoc.getElementsByTagName('item_detail')
453        for s in itemlist:
[17442]454            xmlitems += "%s (%s %s, %s (%s)),  " % (
[17431]455                s.attributes['item_name'].value,
456                u'\u20a6',
457                int(s.attributes['item_amt'].value)/100,
458                s.attributes['acct_num'].value,
459                s.attributes['bank_id'].value,
460                )
461        self.context.p_split_data = xmlitems
462        self.context.provider_amt = provider_amt
463        self.amount_auth = int(100 * self.context.amount_auth)
464        hashargs = (
465            self.context.p_id +
466            PRODUCT_ID +
467            self.pay_item_id +
468            str(int(self.amount_auth)) +
469            self.site_redirect_url +
470            MAC)
471        self.hashvalue = hashlib.sha512(hashargs).hexdigest()
472        return
473
474
475class CustomInterswitchPaymentRequestWebservicePageApplicant(
476    InterswitchPaymentRequestWebservicePageApplicant):
477    """Request webservice view for the CollegePAY gateway
478    """
479    grok.context(ICustomApplicantOnlinePayment)
480    gateway_host = HOST
481    gateway_url = URL
482    https = HTTPS
[17480]483    mac = MAC
484    product_id = PRODUCT_ID
[17431]485
486class CustomInterswitchPaymentVerifyWebservicePageApplicant(
487    InterswitchPaymentVerifyWebservicePageApplicant):
488    """Payment verify view for the CollegePAY gateway
489    """
490    grok.context(ICustomApplicantOnlinePayment)
491    gateway_host = HOST
492    gateway_url = URL
493    https = HTTPS
494    mac = MAC
495    product_id = PRODUCT_ID
496
497class CustomInterswitchPaymentRequestWebservicePageStudent(
498    InterswitchPaymentRequestWebservicePageStudent):
499    """Request webservice view for the CollegePAY gateway
500    """
501    grok.context(ICustomStudentOnlinePayment)
502    gateway_host = HOST
503    gateway_url = URL
504    https = HTTPS
505    mac = MAC
506    product_id = PRODUCT_ID
507
508class CustomInterswitchPaymentVerifyWebservicePageStudent(
509    InterswitchPaymentVerifyWebservicePageStudent):
510    """Payment verify view for the CollegePAY gateway
511    """
512    grok.context(ICustomStudentOnlinePayment)
513    gateway_host = HOST
514    gateway_url = URL
515    https = HTTPS
516    mac = MAC
517    product_id = PRODUCT_ID
Note: See TracBrowser for help on using the repository browser.