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

Last change on this file since 13015 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
RevLine 
[9746]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"""
[9747]20from datetime import datetime
[9746]21import httplib
22import grok
23from xml.dom.minidom import parseString
24from zope.event import notify
25from kofacustom.nigeria.interfaces import MessageFactory as _
26
[11914]27def SOAP_post(soap_action, xml, host, url, https):
[9746]28    """Handles making the SOAP request.
29
30    Further reading:
31    http://testwebpay.interswitchng.com/test_paydirect/services/TransactionQueryWs.asmx?op=getTransactionData
32    """
[11914]33    if https:
34        h = httplib.HTTPSConnection(host)
35    else:
36        h = httplib.HTTPConnection(host)
[9746]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
[11914]47def get_SOAP_response(product_id, transref, host, url, https):
[9746]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)
[11914]58    response=SOAP_post("http://tempuri.org/getTransactionData",xml, host, url, https)
[9746]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
[11914]66def query_interswitch(payment, product_id, host, url, https=False):
67    sr = get_SOAP_response(product_id, payment.p_id, host, url, https)
[9746]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
[10273]90    if round(payment.r_amount_approved, 2) != round(payment.amount_auth, 2):
[9746]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))
[9774]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.