Index: /main/kofacustom.wdu/trunk/src/kofacustom/wdu/interfaces.py
===================================================================
--- /main/kofacustom.wdu/trunk/src/kofacustom/wdu/interfaces.py	(revision 12477)
+++ /main/kofacustom.wdu/trunk/src/kofacustom/wdu/interfaces.py	(revision 12478)
@@ -32,10 +32,4 @@
     # Base fees, do not remove.
 
-    school_fee_base = schema.Float(
-        title = _(u'School Fee (ignored)'),
-        default = 0.0,
-        required = False,
-        )
-
     application_fee = schema.Float(
         title = _(u'Application Fee (fallback)'),
@@ -70,4 +64,17 @@
     # Additional fees in custom package add here
 
+    school_fee_fresh = schema.Float(
+        title = _(u'School Fees Fresh Students'),
+        description = _('tution fee + other charges + tech fees + gateway fee'),
+        default = 0.0,
+        required = False,
+        )
+
+    school_fee_returning = schema.Float(
+        title = _(u'School Fees Returning Students'),
+        description = _('tution fee + other charges + tech fees + gateway fee'),
+        default = 0.0,
+        required = False,
+        )
 
     def getSessionString():
Index: /main/kofacustom.wdu/trunk/src/kofacustom/wdu/interswitch/browser.py
===================================================================
--- /main/kofacustom.wdu/trunk/src/kofacustom/wdu/interswitch/browser.py	(revision 12477)
+++ /main/kofacustom.wdu/trunk/src/kofacustom/wdu/interswitch/browser.py	(revision 12478)
@@ -17,5 +17,7 @@
 ##
 import httplib
+import hashlib
 import grok
+from waeup.kofa.interfaces import CLEARED
 from kofacustom.nigeria.interswitch.browser import (
     InterswitchPaymentRequestWebservicePageApplicant,
@@ -27,22 +29,24 @@
 from kofacustom.wdu.interfaces import MessageFactory as _
 
-PRODUCT_ID = '57'
-SITE_NAME = 'wdu-kofa.waeup.org'
-PROVIDER_ACCT = '00000000'
-PROVIDER_BANK_ID = '00'
+PRODUCT_ID = '6207'
+SITE_NAME = 'wdu.waeup.org'
+PROVIDER_ACCT = '0137712635'
+PROVIDER_BANK_ID = '10'
 PROVIDER_ITEM_NAME = 'BT Education'
-INSTITUTION_NAME = 'Skeleton'
+INSTITUTION_NAME = 'WDU'
 CURRENCY = '566'
-GATEWAY_AMT = 150.0
-#QUERY_URL = 'https://webpay.interswitchng.com/paydirect/services/TransactionQueryURL.aspx'
-#QUERY_URL = 'https://testwebpay.interswitchng.com/test_paydirect/services/TransactionQueryURL.aspx'
-POST_ACTION = 'https://webpay.interswitchng.com/paydirect/webpay/pay.aspx'
-#POST_ACTION = 'https://testwebpay.interswitchng.com/test_paydirect/webpay/pay.aspx'
+GATEWAY_AMT = 300.0
 
-HOST = 'webpay.interswitchng.com'
-#HOST = 'testwebpay.interswitchng.com'
-URL = '/paydirect/services/TransactionQueryWs.asmx'
-#URL = '/test_paydirect/services/TransactionQueryWs.asmx'
-httplib.HTTPConnection.debuglevel = 0
+POST_ACTION = 'https://stageserv.interswitchng.com/test_paydirect/pay'
+#POST_ACTION = 'https://webpay.interswitchng.com/paydirect/pay'
+
+#HOST = 'webpay.interswitchng.com'
+HOST = 'stageserv.interswitchng.com'
+HTTPS = True
+
+#URL = '/paydirect/services/TransactionQueryWs.asmx'
+URL = '/test_paydirect/services/TransactionQueryWS.asmx'
+
+httplib.HTTPSConnection.debuglevel = 0
 
 class CustomInterswitchPageStudent(InterswitchPageStudent):
@@ -55,4 +59,5 @@
     currency = CURRENCY
     product_id = PRODUCT_ID
+    mac = 'CEF793CBBE838AA0CBB29B74D571113B4EA6586D3BA77E7CFA0B95E278364EFC4526ED7BD255A366CDDE11F1F607F0F844B09D93B16F7CFE87563B2272007AB3'
 
     def update(self):
@@ -69,27 +74,30 @@
         xmldict['provider_bank_id'] = PROVIDER_BANK_ID
         xmldict['provider_item_name'] = PROVIDER_ITEM_NAME
-        # Institution data
-        xmldict['institution_acct'] = '00000000'
-        xmldict['institution_bank_id'] = '00'
-        xmldict['institution_amt'] = '0.0'
-        provider_amt = 0.0
-        self.pay_item_id = '0000'
+        xmldict['institution_acct_1'] = '4742014159'
+        xmldict['institution_bank_id_1'] = '47'
+        xmldict['institution_amt_1'] = '0.0'
+        xmldict['institution_acct_2'] = '0029688237'
+        xmldict['institution_bank_id_2'] = '11'
+        xmldict['institution_amt_2'] = '0.0'
+        provider_amt = 4000.0
+        self.pay_item_id = '101'
+        # other charges + tech fee
+        if self.context.student.state == CLEARED:
+            institution_amt_2 = 207500.0 + 1000.0
+        else :
+            institution_amt_2 = 150500.0 + 1000.0
         xmldict['provider_amt'] = 100 * provider_amt
         xmldict['institution_item_name'] = self.category
         xmldict['institution_name'] = INSTITUTION_NAME
-        xmldict['institution_amt'] = 100 * (
-            self.context.amount_auth - provider_amt - GATEWAY_AMT)
+        xmldict['institution_amt_1'] = 100 * (
+            self.context.amount_auth - provider_amt - GATEWAY_AMT - institution_amt_2)
+        xmldict['institution_amt_2'] = 100 * institution_amt_2
+
         # Interswitch amount is not part of the xml data
-        if provider_amt == 0:
-            xmltext = """<payment_item_detail>
+        xmltext = """<payment_item_detail>
 <item_details detail_ref="%(detail_ref)s" college="%(institution_name)s" department="%(department)s" faculty="%(faculty)s">
-<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" />
-</item_details>
-</payment_item_detail>""" % xmldict
-        else:
-            xmltext = """<payment_item_detail>
-<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s" department="%(department)s" faculty="%(faculty)s">
-<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" />
-<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" />
+<item_detail item_id="1" item_name="%(institution_item_name)s" item_amt="%(institution_amt_1)d" bank_id="%(institution_bank_id_1)s" acct_num="%(institution_acct_1)s" />
+<item_detail item_id="2" item_name="other charges and tech fee" item_amt="%(institution_amt_2)d" bank_id="%(institution_bank_id_2)s" acct_num="%(institution_acct_2)s" />
+<item_detail item_id="3" item_name="%(provider_item_name)s" item_amt="%(provider_amt)d" bank_id="%(provider_bank_id)s" acct_num="%(provider_acct)s" />
 </item_details>
 </payment_item_detail>""" % xmldict
@@ -97,42 +105,15 @@
         self.context.provider_amt = provider_amt
         self.context.gateway_amt = GATEWAY_AMT
+
+        hashargs = (
+            self.context.p_id +
+            PRODUCT_ID +
+            self.pay_item_id +
+            str(int(self.amount_auth)) +
+            self.site_redirect_url +
+            self.mac)
+        self.hashvalue = hashlib.sha512(hashargs).hexdigest()
         return
 
-class CustomInterswitchPageApplicant(InterswitchPageApplicant):
-    """ View which sends a POST request to the Interswitch
-    CollegePAY payment gateway.
-    """
-    grok.context(ICustomApplicantOnlinePayment)
-    action = POST_ACTION
-    site_name = SITE_NAME
-    currency = CURRENCY
-    pay_item_id = '0000'
-    product_id = PRODUCT_ID
-
-    def update(self):
-        super(CustomInterswitchPageApplicant, self).update()
-        xmldict = {}
-        provider_amt = 400.0
-        xmldict['institution_acct'] = '00000000000'
-        xmldict['institution_bank_id'] = '00'
-        xmldict['detail_ref'] = self.context.p_id
-        xmldict['provider_amt'] = 100 * provider_amt
-        xmldict['provider_acct'] = PROVIDER_ACCT
-        xmldict['provider_bank_id'] = PROVIDER_BANK_ID
-        xmldict['provider_item_name'] = PROVIDER_ITEM_NAME
-        xmldict['institution_amt'] = 100 * (self.context.amount_auth - provider_amt - GATEWAY_AMT)
-        xmldict['institution_item_name'] = self.context.p_category
-        xmldict['institution_name'] = INSTITUTION_NAME
-        # Interswitch amount is not part of the xml data
-        xmltext = """<payment_item_detail>
-<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s">
-<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" />
-<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" />
-</item_details>
-</payment_item_detail>""" % xmldict
-        self.xml_data = """<input type="hidden" name="xml_data" value='%s'  />""" % xmltext
-        self.context.provider_amt = provider_amt
-        self.context.gateway_amt = GATEWAY_AMT
-        return
 
 class CustomInterswitchPaymentRequestWebservicePageStudent(
@@ -144,4 +125,5 @@
     gateway_host = HOST
     gateway_url = URL
+    https = HTTPS
 
 class CustomInterswitchPaymentRequestWebservicePageApplicant(
@@ -153,2 +135,3 @@
     gateway_host = HOST
     gateway_url = URL
+    https = HTTPS
Index: /main/kofacustom.wdu/trunk/src/kofacustom/wdu/interswitch/tests.py
===================================================================
--- /main/kofacustom.wdu/trunk/src/kofacustom/wdu/interswitch/tests.py	(revision 12477)
+++ /main/kofacustom.wdu/trunk/src/kofacustom/wdu/interswitch/tests.py	(revision 12478)
@@ -52,4 +52,6 @@
 
     def test_interswitch_form(self):
+        self.app['configuration']['2004'].school_fee_fresh = 442800.0
+        self.app['configuration']['2004'].school_fee_returning = 385800.0
         # Manager can access InterswitchForm
         self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
@@ -68,11 +70,9 @@
                            self.browser.contents)
         self.assertMatches(
-            '...<span>40000.0</span>...',
+            '...<span>442800.0</span>...',
             self.browser.contents)
         self.payment_url = self.browser.url
         self.browser.getLink("CollegePAY", index=0).click()
-        # The total amount to be processed by Interswitch
-        # has been reduced by the Interswitch fee of 150 Nairas
-        self.assertMatches('...<input type="hidden" name="pay_item_id" value="0000" />...',
+        self.assertMatches('...<input type="hidden" name="pay_item_id" value="101" />...',
                            self.browser.contents)
         self.assertMatches('...Total Amount Authorized:...',
@@ -80,8 +80,8 @@
         self.assertEqual(self.student.current_mode, 'ug_ft')
         self.assertMatches(
-            '...<input type="hidden" name="amount" value="4000000" />...',
-            self.browser.contents)
-        self.assertMatches(
-            '...item_name="School Fee" item_amt="4000000" bank_id="00" acct_num="00000000"...',
+            '...<input type="hidden" name="amount" value="44280000" />...',
+            self.browser.contents)
+        self.assertMatches(
+            '...item_name="School Fees" item_amt="23000000" bank_id="47" acct_num="4742014159"...',
             self.browser.contents)
 
Index: /main/kofacustom.wdu/trunk/src/kofacustom/wdu/students/utils.py
===================================================================
--- /main/kofacustom.wdu/trunk/src/kofacustom/wdu/students/utils.py	(revision 12477)
+++ /main/kofacustom.wdu/trunk/src/kofacustom/wdu/students/utils.py	(revision 12478)
@@ -30,2 +30,120 @@
     # refix
     STUDENT_ID_PREFIX = u'D'
+
+    def setPaymentDetails(self, category, student,
+            previous_session, previous_level):
+        """Create Payment object and set the payment data of a student for
+        the payment category specified.
+
+        """
+        p_item = u''
+        amount = 0.0
+        if previous_session:
+            if previous_session < student['studycourse'].entry_session:
+                return _('The previous session must not fall below '
+                         'your entry session.'), None
+            if category == 'schoolfee':
+                # School fee is always paid for the following session
+                if previous_session > student['studycourse'].current_session:
+                    return _('This is not a previous session.'), None
+            else:
+                if previous_session > student['studycourse'].current_session - 1:
+                    return _('This is not a previous session.'), None
+            p_session = previous_session
+            p_level = previous_level
+            p_current = False
+        else:
+            p_session = student['studycourse'].current_session
+            p_level = student['studycourse'].current_level
+            p_current = True
+        academic_session = self._getSessionConfiguration(p_session)
+        if academic_session == None:
+            return _(u'Session configuration object is not available.'), None
+        # Determine fee.
+        if category == 'schoolfee':
+            try:
+                certificate = student['studycourse'].certificate
+                p_item = certificate.code
+            except (AttributeError, TypeError):
+                return _('Study course data are incomplete.'), None
+            if previous_session:
+                # Students can pay for previous sessions in all
+                # workflow states.  Fresh students are excluded by the
+                # update method of the PreviousPaymentAddFormPage.
+                if previous_level == 100:
+                    amount = getattr(
+                        academic_session, 'school_fee_fresh', 0.0)
+                else:
+                    amount = getattr(
+                        academic_session, 'school_fee_returning', 0.0)
+            else:
+                if student.state == CLEARED:
+                    amount = getattr(
+                        academic_session, 'school_fee_fresh', 0.0)
+                elif student.state == RETURNING:
+                    # In case of returning school fee payment the
+                    # payment session and level contain the values of
+                    # the session the student has paid for. Payment
+                    # session is always next session.
+                    p_session, p_level = self.getReturningData(student)
+                    academic_session = self._getSessionConfiguration(p_session)
+                    if academic_session == None:
+                        return _(
+                            u'Session configuration object is not available.'
+                            ), None
+                    amount = getattr(
+                        academic_session, 'school_fee_returning', 0.0)
+                elif student.is_postgrad and student.state == PAID:
+                    # Returning postgraduate students also pay for the
+                    # next session but their level always remains the
+                    # same.
+                    p_session += 1
+                    academic_session = self._getSessionConfiguration(p_session)
+                    if academic_session == None:
+                        return _(
+                            u'Session configuration object is not available.'
+                            ), None
+                    amount = 0.0 # not yet configured
+        elif category == 'clearance':
+            try:
+                p_item = student['studycourse'].certificate.code
+            except (AttributeError, TypeError):
+                return _('Study course data are incomplete.'), None
+            amount = academic_session.clearance_fee
+        elif category == 'bed_allocation':
+            p_item = self.getAccommodationDetails(student)['bt']
+            amount = academic_session.booking_fee
+        elif category == 'hostel_maintenance':
+            amount = 0.0
+            bedticket = student['accommodation'].get(
+                str(student.current_session), None)
+            if bedticket:
+                p_item = bedticket.bed_coordinates
+                if bedticket.bed.__parent__.maint_fee > 0:
+                    amount = bedticket.bed.__parent__.maint_fee
+                else:
+                    # fallback
+                    amount = academic_session.maint_fee
+            else:
+                # Should not happen because this is already checked
+                # in the browser module, but anyway ...
+                portal_language = getUtility(IKofaUtils).PORTAL_LANGUAGE
+                p_item = trans(_('no bed allocated'), portal_language)
+        elif category == 'transcript':
+            amount = academic_session.transcript_fee
+        if amount in (0.0, None):
+            return _('Amount could not be determined.'), None
+        if self.samePaymentMade(student, category, p_item, p_session):
+            return _('This type of payment has already been made.'), None
+        if self._isPaymentDisabled(p_session, category, student):
+            return _('Payment temporarily disabled.'), None
+        payment = createObject(u'waeup.StudentOnlinePayment')
+        timestamp = ("%d" % int(time()*10000))[1:]
+        payment.p_id = "p%s" % timestamp
+        payment.p_category = category
+        payment.p_item = p_item
+        payment.p_session = p_session
+        payment.p_level = p_level
+        payment.p_current = p_current
+        payment.amount_auth = amount
+        return None, payment
Index: /main/kofacustom.wdu/trunk/src/kofacustom/wdu/utils/utils.py
===================================================================
--- /main/kofacustom.wdu/trunk/src/kofacustom/wdu/utils/utils.py	(revision 12477)
+++ /main/kofacustom.wdu/trunk/src/kofacustom/wdu/utils/utils.py	(revision 12478)
@@ -18,4 +18,5 @@
 """Customize general helper utilities for Kofa.
 """
+from copy import deepcopy
 from kofacustom.nigeria.utils.utils import NigeriaKofaUtils
 
@@ -24,2 +25,16 @@
     """
 
+    PAYMENT_CATEGORIES = {
+        'schoolfee': 'School Fees',
+        #'clearance': 'Acceptance Fee',
+        #'bed_allocation': 'Bed Allocation Fee',
+        #'hostel_maintenance': 'Hostel Maintenance Fee',
+        #'transfer': 'Transfer Fee',
+        #'gown': 'Gown Hire Fee',
+        'application': 'Application Fee',
+        #'transcript': 'Transcript Fee',
+        }
+
+    SELECTABLE_PAYMENT_CATEGORIES = deepcopy(PAYMENT_CATEGORIES)
+
+    PREVIOUS_PAYMENT_CATEGORIES = deepcopy(SELECTABLE_PAYMENT_CATEGORIES)
