Index: main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/interswitch/browser.py
===================================================================
--- main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/interswitch/browser.py	(revision 14342)
+++ main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/interswitch/browser.py	(revision 14344)
@@ -38,4 +38,5 @@
 CURRENCY = '566'
 GATEWAY_AMT = 300.0
+MAC = '9309B5CBF1BFB09693C6F5F578046E3FCAB0A2538C3FE4221A6E63AFD348DE888E655F9C7E9F112151A702B6B09E6A7ACC5B3BF3C701F0C1B0D8EA6C1872AE94'
 
 POST_ACTION = 'https://webpay.interswitchng.com/paydirect/pay'
@@ -58,5 +59,5 @@
     currency = CURRENCY
     product_id = PRODUCT_ID
-    mac = '9309B5CBF1BFB09693C6F5F578046E3FCAB0A2538C3FE4221A6E63AFD348DE888E655F9C7E9F112151A702B6B09E6A7ACC5B3BF3C701F0C1B0D8EA6C1872AE94'
+    mac = MAC
 
     def update(self):
@@ -128,5 +129,5 @@
     pay_item_id = '101'
     product_id = PRODUCT_ID
-    mac = '9309B5CBF1BFB09693C6F5F578046E3FCAB0A2538C3FE4221A6E63AFD348DE888E655F9C7E9F112151A702B6B09E6A7ACC5B3BF3C701F0C1B0D8EA6C1872AE94'
+    mac = MAC
 
     def update(self):
@@ -177,5 +178,5 @@
     gateway_host = HOST
     gateway_url = URL
-    mac = '9309B5CBF1BFB09693C6F5F578046E3FCAB0A2538C3FE4221A6E63AFD348DE888E655F9C7E9F112151A702B6B09E6A7ACC5B3BF3C701F0C1B0D8EA6C1872AE94'
+    mac = MAC
 
 class CustomInterswitchPaymentVerifyWebservicePageStudent(
@@ -187,5 +188,5 @@
     gateway_host = HOST
     gateway_url = URL
-    mac = '9309B5CBF1BFB09693C6F5F578046E3FCAB0A2538C3FE4221A6E63AFD348DE888E655F9C7E9F112151A702B6B09E6A7ACC5B3BF3C701F0C1B0D8EA6C1872AE94'
+    mac = MAC
 
 class CustomInterswitchPaymentRequestWebservicePageApplicant(
@@ -197,5 +198,5 @@
     gateway_host = HOST
     gateway_url = URL
-    mac = '9309B5CBF1BFB09693C6F5F578046E3FCAB0A2538C3FE4221A6E63AFD348DE888E655F9C7E9F112151A702B6B09E6A7ACC5B3BF3C701F0C1B0D8EA6C1872AE94'
+    mac = MAC
 
 class CustomInterswitchPaymentVerifyWebservicePageApplicant(
@@ -207,3 +208,3 @@
     gateway_host = HOST
     gateway_url = URL
-    mac = '9309B5CBF1BFB09693C6F5F578046E3FCAB0A2538C3FE4221A6E63AFD348DE888E655F9C7E9F112151A702B6B09E6A7ACC5B3BF3C701F0C1B0D8EA6C1872AE94'
+    mac = MAC
Index: main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/interswitch/tests.py
===================================================================
--- main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/interswitch/tests.py	(revision 14342)
+++ main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/interswitch/tests.py	(revision 14344)
@@ -81,5 +81,5 @@
             self.browser.contents)
         self.assertMatches(
-            '...item_name="School Fee" item_amt="7950000" bank_id="7" acct_num="1019684470"...',
+            '...item_name="School Fee (total)" item_amt="7950000" bank_id="7" acct_num="1019684470"...',
             self.browser.contents)
 
Index: main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/students/payments.py
===================================================================
--- main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/students/payments.py	(revision 14342)
+++ main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/students/payments.py	(revision 14344)
@@ -21,6 +21,9 @@
 import grok
 from zope.component.interfaces import IFactory
+from zope.schema.interfaces import ConstraintNotSatisfied
 from zope.interface import implementedBy
+from hurry.workflow.interfaces import IWorkflowInfo
 from waeup.kofa.students.interfaces import IStudentNavigation
+from waeup.kofa.students.workflow import CLEARED, RETURNING, PAID
 from waeup.kofa.utils.helpers import attrs_to_fields
 from kofacustom.nigeria.students.payments import (
@@ -59,5 +62,5 @@
                 return error
             self.ac = pin
-        elif self.p_category.startswith('schoolfee'):
+        elif self.p_category in ('schoolfee', 'schoolfee_1') :
             # Bypass activation code creation if next session
             # can be started directly.
Index: main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/students/tests/test_browser.py
===================================================================
--- main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/students/tests/test_browser.py	(revision 14342)
+++ main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/students/tests/test_browser.py	(revision 14344)
@@ -42,4 +42,72 @@
     layer = FunctionalLayer
 
-    def test_dummytest(self):
+    def test_for_instalment_payments(self):
+
+        #configuration_1 = createObject('waeup.SessionConfiguration')
+        #configuration_1.academic_session = 2015
+        #self.app['configuration'].addSessionConfiguration(configuration_1)
+        self.student['studycourse'].certificate.study_mode = 'ug_ft'
+        self.student.nationality = u'NG'
+        # Fresh student
+        IWorkflowState(self.student).setState('cleared')
+        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+        self.browser.open(self.payments_path + '/addop')
+        self.browser.open(self.payments_path + '/addop')
+        # Add first instalment
+        self.browser.getControl(name="form.p_category").value = ['schoolfee_1']
+        self.browser.getControl("Create ticket").click()
+        self.assertTrue('ticket created' in self.browser.contents)
+        self.browser.open(self.payments_path)
+        ctrl = self.browser.getControl(name='val_id')
+        p_id = ctrl.options[0]
+        self.browser.open(self.payments_path + '/' + p_id + '/approve')
+        # Add the second instalment ...
+        self.browser.open(self.payments_path + '/addop')
+        self.browser.getControl(name="form.p_category").value = ['schoolfee_2']
+        self.browser.getControl("Create ticket").click()
+        self.assertTrue('ticket created' in self.browser.contents)
+        # ... approve the second instalment ...
+        ctrl = self.browser.getControl(name='val_id')
+        p_id = ctrl.options[1]
+        self.browser.open(self.payments_path + '/' + p_id + '/approve')
+        self.assertEqual(self.student['payments'].values()[0].p_category, 'schoolfee_1')
+        self.assertEqual(self.student['payments'].values()[1].p_category, 'schoolfee_2')
+        # 79200 / 2 + 300
+        self.assertEqual(self.student['payments'].values()[0].amount_auth, 39900.0)
+        self.assertEqual(self.student['payments'].values()[1].amount_auth, 39900.0)
+        # The  two payments belong to the same session and level.
+        self.assertEqual(self.student['payments'].values()[0].p_session, 2004)
+        self.assertEqual(self.student['payments'].values()[0].p_level, 100)
+        self.assertEqual(self.student['payments'].values()[1].p_session, 2004)
+        self.assertEqual(self.student['payments'].values()[1].p_level, 100)
+
+        # Returning student
+        configuration_2 = createObject('waeup.SessionConfiguration')
+        configuration_2.academic_session = 2005
+        self.app['configuration'].addSessionConfiguration(configuration_2)
+        IWorkflowState(self.student).setState('returning')
+        self.browser.open(self.payments_path + '/addop')
+        self.browser.getControl(name="form.p_category").value = ['schoolfee_1']
+        self.browser.getControl("Create ticket").click()
+        self.browser.open(self.payments_path + '/addop')
+        self.browser.getControl(name="form.p_category").value = ['schoolfee_2']
+        self.browser.getControl("Create ticket").click()
+        self.browser.open(self.payments_path)
+        ctrl = self.browser.getControl(name='val_id')
+        # Nothing happens if we approve the 2nd instalment for session 2005
+        self.browser.open(self.payments_path + '/' + ctrl.options[3] + '/approve')
+        self.assertEqual(self.student.state, 'returning')
+        # Workflow transition is trigered if we approve the 1st indtalment
+        self.browser.open(self.payments_path + '/' + ctrl.options[2] + '/approve')
+        self.assertEqual(self.student.state, 'school fee paid')
+        self.assertEqual(self.student.current_level, 200)
+        self.assertEqual(self.student.current_session, 2005)
+        # 63100 / 2 + 300
+        self.assertEqual(self.student['payments'].values()[2].amount_auth, 31850.0)
+        self.assertEqual(self.student['payments'].values()[3].amount_auth, 31850.0)
+        # The last two payments belong to the same session and level.
+        self.assertEqual(self.student['payments'].values()[2].p_session, 2005)
+        self.assertEqual(self.student['payments'].values()[2].p_level, 200)
+        self.assertEqual(self.student['payments'].values()[3].p_session, 2005)
+        self.assertEqual(self.student['payments'].values()[3].p_level, 200)
         return
Index: main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/students/tests/test_utils.py
===================================================================
--- main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/students/tests/test_utils.py	(revision 14342)
+++ main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/students/tests/test_utils.py	(revision 14344)
@@ -27,12 +27,22 @@
         self.app['configuration']['2016'].clearance_fee = 10234.0
 
-        error, payment = utils.setPaymentDetails('schoolfee', self.student)
-        self.assertEqual(payment, None)
-        self.assertEqual(error, u'Amount could not be determined.')
-        IWorkflowState(self.student).setState('cleared')
         error, payment = utils.setPaymentDetails('schoolfee',self.student)
         self.assertEqual(payment.p_level, 100)
         self.assertEqual(payment.p_session, 2016)
         self.assertEqual(payment.amount_auth, 79500.0)
+        self.assertEqual(payment.p_item, u'CERT1')
+        self.assertEqual(error, None)
+
+        error, payment = utils.setPaymentDetails('schoolfee_1',self.student)
+        self.assertEqual(payment.p_level, 100)
+        self.assertEqual(payment.p_session, 2016)
+        self.assertEqual(payment.amount_auth, 39900.0)
+        self.assertEqual(payment.p_item, u'CERT1')
+        self.assertEqual(error, None)
+
+        error, payment = utils.setPaymentDetails('schoolfee_2',self.student)
+        self.assertEqual(payment.p_level, 100)
+        self.assertEqual(payment.p_session, 2016)
+        self.assertEqual(payment.amount_auth, 39900.0)
         self.assertEqual(payment.p_item, u'CERT1')
         self.assertEqual(error, None)
Index: main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/students/utils.py
===================================================================
--- main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/students/utils.py	(revision 14342)
+++ main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/students/utils.py	(revision 14344)
@@ -75,5 +75,5 @@
             return _(u'Session configuration object is not available.'), None
         # Determine fee.
-        if category == 'schoolfee':
+        if category.startswith('schoolfee'):
             try:
                 certificate = student['studycourse'].certificate
@@ -88,13 +88,15 @@
                     return _(u'Session configuration object '
                               'is not available.'), None
-            if student.state in (RETURNING, CLEARED):
-                if p_level in PAYMENT_LEVELS:
-                    amount = SCHOOL_FEES.get_fee(
-                        (
-                         local_nonlocal(student),
-                         student.current_mode,
-                         p_level)
-                        )
-                    amount += GATEWAY_AMT
+            if p_level in PAYMENT_LEVELS:
+                amount = SCHOOL_FEES.get_fee(
+                    (
+                     local_nonlocal(student),
+                     student.current_mode,
+                     p_level)
+                    )
+            if amount and category in ('schoolfee_1', 'schoolfee_2'):
+                amount /= 2
+            if amount:
+                amount += GATEWAY_AMT
         elif category == 'clearance':
             try:
Index: main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/utils/utils.py
===================================================================
--- main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/utils/utils.py	(revision 14342)
+++ main/kofacustom.coewarri/trunk/src/kofacustom/coewarri/utils/utils.py	(revision 14344)
@@ -18,4 +18,5 @@
 """Customize general helper utilities for Kofa.
 """
+from copy import deepcopy
 from kofacustom.nigeria.utils.utils import NigeriaKofaUtils
 
@@ -43,2 +44,18 @@
         'no': 'no application',
         }
+
+    PAYMENT_CATEGORIES = {
+        'schoolfee': 'School Fee (total)',
+        'schoolfee_1': 'School Fee (1st instalment)',
+        'schoolfee_2': 'School Fee (2nd instalment)',
+        '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',
+        #'late_registration': 'Late Course Registration Fee'
+        }
+
+    SELECTABLE_PAYMENT_CATEGORIES = deepcopy(PAYMENT_CATEGORIES)
