source: main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/remita/helpers.py @ 15468

Last change on this file since 15468 was 14916, checked in by Henrik Bettermann, 7 years ago

Catch traceback.

  • Property svn:keywords set to Id
File size: 5.7 KB
RevLine 
[14735]1## $Id: helpers.py 14916 2017-11-30 09:10:38Z henrik $
2##
3## Copyright (C) 2017 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 remita module in custom packages.
19"""
[14737]20import grok
[14735]21from datetime import datetime
22import httplib
23import hashlib
24import json
25
26from zope.event import notify
27from kofacustom.nigeria.interfaces import MessageFactory as _
28
29def get_JSON_POST_response(
30        merchantId, serviceTypeId, api_key, orderId,
31        amount, responseurl, host, url, https, fullname, email, lineitems):
[14753]32    hashargs =  merchantId + serviceTypeId + orderId + str(amount) + responseurl + api_key
[14735]33    hashvalue = hashlib.sha512(hashargs).hexdigest()
34    headers={
35        'Content-Type':'application/json; charset=utf-8',
36    }
37    if https:
38        h = httplib.HTTPSConnection(host)
39    else:
40        h = httplib.HTTPConnection(host)
41    data = {
42            "merchantId":merchantId,
43            "serviceTypeId":serviceTypeId,
44            "totalAmount":amount,
45            "hash":hashvalue,
46            "payerName":fullname,
47            "payerEmail":email,
48            "orderId":orderId,
49            "responseurl":responseurl,
50            "lineItems":lineitems
51            }
[14769]52    try:
53        h.request("POST", url, body=json.dumps(data), headers=headers)
[14916]54        resp = h.getresponse()
[14769]55    except:
56        return {'error': 'Socket Error: Connection to Remita gateway refused.'}
[14737]57    if resp.status!=200:
[14916]58        return {'error': 'Connection Error (%s, %s)' % (resp.status, resp.reason)}
[14735]59    jsonout = resp.read()
[14736]60    try:
61        parsed_json = json.loads(jsonout[6:-1])
62    except ValueError:
[14737]63        return {'error': 'No JSON response'}
[14735]64    return parsed_json
65
66def get_payment_status_via_rrr(merchantId, api_key, RRR, host, https):
[14738]67    RRR = RRR.rstrip()
[14735]68    hashargs =  RRR + api_key + merchantId
69    hashvalue = hashlib.sha512(hashargs).hexdigest()
70    headers={
71        'Content-Type':'application/json; charset=utf-8',
72    }
73    url = '/remita/ecomm/%s/%s/%s/status.reg' % (merchantId, RRR, hashvalue)
74    if https:
75        h = httplib.HTTPSConnection(host)
76    else:
77        h = httplib.HTTPConnection(host)
[14769]78    try:
79        h.request("GET", url, headers=headers)
80    except:
81        return {'error': 'Socket Error: Connection to Remita gateway refused.'}
[14735]82    resp = h.getresponse()
[14737]83    if resp.status!=200:
[14738]84        return {'error': 'Connection error (%s, %s)' % (resp.status, resp.reason)}
[14735]85    jsonout = resp.read()
[14736]86    try:
87        parsed_json = json.loads(jsonout)
88    except ValueError:
[14737]89        return {'error': 'No JSON response'}
[14735]90    return parsed_json
91
[14737]92def query_remita(payment, merchantId, api_key, RRR, host, https, verify):
93
94    jr = get_payment_status_via_rrr(merchantId, api_key, RRR, host, https)
95    error = jr.get('error')
96    if error:
97        msg = log = error
98        return False, msg, log
99
100    # A typical JSON response
101    # {
102    # u'orderId': u'3456346346',
103    # u'status': u'021',
104    # u'amount': 1000.0,
105    # u'transactiontime': u'2017-07-31 11:17:24 AM',
106    # u'message': u'Transaction Pending',
107    # u'lineitems': [{u'status': u'021', u'lineItemsId': u'itemid1'},
108    #                {u'status': u'021', u'lineItemsId': u'itemid2'}
109    #               ],
110    # u'RRR': u'280007640804'}
111
112    payment.r_code = jr['status']
113    payment.r_desc = jr['message']
114    payment.r_amount_approved = jr['amount']
115    payment.r_pay_reference = jr['RRR']
116    payment.r_company = u'remita'
[14743]117    if payment.r_code not in ('00', '01'):
[14788]118        msg = _('Unsuccessful response: ${a}', mapping = {'a': payment.r_desc})
119        log = 'unsuccessful response for %s payment %s: %s' % (
[14737]120            payment.p_category, payment.p_id, payment.r_desc)
121        payment.p_state = 'failed'
122        notify(grok.ObjectModifiedEvent(payment))
123        return False, msg, log
[14820]124    if round(payment.r_amount_approved/10.0, 0) != round(
125        payment.amount_auth/10.0, 0):
[14788]126        msg = _('Response amount does not match.')
127        log = 'wrong response for %s payment %s: %s' % (
[14737]128            payment.p_category, payment.p_id, str(jr))
129        payment.p_state = 'failed'
130        notify(grok.ObjectModifiedEvent(payment))
131        return False, msg, log
[14806]132    orderId = jr.get('orderId', None)
133    if orderId and orderId != payment.p_id:
[14788]134        msg = _('Response order id does not match.')
135        log = 'wrong response for %s payment %s: %s' % (
[14737]136            payment.p_category, payment.p_id, str(jr))
137        payment.p_state = 'failed'
138        notify(grok.ObjectModifiedEvent(payment))
139        return False, msg, log
140    payment.p_state = 'paid'
141    if not verify:
142        payment.payment_date = datetime.utcnow()
[14788]143    msg = _('Successful response received')
144    log = 'valid response for %s payment %s: %s' % (
[14737]145        payment.p_category, payment.p_id, str(jr))
146    notify(grok.ObjectModifiedEvent(payment))
147    return True, msg, log
148
[14735]149def write_payments_log(id, payment):
150    payment.logger.info(
151        '%s,%s,%s,%s,%s,%s,%s,%s,,,' % (
152        id, payment.p_id, payment.p_category,
153        payment.amount_auth, payment.r_code,
154        payment.provider_amt, payment.gateway_amt,
155        payment.thirdparty_amt))
Note: See TracBrowser for help on using the repository browser.