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

Last change on this file since 17569 was 17529, checked in by Henrik Bettermann, 16 months ago

Add additional fees also to tuition when splitting amounts.

  • Property svn:executable set to *
File size: 24.4 KB
Line 
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
38from waeup.aaue.students.utils import SFEECHANGES
39from waeup.aaue.interfaces import MessageFactory as _
40
41PRODUCT_ID = '5845'
42SITE_NAME = 'aaue.waeup.org'
43PROVIDER_ACCT = '0200244434'
44PROVIDER_BANK_ID = '11'
45PROVIDER_ITEM_NAME = 'WAeAC Portal Fee'
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 = {
59    'edohis':    ('1222577132', '117'),
60    'union':     ('1019763348', '7'),
61    'union_pt':  ('0051005007', '31'),
62    'sport':     ('1021941220', '7'),
63    'access':    ('1012688013', '123'),
64    'notebook':  ('4011210501', '51'),
65    'accredit':  ('5060023412', '51'),
66    'library':   ('2000122995', '8'),
67    'fac1':      ('1022438743', '7'),
68    'fac2':      ('2000249757', '8'),
69    'fac3':      ('1012678566', '123'),
70    'matricgown':('2000249757', '8'),
71    'lapel':     ('2000249757', '8'),
72    'lmsplus':   ('5060023429', '51'),
73
74    'acceptance': ('2000249757', '8'),
75    'parttime': ('1012678566', '123'),
76
77    'hostel_maintenance': ('1006406795', '123'),
78    'bed_allocation':     ('1006406795', '123'),
79    'late_registration':  ('5210006575', '51'),
80    'ent_combined':       ('6220029828', '51'),
81    'ent_registration_0': ('6220029828', '51'),
82    'ent_registration_1': ('6220029828', '51'),
83    'ent_registration_2': ('6220029828', '51'),
84    'ent_text_book_0':    ('6220029828', '51'),
85    'ent_text_book_1':    ('6220029828', '51'),
86    'ent_text_book_2':    ('6220029828', '51'),
87    'gst_registration_1': ('1010893123', '117'),
88    'gst_registration_2': ('1010893123', '117'),
89    'gst_text_book_0':    ('1010893123', '117'),
90    'gst_text_book_1':    ('1010893123', '117'),
91    'gst_text_book_2':    ('1010893123', '117'),
92    'gst_text_book_3':    ('1010893123', '117'),
93
94    'postgrad': ('1010827641', '117'),
95    }
96
97FEE_NAMES = {
98    'edohis':     'Edo State Health Insurance Scheme',
99    'union':      'Student Union Dues',
100    'union_pt':   'Student Union Dues Part-Time',
101    'sport':      'Sport Development Fee',
102    'access':     'Access Card Fee',
103    'notebook':   'Branded Notebook',
104    'accredit':   'Accreditation Fee',
105    'library':    'Library Development Fee',
106    'tuition':    'Tuition',
107    'acceptance': 'Acceptance Fee',
108    'matricgown': 'Matriculation Gown Fee',
109    'lapel':      'File/Lapel Fee',
110    'lmsplus':    'LMS Plus Fee',
111    'nuga':       'NUGA Fee',
112    }
113
114
115SCHOOLFEES = dict()
116
117for year in SFEECHANGES:
118    schoolfees_path = os.path.join(
119        os.path.dirname(__file__), '../students/schoolfees_%s.csv' %year)
120    reader = csv.DictReader(open(schoolfees_path, 'rb'))
121    SCHOOLFEES[year] = {item['code']:item for item in reader}
122
123acceptancefees_path = os.path.join(
124    os.path.dirname(__file__), '../students/acceptancefees.csv')
125reader = csv.DictReader(open(acceptancefees_path, 'rb'))
126ACCEPTANCEFEES = {item['code']:item for item in reader}
127
128class CustomInterswitchPageApplicant(InterswitchPageApplicant):
129    """ View which sends a POST request to the Interswitch
130    CollegePAY payment gateway.
131
132    So far only PT application has been configured.
133    """
134    grok.context(ICustomApplicantOnlinePayment)
135    action = POST_ACTION
136    site_name = SITE_NAME
137    currency = CURRENCY
138    provider_bank_id = PROVIDER_BANK_ID
139    provider_acct = PROVIDER_ACCT
140    pay_item_id = '101'
141    product_id = PRODUCT_ID
142
143    def update(self):
144        if not module_activated(
145            self.context.__parent__.__parent__.year, self.context):
146            self.flash(_('Forbidden'), type='danger')
147            self.redirect(self.url(self.context, '@@index'))
148            return
149        error = self.init_update()
150        if error:
151            self.flash(error, type='danger')
152            self.redirect(self.url(self.context, '@@index'))
153            return
154        # Already now it becomes an Interswitch payment. We set the net amount
155        # and add the gateway amount.
156        if not self.context.r_company:
157            self.context.net_amt = self.context.amount_auth
158            self.context.amount_auth += GATEWAY_AMT
159            self.context.gateway_amt = GATEWAY_AMT
160            self.context.r_company = u'interswitch'
161        xmldict = {}
162        provider_amt = 2000.0
163        if self.applicant.__parent__.code in ('ver2019', 'send2019'):
164            provider_amt = 0.0
165        elif self.applicant.__parent__.code.startswith('cert'):
166            provider_amt = 3000.0
167        elif self.applicant.__parent__.code.startswith('trans'):
168            provider_amt = 3000.0
169        xmldict['institution_acct'] = '1012332141'
170        xmldict['institution_bank_id'] = '123'
171        if self.applicant.applicant_id.startswith('dsh'):
172            xmldict['institution_acct'] = '1014847058'
173            xmldict['institution_bank_id'] = '7'
174        if self.applicant.applicant_id.startswith('ijmbe'):
175            xmldict['institution_acct'] = '1012278272'
176            xmldict['institution_bank_id'] = '123'
177        xmldict['detail_ref'] = self.context.p_id
178        xmldict['provider_amt'] = 100 * provider_amt
179        xmldict['provider_acct'] = PROVIDER_ACCT
180        xmldict['provider_bank_id'] = PROVIDER_BANK_ID
181        if 'alumni' in self.application_url():
182            xmldict['provider_acct'] = '0427773399'
183            xmldict['provider_bank_id'] = '10'
184        xmldict['provider_item_name'] = PROVIDER_ITEM_NAME
185        xmldict['institution_item_name'] = self.context.category
186        xmldict['institution_name'] = INSTITUTION_NAME
187        xmldict['institution_amt'] = 100 * self.context.net_amt
188        if not self.context.provider_amt:
189            self.context.provider_amt = provider_amt
190            self.context.amount_auth += provider_amt
191        if provider_amt:
192            xmltext = """<payment_item_detail>
193<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s">
194<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" />
195<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" />
196</item_details>
197</payment_item_detail>""" % xmldict
198        else:
199            xmltext = """<payment_item_detail>
200<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s">
201<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" />
202</item_details>
203</payment_item_detail>""" % xmldict
204
205        # Overwrite above configuration
206        if self.applicant.__parent__.code in ('cert1', 'cert2', 'cert6', 'cert9'):
207            xmldict['institution_amt'] = 100 * self.context.net_amt - 100000
208            xmltext = """<payment_item_detail>
209<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s">
210<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" />
211<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" />
212<item_detail item_id="3" item_name="Ambrose Alli Foundation" item_amt="100000" bank_id="117" acct_num="1015567975" />
213</item_details>
214</payment_item_detail>""" % xmldict
215
216        self.xml_data = """<input type="hidden" name="xml_data" value='%s'  />""" % xmltext
217        xmlitems = ''
218        xmldoc = minidom.parseString(xmltext)
219        itemlist = xmldoc.getElementsByTagName('item_detail')
220        for s in itemlist:
221            xmlitems += "%s (%s %s, %s (%s)),  " % (
222                s.attributes['item_name'].value,
223                u'\u20a6',
224                int(s.attributes['item_amt'].value)/100,
225                s.attributes['acct_num'].value,
226                s.attributes['bank_id'].value,
227                )
228        self.context.p_split_data = xmlitems
229        self.amount_auth = int(100 * self.context.amount_auth)
230        hashargs = (
231            self.context.p_id +
232            PRODUCT_ID +
233            self.pay_item_id +
234            str(int(self.amount_auth)) +
235            self.site_redirect_url +
236            MAC)
237        self.hashvalue = hashlib.sha512(hashargs).hexdigest()
238        return
239
240class CustomInterswitchPageStudent(InterswitchPageStudent):
241    """ View which sends a POST request to the Interswitch
242    CollegePAY payment gateway.
243    """
244    grok.context(ICustomStudentOnlinePayment)
245    action = POST_ACTION
246    site_name = SITE_NAME
247    currency = CURRENCY
248    pay_item_id = '101'
249    product_id = PRODUCT_ID
250
251    def update(self):
252        if not module_activated(
253            self.context.student.current_session, self.context):
254            self.flash(_('Forbidden'), type='danger')
255            self.redirect(self.url(self.context, '@@index'))
256            return
257        error = self.init_update()
258        if error:
259            self.flash(error, type='danger')
260            self.redirect(self.url(self.context, '@@index'))
261            return
262        student = self.student
263        category = self.context.p_category
264        # To guarantee that cleared students pay both acceptance fee
265        # and school fees, the page can only be accessed
266        # for school fee payments if acceptance/clearance fee has
267        # been successfully queried/paid beforehand. This
268        # requirement applies to students in state 'cleared' and
269        # entry_session greater than 2012 only.
270        if self.context.p_category.startswith('schoolfee') and \
271            student.state == CLEARED and \
272            student.entry_session > 2012:
273            acceptance_fee_paid = False
274            for ticket in student['payments'].values():
275                if ticket.p_state == 'paid' and \
276                    ticket.p_category.startswith('clearance'):
277                    acceptance_fee_paid = True
278                    break
279            if not acceptance_fee_paid:
280                self.flash(
281                    _('Please pay acceptance fee first.'), type="danger")
282                self.redirect(self.url(self.context, '@@index'))
283                return
284        # Already now it becomes an Interswitch payment. We set the net amount
285        # and add the gateway amount.
286        if not self.context.r_company:
287            self.context.net_amt = self.context.amount_auth
288            self.context.amount_auth += GATEWAY_AMT
289            self.context.gateway_amt = GATEWAY_AMT
290            self.context.r_company = u'interswitch'
291        xmldict = self.xmldict
292        # Provider data
293        xmldict['detail_ref'] = self.context.p_id
294        xmldict['provider_acct'] = PROVIDER_ACCT
295        xmldict['provider_bank_id'] = PROVIDER_BANK_ID
296        xmldict['provider_item_name'] = PROVIDER_ITEM_NAME
297        # Institution data
298        xmldict['institution_acct'] = '00000000'
299        xmldict['institution_bank_id'] = '00'
300        provider_amt = 0.0
301        if category.startswith('clearance'):
302            provider_amt = 1500.0
303        elif category.startswith('hostel_maintenance'):
304            provider_amt = 1000.0
305        elif category in ('schoolfee', 'schoolfee_1', 'schoolfee_incl'):
306            provider_amt = 2500.0
307        xmldict['provider_amt'] = 100 * provider_amt
308        xmldict['institution_item_name'] = self.context.category
309        xmldict['institution_name'] = INSTITUTION_NAME
310        xmldict['institution_amt'] = 100 * self.context.net_amt
311        if not self.context.provider_amt:
312            self.context.provider_amt = provider_amt
313            self.context.amount_auth += provider_amt
314        xmltext = ''
315
316        # School fee
317        if category.startswith('schoolfee'):
318            # collect additional fees
319            if self.context.p_category in ('schoolfee_1', 'schoolfee_incl'):
320                xmltext = """<payment_item_detail>
321<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s" department="%(department)s" faculty="%(faculty)s">""" % xmldict
322                item_id = 1
323
324                if student.entry_session < 2013:
325                    sorted_items = SCHOOLFEES[12][student.certcode].items()
326                elif student.entry_session < 2014:
327                    sorted_items = SCHOOLFEES[13][student.certcode].items()
328                elif student.entry_session < 2015:
329                    sorted_items = SCHOOLFEES[14][student.certcode].items()
330                elif student.entry_session < 2020:
331                    sorted_items = SCHOOLFEES[15][student.certcode].items()
332                elif student.entry_session < 2021:
333                    sorted_items = SCHOOLFEES[20][student.certcode].items()
334                elif student.entry_session < 2022:
335                    sorted_items = SCHOOLFEES[21][student.certcode].items()
336                else:
337                    sorted_items = SCHOOLFEES[22][student.certcode].items()
338                # Move tuition. We expect that tuition is the fourth element
339                sorted_items.insert(0, sorted_items.pop(3))
340                for item in sorted_items:
341                    try:
342                        if  item[1].startswith('100_') and student.state == CLEARED:
343                            # first year payment only
344                            item_amt = int(item[1].split('_')[1])
345                        else:
346                            item_amt = int(item[1])
347                        if self.context.p_category == 'schoolfee_1' and item[0] == 'tuition':
348                            item_amt /= 2
349                        # Add non-indigenous fee and session specific penalty fees
350                        try:
351                            academic_session = grok.getSite()['configuration'][str(self.context.p_session)]
352                        except KeyError:
353                            self.flash(
354                                _('Session configuration object is missing.'), type="danger")
355                            self.redirect(self.url(self.context, '@@index'))
356                            return
357                        if student.is_postgrad and item[0] == 'tuition':
358                            item_amt += academic_session.penalty_pg
359                            if student.lga and not student.lga.startswith('edo') \
360                                and student.entry_session < 2022:
361                                item_amt += 20000.0
362                        else:
363                            item_amt += academic_session.penalty_ug
364                        item_amt *= 100
365                        acct_num = ''
366                        bank_id = ''
367                        item_name = ''
368                        # Find appropriate bank
369                        try:
370                            bank = BANK_ACCOUNTS[item[0]]
371                        except: # transfer to faculty account
372                            if student.is_postgrad:
373                                bank = BANK_ACCOUNTS['postgrad']
374                            elif student.current_mode in (
375                                'ug_pt', 'de_pt','dp_pt', 'de_dsh', 'ug_dsh'):
376                                bank = BANK_ACCOUNTS['parttime']
377                            elif student.faccode in ('FAG', 'FAT', 'FBM', 'FMLS', 'fac1'):
378                                bank = BANK_ACCOUNTS['fac1']
379                            elif student.faccode in ('FCS', 'FED', 'FES', 'FET'):
380                                bank = BANK_ACCOUNTS['fac2']
381                            elif student.faccode in ('FLS', 'FLW', 'FMS', 'FPS', 'FSS'):
382                                bank = BANK_ACCOUNTS['fac3']
383                        acct_num = bank[0]
384                        bank_id = bank[1]
385                        item_name = FEE_NAMES[item[0]]
386                        xmltext += """
387<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)
388                        item_id += 1
389                    except:
390                        pass
391                xmldict['item_id'] = item_id
392                xmltext += """
393<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" />
394</item_details>
395</payment_item_detail>""" % xmldict
396            # no additional charges, determine faculty bank only
397            else:
398                if student.is_postgrad:
399                    bank = BANK_ACCOUNTS['postgrad']
400                elif student.faccode in ('FAG', 'FAT', 'FBM', 'FMLS', 'fac1'):
401                    bank = BANK_ACCOUNTS['fac1']
402                elif student.faccode in ('FCS', 'FED', 'FES', 'FET'):
403                    bank = BANK_ACCOUNTS['fac2']
404                elif student.faccode in ('FLS', 'FLW', 'FMS', 'FPS', 'FSS'):
405                    bank = BANK_ACCOUNTS['fac3']
406                xmldict['institution_acct'] = bank[0]
407                xmldict['institution_bank_id'] = bank[1]
408
409
410        # Clearance (acceptance) fee
411
412        elif category.startswith('clearance'):
413            # collect additional fees
414            if self.context.p_category == 'clearance_incl':
415                xmltext = """<payment_item_detail>
416<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s" department="%(department)s" faculty="%(faculty)s">""" % xmldict
417                item_id = 1
418                for item in ACCEPTANCEFEES[student.certcode].items():
419                    try:
420                        item_amt = 100 * int(item[1])
421                        bank = BANK_ACCOUNTS[item[0]]
422                        acct_num = bank[0]
423                        bank_id = bank[1]
424                        item_name = FEE_NAMES[item[0]]
425                        xmltext += """
426<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)
427                        item_id += 1
428                    except:
429                        pass
430                xmldict['item_id'] = item_id
431                xmltext += """
432<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" />
433</item_details>
434</payment_item_detail>""" % xmldict
435            # no additional charges, determine faculty bank only
436            else:
437                if student.is_postgrad:
438                    bank = BANK_ACCOUNTS['postgrad']
439                else:
440                    bank = BANK_ACCOUNTS['acceptance']
441                xmldict['institution_acct'] = bank[0]
442                xmldict['institution_bank_id'] = bank[1]
443
444        # Hostel Maintenance
445
446        elif category == 'hostel_maintenance':
447            xmldict['institution_amt'] = 100 * self.context.net_amt - 1000000
448            bank = BANK_ACCOUNTS[category]
449            xmldict['institution_acct'] = bank[0]
450            xmldict['institution_bank_id'] = bank[1]
451            xmltext = """<payment_item_detail>
452<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s" department="%(department)s" faculty="%(faculty)s">
453<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" />
454<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" />
455<item_detail item_id="3" item_name="Hostel Consumable Fee" item_amt="1000000" bank_id="123" acct_num="1012332141" />
456</item_details>
457</payment_item_detail>""" % xmldict
458
459        # Other fees
460
461        elif category in BANK_ACCOUNTS.keys():
462            bank = BANK_ACCOUNTS[category]
463            xmldict['institution_acct'] = bank[0]
464            xmldict['institution_bank_id'] = bank[1]
465
466        if not xmltext and provider_amt == 0:
467            xmltext = """<payment_item_detail>
468<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s" department="%(department)s" faculty="%(faculty)s">
469<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" />
470</item_details>
471</payment_item_detail>""" % xmldict
472        elif not xmltext:
473            xmltext = """<payment_item_detail>
474<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s" department="%(department)s" faculty="%(faculty)s">
475<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" />
476<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" />
477</item_details>
478</payment_item_detail>""" % xmldict
479        self.xml_data = """<input type="hidden" name="xml_data" value='%s'  />""" % xmltext
480        xmlitems = ''
481        xmldoc = minidom.parseString(xmltext)
482        itemlist = xmldoc.getElementsByTagName('item_detail')
483        for s in itemlist:
484            xmlitems += "%s (%s %s, %s (%s)),  " % (
485                s.attributes['item_name'].value,
486                u'\u20a6',
487                int(s.attributes['item_amt'].value)/100,
488                s.attributes['acct_num'].value,
489                s.attributes['bank_id'].value,
490                )
491        self.context.p_split_data = xmlitems
492        self.context.provider_amt = provider_amt
493        self.amount_auth = int(100 * self.context.amount_auth)
494        hashargs = (
495            self.context.p_id +
496            PRODUCT_ID +
497            self.pay_item_id +
498            str(int(self.amount_auth)) +
499            self.site_redirect_url +
500            MAC)
501        self.hashvalue = hashlib.sha512(hashargs).hexdigest()
502        return
503
504
505class CustomInterswitchPaymentRequestWebservicePageApplicant(
506    InterswitchPaymentRequestWebservicePageApplicant):
507    """Request webservice view for the CollegePAY gateway
508    """
509    grok.context(ICustomApplicantOnlinePayment)
510    gateway_host = HOST
511    gateway_url = URL
512    https = HTTPS
513    mac = MAC
514    product_id = PRODUCT_ID
515
516class CustomInterswitchPaymentVerifyWebservicePageApplicant(
517    InterswitchPaymentVerifyWebservicePageApplicant):
518    """Payment verify view for the CollegePAY gateway
519    """
520    grok.context(ICustomApplicantOnlinePayment)
521    gateway_host = HOST
522    gateway_url = URL
523    https = HTTPS
524    mac = MAC
525    product_id = PRODUCT_ID
526
527class CustomInterswitchPaymentRequestWebservicePageStudent(
528    InterswitchPaymentRequestWebservicePageStudent):
529    """Request webservice view for the CollegePAY gateway
530    """
531    grok.context(ICustomStudentOnlinePayment)
532    gateway_host = HOST
533    gateway_url = URL
534    https = HTTPS
535    mac = MAC
536    product_id = PRODUCT_ID
537
538class CustomInterswitchPaymentVerifyWebservicePageStudent(
539    InterswitchPaymentVerifyWebservicePageStudent):
540    """Payment verify view for the CollegePAY gateway
541    """
542    grok.context(ICustomStudentOnlinePayment)
543    gateway_host = HOST
544    gateway_url = URL
545    https = HTTPS
546    mac = MAC
547    product_id = PRODUCT_ID
Note: See TracBrowser for help on using the repository browser.