source: main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/interswitch/helpers.py @ 13386

Last change on this file since 13386 was 11914, checked in by Henrik Bettermann, 10 years ago

Be prepared for https webservice requests.

  • Property svn:keywords set to Id
File size: 4.7 KB
Line 
1## $Id: helpers.py 11914 2014-10-30 16:43:11Z henrik $
2##
3## Copyright (C) 2012 Uli Fouquet & Henrik Bettermann
4## This program is free software; you can redistribute it and/or modify
5## it under the terms of the GNU General Public License as published by
6## the Free Software Foundation; either version 2 of the License, or
7## (at your option) any later version.
8##
9## This program is distributed in the hope that it will be useful,
10## but WITHOUT ANY WARRANTY; without even the implied warranty of
11## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12## GNU General Public License for more details.
13##
14## You should have received a copy of the GNU General Public License
15## along with this program; if not, write to the Free Software
16## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17##
18"""General helper functions for the interswitch module in custom packages.
19"""
20from datetime import datetime
21import httplib
22import grok
23from xml.dom.minidom import parseString
24from zope.event import notify
25from kofacustom.nigeria.interfaces import MessageFactory as _
26
27def SOAP_post(soap_action, xml, host, url, https):
28    """Handles making the SOAP request.
29
30    Further reading:
31    http://testwebpay.interswitchng.com/test_paydirect/services/TransactionQueryWs.asmx?op=getTransactionData
32    """
33    if https:
34        h = httplib.HTTPSConnection(host)
35    else:
36        h = httplib.HTTPConnection(host)
37    headers={
38        'Host':host,
39        'Content-Type':'text/xml; charset=utf-8',
40        'Content-Length':len(xml),
41        'SOAPAction':'"%s"' % soap_action,
42    }
43    h.request('POST', url, body=xml,headers=headers)
44    response = h.getresponse()
45    return response
46
47def get_SOAP_response(product_id, transref, host, url, https):
48    xml="""\
49<?xml version="1.0" encoding="utf-8"?>
50<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/">
51  <soap:Body>
52    <getTransactionData xmlns="http://tempuri.org/">
53      <product_id>%s</product_id>
54      <trans_ref>%s</trans_ref>
55    </getTransactionData>
56  </soap:Body>
57</soap:Envelope>""" % (product_id, transref)
58    response=SOAP_post("http://tempuri.org/getTransactionData",xml, host, url, https)
59    if response.status!=200:
60        return 'Connection error (%s, %s)' % (response.status, response.reason)
61    result_xml = response.read()
62    doc=parseString(result_xml)
63    response=doc.getElementsByTagName('getTransactionDataResult')[0].firstChild.data
64    return response
65
66def query_interswitch(payment, product_id, host, url, https=False):
67    sr = get_SOAP_response(product_id, payment.p_id, host, url, https)
68    if sr.startswith('Connection error'):
69        msg = _('Connection error')
70        log = sr
71        return False, msg, log
72    wlist = sr.split(':')
73    if len(wlist) != 7:
74        msg = _('Invalid callback: ${a}', mapping = {'a': sr})
75        log = 'invalid callback for payment %s: %s' % (payment.p_id, sr)
76        return False, msg, log
77    payment.r_code = wlist[0]
78    payment.r_desc = wlist[1]
79    payment.r_amount_approved = float(wlist[2]) / 100
80    payment.r_card_num = wlist[3]
81    payment.r_pay_reference = wlist[5]
82    payment.r_company = u'interswitch'
83    if payment.r_code != '00':
84        msg = _('Unsuccessful callback: ${a}', mapping = {'a': sr})
85        log = 'unsuccessful callback for %s payment %s: %s' % (
86            payment.p_category, payment.p_id, sr)
87        payment.p_state = 'failed'
88        notify(grok.ObjectModifiedEvent(payment))
89        return False, msg, log
90    if round(payment.r_amount_approved, 2) != round(payment.amount_auth, 2):
91        msg = _('Callback amount does not match.')
92        log = 'wrong callback for %s payment %s: %s' % (
93            payment.p_category, payment.p_id, sr)
94        payment.p_state = 'failed'
95        notify(grok.ObjectModifiedEvent(payment))
96        return False, msg, log
97    if wlist[4] != payment.p_id:
98        msg = _('Callback transaction id does not match.')
99        log = 'wrong callback for %s payment %s: %s' % (
100            payment.p_category, payment.p_id, sr)
101        payment.p_state = 'failed'
102        notify(grok.ObjectModifiedEvent(payment))
103        return False, msg, log
104    payment.p_state = 'paid'
105    payment.payment_date = datetime.utcnow()
106    msg = _('Successful callback received')
107    log = 'valid callback for %s payment %s: %s' % (
108        payment.p_category, payment.p_id, sr)
109    notify(grok.ObjectModifiedEvent(payment))
110    return True, msg, log
111
112def write_payments_log(id, payment):
113    payment.logger.info(
114        '%s,%s,%s,%s,%s,%s,%s,%s,,,' % (
115        id, payment.p_id, payment.p_category,
116        payment.amount_auth, payment.r_code,
117        payment.provider_amt, payment.gateway_amt,
118        payment.thirdparty_amt))
Note: See TracBrowser for help on using the repository browser.