Index: main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/interfaces.py
===================================================================
--- main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/interfaces.py	(revision 15644)
+++ main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/interfaces.py	(revision 15645)
@@ -79,4 +79,81 @@
     # Additional fees in custom package add here
 
+    late_registration_fee = schema.Float(
+        title = _(u'Late Registration Fee'),
+        default = 0.0,
+        required = False,
+        )
+
+    science_fee = schema.Float(
+        title = _(u'Science Bench Fee'),
+        default = 0.0,
+        required = False,
+        )
+
+    clinical_fee = schema.Float(
+        title = _(u'Clinical Fee (Medical Students)'),
+        default = 0.0,
+        required = False,
+        )
+
+    develop_fee = schema.Float(
+        title = _(u'Development Fee'),
+        default = 0.0,
+        required = False,
+        )
+
+    municipal_fee = schema.Float(
+        title = _(u'Municipal Fee'),
+        default = 0.0,
+        required = False,
+        )
+
+    alumni_fee = schema.Float(
+        title = _(u'Alumni Fee'),
+        default = 0.0,
+        required = False,
+        )
+
+    conv_fee = schema.Float(
+        title = _(u'Convocation Fee'),
+        default = 0.0,
+        required = False,
+        )
+
+    matric_fee = schema.Float(
+        title = _(u'Matriculation Fee'),
+        default = 0.0,
+        required = False,
+        )
+
+    waecneco_fee = schema.Float(
+        title = _(u'WAEC & NECO Verification Fee'),
+        default = 0.0,
+        required = False,
+        )
+
+    jambver_fee = schema.Float(
+        title = _(u'JAMB Verification Fee'),
+        default = 0.0,
+        required = False,
+        )
+
+    book_fee = schema.Float(
+        title = _(u'Book Deposit'),
+        default = 0.0,
+        required = False,
+        )
+
+    parentsconsult_fee = schema.Float(
+        title = _(u'Parents Consultative Forum (PCF) Fee'),
+        default = 0.0,
+        required = False,
+        )
+
+    pharmlab_fee = schema.Float(
+        title = _(u'Pharmacy Lab Support Fee'),
+        default = 0.0,
+        required = False,
+        )
 
     def getSessionString():
Index: main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/interswitch/browser.py
===================================================================
--- main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/interswitch/browser.py	(revision 15644)
+++ main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/interswitch/browser.py	(revision 15645)
@@ -30,13 +30,13 @@
 from kofacustom.iuokada.interfaces import MessageFactory as _
 
-PRODUCT_ID = '' # must be provided by Interswitch
+PRODUCT_ID = '6207' # must be provided by Interswitch
 SITE_NAME = 'iuokada-kofa.waeup.org'
-PROVIDER_ACCT = '00000000'
-PROVIDER_BANK_ID = '00'
-PROVIDER_ITEM_NAME = 'BT Education'
+PROVIDER_ACCT = '0773411069'
+PROVIDER_BANK_ID = '31'
+PROVIDER_ITEM_NAME = 'WAeAC'
 INSTITUTION_NAME = 'IUOkada'
 CURRENCY = '566'
 GATEWAY_AMT = 150.0
-MAC = '' # must be provided by Interswitch
+MAC = 'CEF793CBBE838AA0CBB29B74D571113B4EA6586D3BA77E7CFA0B95E278364EFC4526ED7BD255A366CDDE11F1F607F0F844B09D93B16F7CFE87563B2272007AB3' # must be provided by Interswitch
 
 #POST_ACTION = 'https://webpay.interswitchng.com/paydirect/pay'
Index: main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/students/utils.py
===================================================================
--- main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/students/utils.py	(revision 15644)
+++ main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/students/utils.py	(revision 15645)
@@ -30,2 +30,113 @@
     # refix
     STUDENT_ID_PREFIX = u'I'
+
+    def setPaymentDetails(self, category, student,
+            previous_session, previous_level):
+        """Create a payment ticket 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(certificate, 'school_fee_1', 0.0)
+                else:
+                    amount = getattr(certificate, 'school_fee_2', 0.0)
+            else:
+                if student.state == CLEARED:
+                    amount = getattr(certificate, 'school_fee_1', 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(certificate, 'school_fee_2', 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 = getattr(certificate, 'school_fee_2', 0.0)
+        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 is not None and bedticket.bed is not None:
+                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:
+                return _(u'No bed allocated.'), None
+        else:
+            fee_name = category + '_fee'
+            amount = getattr(academic_session, fee_name, 0.0)
+        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 _('This category of payments has been 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.iuokada/trunk/src/kofacustom/iuokada/utils/utils.py
===================================================================
--- main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/utils/utils.py	(revision 15644)
+++ main/kofacustom.iuokada/trunk/src/kofacustom/iuokada/utils/utils.py	(revision 15645)
@@ -18,4 +18,6 @@
 """Customize general helper utilities for Kofa.
 """
+
+from copy import deepcopy
 from kofacustom.nigeria.utils.utils import NigeriaKofaUtils
 
@@ -24,2 +26,53 @@
     """
 
+    PAYMENT_CATEGORIES = {
+        'schoolfee': 'School Fee',
+        'clearance': 'Acceptance Fee',
+        'bed_allocation': 'Bed Allocation Fee',
+        'hostel_maintenance': 'Accommodation',
+        #'transfer': 'Transfer Fee',
+        #'gown': 'Gown Hire Fee',
+        'application': 'Application Fee',
+        'app_balance': 'Application Fee Balance',
+        'transcript': 'Transcript Fee',
+        'late_registration': 'Late Registration Fee',
+        'science': 'Science Bench Fee',
+        'clinical': 'Clinical Fee (Medical Students)',
+        'develop': 'Development Fee',
+        'municipal': 'Municipal Fee',
+        'alumni': 'Alumni Fee',
+        'conv': 'Convocation Fee',
+        'matric': 'Matriculation Fee',
+        'waecneco': 'WAEC & NECO Verification',
+        'jambver': 'JAMB Verification',
+        'book': 'Book Deposit',
+        'parentsconsult': 'Parents Consultative Forum (PCF) Fee',
+        'pharmlab': 'Pharmacy Lab Support Fee',
+        }
+
+    SELECTABLE_PAYMENT_CATEGORIES = {
+        'schoolfee': 'School Fee',
+        'clearance': 'Acceptance Fee',
+        #'bed_allocation': 'Bed Allocation Fee',
+        'hostel_maintenance': 'Accommodation',
+        #'transfer': 'Transfer Fee',
+        #'gown': 'Gown Hire Fee',
+        'application': 'Application Fee',
+        #'app_balance': 'Application Fee Balance',
+        #'transcript': 'Transcript Fee',
+        'late_registration': 'Late Registration Fee',
+        'science': 'Science Bench Fee',
+        'clinical': 'Clinical Fee (Medical Students)',
+        'develop': 'Development Fee',
+        'municipal': 'Municipal Fee',
+        'alumni': 'Alumni Fee',
+        'conv': 'Convocation Fee',
+        'matric': 'Matriculation Fee',
+        'waecneco': 'WAEC & NECO Verification',
+        'jambver': 'JAMB Verification',
+        'book': 'Book Deposit',
+        'parentsconsult': 'Parents Consultative Forum (PCF) Fee',
+        'pharmlab': 'Pharmacy Lab Support Fee',
+        }
+
+    PREVIOUS_PAYMENT_CATEGORIES = deepcopy(SELECTABLE_PAYMENT_CATEGORIES)
