Index: main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/interswitch/__init__.py
===================================================================
--- main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/interswitch/__init__.py	(revision 9746)
+++ main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/interswitch/__init__.py	(revision 9746)
@@ -0,0 +1,1 @@
+# Make this a package.
Index: main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/interswitch/helpers.py
===================================================================
--- main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/interswitch/helpers.py	(revision 9746)
+++ main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/interswitch/helpers.py	(revision 9746)
@@ -0,0 +1,107 @@
+## $Id$
+##
+## Copyright (C) 2012 Uli Fouquet & Henrik Bettermann
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##
+"""General helper functions for the interswitch module in custom packages.
+"""
+
+import httplib
+import grok
+from xml.dom.minidom import parseString
+from zope.event import notify
+from kofacustom.nigeria.interfaces import MessageFactory as _
+
+def SOAP_post(soap_action, xml, host, url):
+    """Handles making the SOAP request.
+
+    Further reading:
+    http://testwebpay.interswitchng.com/test_paydirect/services/TransactionQueryWs.asmx?op=getTransactionData
+    """
+    h = httplib.HTTPConnection(host)
+    headers={
+        'Host':host,
+        'Content-Type':'text/xml; charset=utf-8',
+        'Content-Length':len(xml),
+        'SOAPAction':'"%s"' % soap_action,
+    }
+    h.request('POST', url, body=xml,headers=headers)
+    response = h.getresponse()
+    return response
+
+def get_SOAP_response(product_id, transref, host, url):
+    xml="""\
+<?xml version="1.0" encoding="utf-8"?>
+<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
+  <soap:Body>
+    <getTransactionData xmlns="http://tempuri.org/">
+      <product_id>%s</product_id>
+      <trans_ref>%s</trans_ref>
+    </getTransactionData>
+  </soap:Body>
+</soap:Envelope>""" % (product_id, transref)
+    response=SOAP_post("http://tempuri.org/getTransactionData",xml, host, url)
+    if response.status!=200:
+        return 'Connection error (%s, %s)' % (response.status, response.reason)
+    result_xml = response.read()
+    doc=parseString(result_xml)
+    response=doc.getElementsByTagName('getTransactionDataResult')[0].firstChild.data
+    return response
+
+def query_interswitch(payment, product_id, host, url):
+    sr = get_SOAP_response(product_id, payment.p_id, host, url)
+    if sr.startswith('Connection error'):
+        msg = _('Connection error')
+        log = sr
+        return False, msg, log
+    wlist = sr.split(':')
+    if len(wlist) != 7:
+        msg = _('Invalid callback: ${a}', mapping = {'a': sr})
+        log = 'invalid callback for payment %s: %s' % (payment.p_id, sr)
+        return False, msg, log
+    payment.r_code = wlist[0]
+    payment.r_desc = wlist[1]
+    payment.r_amount_approved = float(wlist[2]) / 100
+    payment.r_card_num = wlist[3]
+    payment.r_pay_reference = wlist[5]
+    payment.r_company = u'interswitch'
+    if payment.r_code != '00':
+        msg = _('Unsuccessful callback: ${a}', mapping = {'a': sr})
+        log = 'unsuccessful callback for %s payment %s: %s' % (
+            payment.p_category, payment.p_id, sr)
+        payment.p_state = 'failed'
+        notify(grok.ObjectModifiedEvent(payment))
+        return False, msg, log
+    if payment.r_amount_approved != payment.amount_auth:
+        msg = _('Callback amount does not match.')
+        log = 'wrong callback for %s payment %s: %s' % (
+            payment.p_category, payment.p_id, sr)
+        payment.p_state = 'failed'
+        notify(grok.ObjectModifiedEvent(payment))
+        return False, msg, log
+    if wlist[4] != payment.p_id:
+        msg = _('Callback transaction id does not match.')
+        log = 'wrong callback for %s payment %s: %s' % (
+            payment.p_category, payment.p_id, sr)
+        payment.p_state = 'failed'
+        notify(grok.ObjectModifiedEvent(payment))
+        return False, msg, log
+    payment.p_state = 'paid'
+    payment.payment_date = datetime.utcnow()
+    msg = _('Successful callback received')
+    log = 'valid callback for %s payment %s: %s' % (
+        payment.p_category, payment.p_id, sr)
+    notify(grok.ObjectModifiedEvent(payment))
+    return True, msg, log
