Index: main/waeup.uniben/trunk/src/waeup/uniben/students/browser.py
===================================================================
--- main/waeup.uniben/trunk/src/waeup/uniben/students/browser.py	(revision 8582)
+++ main/waeup.uniben/trunk/src/waeup/uniben/students/browser.py	(revision 8598)
@@ -178,9 +178,4 @@
     form_fields = grok.AutoFields(ICustomStudentOnlinePayment).select(
         'p_category')
-    factory = u'waeup.CustomStudentOnlinePayment'
-
-    def _fillCustomFields(self, payment, pay_details):
-        # No custom fields at the moment
-        return payment
 
 class CustomOnlinePaymentFakeApprovePage(OnlinePaymentFakeApprovePage):
Index: main/waeup.uniben/trunk/src/waeup/uniben/students/tests/test_browser.py
===================================================================
--- main/waeup.uniben/trunk/src/waeup/uniben/students/tests/test_browser.py	(revision 8582)
+++ main/waeup.uniben/trunk/src/waeup/uniben/students/tests/test_browser.py	(revision 8598)
@@ -30,5 +30,4 @@
 from waeup.uniben.students.batching import CustomStudentProcessor
 from waeup.uniben.testing import FunctionalLayer
-from waeup.uniben.students.utils import get_school_fee
 from waeup.uniben.students.interfaces import (
     ICustomStudentStudyCourse, ICustomStudent,
@@ -303,13 +302,5 @@
         return
 
-    def test_get_schoolfee(self):
-        self.assertEqual(get_school_fee(self.student),0.0)
-        IWorkflowState(self.student).setState('cleared')
-        self.assertEqual(get_school_fee(self.student),40000.0)
-        IWorkflowState(self.student).setState('returning')
-        self.assertEqual(get_school_fee(self.student),20000.0)
-        return
-
-    def test_get_payment_details(self):
+    def test_set_payment_details(self):
         self.app['configuration']['2004'].gown_fee = 150.0
         self.app['configuration']['2004'].transfer_fee = 90.0
@@ -317,27 +308,58 @@
         self.app['configuration']['2004'].maint_fee = 180.0
         utils = getUtility(IStudentsUtils)
-        self.assertEqual(utils.getPaymentDetails('schoolfee',self.student),
-            {'p_level': 100, 'p_session': 2004, 'amount': 0.0,
-            'p_item': u'CERT1', 'error': u'Amount could not be determined.'}
-            )
-        self.assertEqual(utils.getPaymentDetails('clearance',self.student),
-            {'p_level': 100, 'p_session': 2004, 'amount': 34250.0,
-            'p_item': u'CERT1', 'error': u''}
-            )
-        self.assertEqual(utils.getPaymentDetails('gown',self.student),
-            {'p_level': 100, 'p_session': 2004, 'amount': 150.0,
-            'p_item': u'', 'error': u''}
-            )
-        self.assertEqual(utils.getPaymentDetails('hostel_maintenance',self.student),
-            {'p_level': 100, 'p_session': 2004, 'amount': 180.0,
-            'p_item': u'', 'error': u''}
-            )
-        self.assertEqual(utils.getPaymentDetails('bed_allocation',self.student),
-            {'p_level': 100, 'p_session': 2004, 'amount': 150.0,
-            'p_item': u'', 'error': u''}
-            )
-        self.assertEqual(utils.getPaymentDetails('transfer',self.student),
-            {'p_level': 100, 'p_session': 2004, 'amount': 90.0,
-            'p_item': u'', 'error': u''}
-            )
+
+        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, 2004)
+        self.assertEqual(payment.amount_auth, 40000.0)
+        self.assertEqual(payment.p_item, u'CERT1')
+        self.assertEqual(error, None)
+
+        IWorkflowState(self.student).setState('returning')
+        error, payment = utils.setPaymentDetails('schoolfee',self.student)
+        self.assertEqual(payment.p_level, 200)
+        self.assertEqual(payment.p_session, 2005)
+        self.assertEqual(payment.amount_auth, 20000.0)
+        self.assertEqual(payment.p_item, u'CERT1')
+        self.assertEqual(error, None)
+
+        error, payment = utils.setPaymentDetails('clearance',self.student)
+        self.assertEqual(payment.p_level, 100)
+        self.assertEqual(payment.p_session, 2004)
+        self.assertEqual(payment.amount_auth, 34250.0)
+        self.assertEqual(payment.p_item, u'CERT1')
+        self.assertEqual(error, None)
+
+        error, payment = utils.setPaymentDetails('gown',self.student)
+        self.assertEqual(payment.p_level, 100)
+        self.assertEqual(payment.p_session, 2004)
+        self.assertEqual(payment.amount_auth, 150.0)
+        self.assertEqual(payment.p_item, u'')
+        self.assertEqual(error, None)
+
+        error, payment = utils.setPaymentDetails('hostel_maintenance',self.student)
+        self.assertEqual(payment.p_level, 100)
+        self.assertEqual(payment.p_session, 2004)
+        self.assertEqual(payment.amount_auth, 180.0)
+        self.assertEqual(payment.p_item, u'')
+        self.assertEqual(error, None)
+
+        error, payment = utils.setPaymentDetails('bed_allocation',self.student)
+        self.assertEqual(payment.p_level, 100)
+        self.assertEqual(payment.p_session, 2004)
+        self.assertEqual(payment.amount_auth, 150.0)
+        self.assertEqual(payment.p_item, u'')
+        self.assertEqual(error, None)
+
+        error, payment = utils.setPaymentDetails('transfer',self.student)
+        self.assertEqual(payment.p_level, 100)
+        self.assertEqual(payment.p_session, 2004)
+        self.assertEqual(payment.amount_auth, 90.0)
+        self.assertEqual(payment.p_item, u'')
+        self.assertEqual(error, None)
         return
Index: main/waeup.uniben/trunk/src/waeup/uniben/students/utils.py
===================================================================
--- main/waeup.uniben/trunk/src/waeup/uniben/students/utils.py	(revision 8582)
+++ main/waeup.uniben/trunk/src/waeup/uniben/students/utils.py	(revision 8598)
@@ -17,4 +17,6 @@
 ##
 import grok
+from time import time
+from zope.component import createObject
 from waeup.kofa.interfaces import CLEARED, RETURNING, PAID
 from waeup.kofa.students.utils import StudentsUtils
@@ -23,15 +25,4 @@
 from waeup.uniben.interfaces import MessageFactory as _
 
-def get_school_fee(student):
-    state = student.state
-    fee = None
-    if state == CLEARED:
-        fee = getattr(student['studycourse'].certificate,'school_fee_1')
-    elif state == RETURNING:
-        fee = getattr(student['studycourse'].certificate,'school_fee_2')
-    if fee is not None:
-        return fee
-    return 0.0
-
 class CustomStudentsUtils(StudentsUtils):
     """A collection of customized methods.
@@ -39,4 +30,6 @@
     """
     grok.implements(IStudentsUtils)
+
+    paymentfactory = u'waeup.CustomStudentOnlinePayment'
 
     def getReturningData(self, student):
@@ -59,50 +52,75 @@
         return new_session, new_level
 
-    def getPaymentDetails(self, category, student):
+    def setPaymentDetails(self, category, student):
+        """Create Payment object and set the payment data of a student for
+        the payment category specified.
+
+        """
         details = {}
-        details['p_item'] = u''
-        details['amount'] = 0.0
-        details['error'] = u''
-        details['p_session'] = student['studycourse'].current_session
-        session = str(details['p_session'])
-        details['p_level'] = student['studycourse'].current_level
+        p_item = u''
+        amount = 0.0
+        error = u''
+        p_session = student['studycourse'].current_session
+        p_level = student['studycourse'].current_level
+        session = str(p_session)
         try:
             academic_session = grok.getSite()['configuration'][session]
         except KeyError:
-            details['error'] = _(u'Session configuration object is not available.')
-            return details
+            return _(u'Session configuration object is not available.'), None
         if category == 'transfer':
-            details['amount'] = academic_session.transfer_fee
+            amount = academic_session.transfer_fee
         elif category == 'gown':
-            details['amount'] = academic_session.gown_fee
+            amount = academic_session.gown_fee
         elif category == 'bed_allocation':
-            details['amount'] = academic_session.booking_fee
+            amount = academic_session.booking_fee
         elif category == 'hostel_maintenance':
-            details['amount'] = academic_session.maint_fee
+            amount = academic_session.maint_fee
         elif category == 'clearance':
-            details['p_item'] = student['studycourse'].certificate.code
-            if details['p_item'] in ('BEDCET', 'BIOEDCET', 'CHMEDCET', 'ISEDCET',
+            try:
+                p_item = student['studycourse'].certificate.code
+            except (AttributeError, TypeError):
+                return _('Study course data are incomplete.'), None
+            if p_item in ('BEDCET', 'BIOEDCET', 'CHMEDCET', 'ISEDCET',
                 'MTHEDCET', 'PHYEDCET', 'ITECET', 'AGREDCET', 'HEEDCET'):
-                details['amount'] = 17250.0
+                amount = 17250.0
             else:
-                details['amount'] = 34250.0
+                amount = 34250.0
         elif category == 'schoolfee':
-            details['amount'] = get_school_fee(student)
-            code = student['studycourse'].certificate.code
-            details['p_item'] = code
-            if student.state == RETURNING:
+            try:
+                certificate = student['studycourse'].certificate
+                p_item = certificate.code
+            except (AttributeError, TypeError):
+                return _('Study course data are incomplete.'), None
+            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.
-                details['p_session'], details['p_level'] = self.getReturningData(student)
-            elif student.current_mode.startswith('pg') and student.state == PAID:
+                p_session, p_level = self.getReturningData(student)
+                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.
-                details['p_session'] += 1
-                details['amount'] = getattr(
-                    student['studycourse'].certificate,'school_fee_2')
-        if details['amount'] in (0.0, None):
-            details['error'] = _(u'Amount could not be determined.')
-        return details
+                p_session += 1
+                amount = getattr(certificate, 'school_fee_2', 0.0)
+        if amount in (0.0, None):
+            return _(u'Amount could not be determined.'), None
+        for key in student['payments'].keys():
+            ticket = student['payments'][key]
+            if ticket.p_state == 'paid' and\
+               ticket.p_category == category and \
+               ticket.p_item == p_item and \
+               ticket.p_session == p_session:
+                  return _('This type of payment has already been made.'), None
+        payment = createObject(self.paymentfactory)
+        timestamp = "%d" % int(time()*1000)
+        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.amount_auth = amount
+        return None, payment
 
     VERDICTS_DICT = {
