Index: /main/kofacustom.lpng/trunk/src/kofacustom/lpng/interswitch/browser.py
===================================================================
--- /main/kofacustom.lpng/trunk/src/kofacustom/lpng/interswitch/browser.py	(revision 17222)
+++ /main/kofacustom.lpng/trunk/src/kofacustom/lpng/interswitch/browser.py	(revision 17223)
@@ -25,5 +25,11 @@
     InterswitchPaymentVerifyWebservicePageApplicant,
     InterswitchPaymentVerifyWebservicePageStudent,
-    InterswitchPageStudent, InterswitchPageApplicant,
+    InterswitchPageStudent,
+    InterswitchPageApplicant,)
+from kofacustom.nigeria.interswitch.webcheckoutbrowser import (
+    WebCheckoutPageStudent,
+    WebCheckoutPageApplicant,
+    WebCheckoutConfirmTransactionStudent,
+    WebCheckoutConfirmTransactionApplicant,
     )
 from kofacustom.lpng.students.interfaces import ICustomStudentOnlinePayment
@@ -229,2 +235,44 @@
     gateway_url = URL
     mac = MAC
+
+
+# WebCheckout customizations
+
+class CustomWebCheckoutPageStudent(WebCheckoutPageStudent):
+    """ View which sends a POST request to the Interswitch
+    WebCheckout payment gateway.
+    """
+    action = 'https://newwebpay.interswitchng.com/collections/w/pay'
+    currency = '566'
+    pay_item_id = 'Default_Payable_MX76823'
+    merchant_code = 'MX76823'
+    gateway_amt = GATEWAY_AMT
+
+class CustomWebCheckoutPageApplicant(WebCheckoutPageApplicant):
+    """ View which sends a POST request to the Interswitch
+    WebCheckout payment gateway.
+    """
+
+    action = 'https://newwebpay.interswitchng.com/collections/w/pay'
+    currency = '566'
+    pay_item_id = 'Default_Payable_MX76823'
+    merchant_code = 'MX76823'
+    gateway_amt = GATEWAY_AMT
+
+class CustomWebCheckoutConfirmTransactionStudent(WebCheckoutConfirmTransactionStudent):
+    """ Request webservice view for the WebCheckout gateway
+    """
+    merchant_code = 'MX76823'
+    gateway_host = 'webpay.interswitchng.com'
+    gateway_url = '/collections/api/v1/gettransaction.json'
+    https = True
+
+class CustomWebCheckoutConfirmTransactionApplicant(WebCheckoutConfirmTransactionApplicant):
+    """ Request webservice view for the WebCheckout gateway
+    """
+    merchant_code = 'MX76823'
+    gateway_host = 'webpay.interswitchng.com'
+    gateway_url = '/collections/api/v1/gettransaction.json'
+    https = True
+
+
Index: /main/kofacustom.lpng/trunk/src/kofacustom/lpng/interswitch/tests.py
===================================================================
--- /main/kofacustom.lpng/trunk/src/kofacustom/lpng/interswitch/tests.py	(revision 17222)
+++ /main/kofacustom.lpng/trunk/src/kofacustom/lpng/interswitch/tests.py	(revision 17223)
@@ -22,6 +22,8 @@
 from hurry.workflow.interfaces import IWorkflowState
 from waeup.kofa.students.tests.test_browser import StudentsFullSetup
+from waeup.kofa.students.payments import StudentOnlinePayment
 from waeup.kofa.applicants.tests.test_browser import ApplicantsFullSetup
 from waeup.kofa.configuration import SessionConfiguration
+from kofacustom.nigeria.interswitch.helpers import confirm_transaction
 from kofacustom.lpng.testing import FunctionalLayer
 
@@ -35,162 +37,9 @@
         myself = __file__
         if myself.endswith('.pyc'):
-            myself = myself[:-2]
+            myself = myself[:-1]
         print "WARNING: external tests are skipped!"
         print "WARNING: edit %s to enable them." % myself
         return
     return func
-
-
-class InterswitchTestsStudents(StudentsFullSetup):
-    """Tests for the Interswitch payment gateway.
-    """
-
-    layer = FunctionalLayer
-
-    def setUp(self):
-        super(InterswitchTestsStudents, self).setUp()
-        self.app['configuration']['2004'].interswitch_enabled = True
-
-    def test_interswitch_form(self):
-        # Manager can access InterswitchForm
-        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
-        self.browser.open(self.payments_path)
-        IWorkflowState(self.student).setState('cleared')
-        self.student.nationality = u'NG'
-        self.browser.open(self.payments_path + '/addop')
-        self.browser.getControl(name="form.p_category").value = ['schoolfee']
-        self.browser.getControl("Create ticket").click()
-        self.assertMatches('...ticket created...',
-                           self.browser.contents)
-        self.browser.open(self.payments_path)
-        ctrl = self.browser.getControl(name='val_id')
-        self.value = ctrl.options[0]
-        self.browser.getLink(self.value).click()
-        self.assertMatches('...Amount Authorized...',
-                           self.browser.contents)
-        self.assertTrue(
-            '<span>40000.0</span>' in self.browser.contents)
-        self.payment_url = self.browser.url
-        self.browser.getLink("Pay via Interswitch", index=0).click()
-        self.assertTrue('<input type="hidden" name="pay_item_id" value="0000" />' in
-                           self.browser.contents)
-        self.assertEqual(self.student.current_mode, 'ug_ft')
-        self.assertTrue(
-            '<input type="hidden" name="amount" value="4015000" />' in
-            self.browser.contents)
-        self.assertTrue(
-            'item_name="Annual Membership Fee" item_amt="4000000" bank_id="00" acct_num="00000000"' in
-            self.browser.contents)
-
-    def test_interswitch_form_ticket_expired(self):
-        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
-        acc_payment = createObject('waeup.StudentOnlinePayment')
-        acc_payment.p_state = 'unpaid'
-        acc_payment.p_category = 'clearance'
-        acc_payment.p_id = 'xyz'
-        acc_payment.pay_item_id = '123'
-        acc_payment.amount_auth = 1000.0
-        self.student['payments']['xyz'] = acc_payment
-        self.browser.open(self.payments_path + '/xyz')
-        self.browser.getLink("Pay via Interswitch", index=0).click()
-        self.assertMatches('...<input type="hidden" name="pay_item_id" value="0000" />...',
-                           self.browser.contents)
-        self.assertMatches('...Total Amount Authorized:...',
-                           self.browser.contents)
-        self.assertEqual(self.student.current_mode, 'ug_ft')
-        self.assertMatches(
-            '...<input type="hidden" name="amount" value="115000" />...',
-            self.browser.contents)
-        delta = timedelta(days=8)
-        acc_payment.creation_date -= delta
-        self.browser.open(self.payments_path + '/xyz')
-        self.browser.getLink("Pay via Interswitch", index=0).click()
-        self.assertMatches(
-            '...This payment ticket is too old. Please create a new ticket...',
-            self.browser.contents)
-        delta = timedelta(days=2)
-        acc_payment.creation_date += delta
-        self.browser.open(self.payments_path + '/xyz')
-        self.browser.getLink("Pay via Interswitch", index=0).click()
-        self.assertMatches('...Total Amount Authorized:...',
-                           self.browser.contents)
-
-    @external_test
-    def test_webservice(self):
-        self.browser.addHeader('Authorization', 'Basic mgr:mgrpw')
-        self.browser.open(self.payments_path)
-        IWorkflowState(self.student).setState('cleared')
-        self.student.nationality = u'NG'
-        self.browser.open(self.payments_path + '/addop')
-        self.browser.getControl(name="form.p_category").value = ['schoolfee']
-        self.browser.getControl("Create ticket").click()
-        self.assertMatches('...ticket created...',
-                           self.browser.contents)
-        ctrl = self.browser.getControl(name='val_id')
-        self.value = ctrl.options[0]
-        self.browser.getLink(self.value).click()
-        self.payment_url = self.browser.url
-        # First we have open InterswitchPageStudent to set provider_amt
-        # and gateway_amt
-        self.browser.open(self.payment_url + '/goto_interswitch')
-        # Now we can call the webservice
-        self.browser.open(self.payment_url + '/request_webservice')
-        self.assertMatches('...Unsuccessful callback...',
-                          self.browser.contents)
-        # The payment is now in state failed ...
-        self.assertMatches('...<span>Failed</span>...',
-                          self.browser.contents)
-        # ... and the catalog has been updated
-        cat = getUtility(ICatalog, name='payments_catalog')
-        results = list(
-            cat.searchResults(p_state=('failed', 'failed')))
-        self.assertEqual(len(results), 1)
-        self.assertEqual(results[0].p_state, 'failed')
-
-        # Let's replace the p_id with a valid p_id of the Uniben
-        # live system. This is definitely not an appropriate
-        # solution for testing, but we have no choice since
-        # Interswitch doesn't provide any interface
-        # for testing.
-        payment = self.student['payments'][self.value]
-        payment.p_id = 'p3547789850240'
-        self.browser.open(self.payment_url + '/request_webservice')
-        self.assertMatches('...Callback amount does not match...',
-                          self.browser.contents)
-        # The payment is now in state failed ...
-        self.assertMatches('...<span>Failed</span>...',
-                          self.browser.contents)
-        # Let's replace the amount autorized with the amount of the
-        # live system payment
-        payment.amount_auth = payment.r_amount_approved
-        self.browser.open(self.payment_url + '/request_webservice')
-        self.assertMatches('...Successful payment...',
-                          self.browser.contents)
-        # The payment is now in state paid ...
-        self.assertMatches('...<span>Paid</span>...',
-                          self.browser.contents)
-        # ... and the catalog has been updated
-        cat = getUtility(ICatalog, name='payments_catalog')
-        results = list(
-            cat.searchResults(p_state=('paid', 'paid')))
-        self.assertEqual(len(results), 1)
-        self.assertEqual(results[0].p_state, 'paid')
-        # Approval is logged in students.log ...
-        logfile = os.path.join(
-            self.app['datacenter'].storage, 'logs', 'students.log')
-        logcontent = open(logfile).read()
-        self.assertTrue(
-            'zope.mgr - '
-            'kofacustom.lpng.interswitch.browser.CustomInterswitchPaymentRequestWebservicePageStudent - '
-            'X1000000 - successful schoolfee payment: p3547789850240\n'
-            in logcontent)
-        # ... and in payments.log
-        logfile = os.path.join(
-            self.app['datacenter'].storage, 'logs', 'payments.log')
-        logcontent = open(logfile).read()
-        self.assertTrue(
-            '"zope.mgr",X1000000,p3547789850240,schoolfee,'
-            '12000.0,00,0.0,150.0,0.0,,,\n'
-            in logcontent)
 
 
@@ -218,22 +67,23 @@
         self.browser.getControl(name="form.email").value = 'xx@yy.zz'
         self.applicantscontainer.application_fee = 1000.0
-        self.browser.getControl(name="form.nationality").value = ['NG']
         self.browser.getControl(name="transition").value = ['start']
         self.browser.getControl("Save").click()
-        self.browser.getControl("Pay membership").click()
+
+
+    def test_webcheckout_form(self):
+        self.browser.getControl("Make").click()
+        self.browser.getControl(name="form.balance_amount").value = '500'
+        self.browser.getControl(name="form.p_category").value = ['donation']
+        self.browser.getControl("Create").click()
+
         self.assertMatches('...ticket created...',
                            self.browser.contents)
-        #ctrl = self.browser.getControl(name='val_id')
-        #value = ctrl.options[0]
-        #self.browser.getLink(value).click()
+
         self.assertMatches('...Amount Authorized...',
                            self.browser.contents)
         self.assertMatches(
-            '...<span>1000.0</span>...',
+            '...<span>500.0</span>...',
             self.browser.contents)
         self.payment_url = self.browser.url
-
-
-    def disabled_test_interswitch_form(self):
         # Manager can access InterswitchForm
         self.browser.getLink("Pay via Interswitch", index=0).click()
@@ -251,11 +101,43 @@
             self.browser.contents)
 
+
+# WebCheckout tests
+
+    # https://webpay.interswitchng.com/collections/api/v1/gettransaction.json?merchantcode=MX76823&transactionreference=p6709347986663&amount=100
+
     @external_test
-    def test_webservice(self):
+    def test_confirm_transaction(self):
+        host = 'webpay.interswitchng.com'
+        url = '/collections/api/v1/gettransaction.json'
+        https = True
+        merchant_code = 'MX76823'
+        payment = StudentOnlinePayment()
+        payment.p_id ='p4465649308559'
+        success, msg, log = confirm_transaction(
+            payment, merchant_code, host, url, https)
+        self.assertFalse(success)
+        self.assertTrue('Unsuccessful callback:' in msg)
+        self.assertTrue('Transaction not Found' in log)
 
-        self.browser.open(self.payment_url + '/request_webservice')
-        self.assertMatches('...Unsuccessful callback...',
-                          self.browser.contents)
-        # The payment is now in state failed
-        self.assertMatches('...<span>Failed</span>...',
-                          self.browser.contents)
+        payment.p_id ='p6709347986663'
+        payment.amount_auth = 1.0
+        success, msg, log = confirm_transaction(
+            payment, merchant_code, host, url, https)
+        self.assertTrue('Amount Inconsistency' in log)
+        payment.amount_auth = 100.0
+        success, msg, log = confirm_transaction(
+            payment, merchant_code, host, url, https)
+        self.assertEqual('Successful callback received', msg)
+        self.assertTrue(success)
+        self.assertTrue(
+            "{u'SplitAccounts': [], "
+            "u'RemittanceAmount': 0, "
+            "u'MerchantReference': u'p6709347986663', "
+            "u'PaymentReference': u'FBN|WEB|MX76823|13-12-2022|935097929|608001', "
+            "u'TransactionDate': u'2022-12-13T01:34:21', "
+            "u'RetrievalReferenceNumber': u'814212374638', "
+            "u'ResponseDescription': u'Approved by Financial Institution', "
+            "u'Amount': 10000, "
+            "u'CardNumber': u'', "
+            "u'ResponseCode': u'00', "
+            "u'BankCode': u'011'}" in log)
