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

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

Add first Remita views.

  • Property svn:keywords set to Id
File size: 5.4 KB
Line 
1## $Id: helpers.py 14743 2017-08-02 08:28:31Z 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"""
20import grok
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):
32    hashargs =  merchantId + serviceTypeId + orderId + amount + responseurl + api_key
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            }
52    h.request("POST", url, body=json.dumps(data), headers=headers)
53    resp = h.getresponse()
54    if resp.status!=200:
55        return {'error': 'Connection error (%s, %s)' % (resp.status, resp.reason)}
56    jsonout = resp.read()
57    try:
58        parsed_json = json.loads(jsonout[6:-1])
59    except ValueError:
60        return {'error': 'No JSON response'}
61    return parsed_json
62
63def get_payment_status_via_rrr(merchantId, api_key, RRR, host, https):
64    RRR = RRR.rstrip()
65    hashargs =  RRR + api_key + merchantId
66    hashvalue = hashlib.sha512(hashargs).hexdigest()
67    headers={
68        'Content-Type':'application/json; charset=utf-8',
69    }
70    url = '/remita/ecomm/%s/%s/%s/status.reg' % (merchantId, RRR, hashvalue)
71    if https:
72        h = httplib.HTTPSConnection(host)
73    else:
74        h = httplib.HTTPConnection(host)
75    h.request("GET", url, headers=headers)
76    resp = h.getresponse()
77    if resp.status!=200:
78        return {'error': 'Connection error (%s, %s)' % (resp.status, resp.reason)}
79    jsonout = resp.read()
80    try:
81        parsed_json = json.loads(jsonout)
82    except ValueError:
83        return {'error': 'No JSON response'}
84    return parsed_json
85
86def query_remita(payment, merchantId, api_key, RRR, host, https, verify):
87
88    jr = get_payment_status_via_rrr(merchantId, api_key, RRR, host, https)
89    error = jr.get('error')
90    if error:
91        msg = log = error
92        return False, msg, log
93
94    # A typical JSON response
95    # {
96    # u'orderId': u'3456346346',
97    # u'status': u'021',
98    # u'amount': 1000.0,
99    # u'transactiontime': u'2017-07-31 11:17:24 AM',
100    # u'message': u'Transaction Pending',
101    # u'lineitems': [{u'status': u'021', u'lineItemsId': u'itemid1'},
102    #                {u'status': u'021', u'lineItemsId': u'itemid2'}
103    #               ],
104    # u'RRR': u'280007640804'}
105
106    payment.r_code = jr['status']
107    payment.r_desc = jr['message']
108    payment.r_amount_approved = jr['amount']
109    payment.r_pay_reference = jr['RRR']
110    payment.r_company = u'remita'
111    if payment.r_code not in ('00', '01'):
112        msg = _('Unsuccessful callback: ${a}', mapping = {'a': payment.r_desc})
113        log = 'unsuccessful callback for %s payment %s: %s' % (
114            payment.p_category, payment.p_id, payment.r_desc)
115        payment.p_state = 'failed'
116        notify(grok.ObjectModifiedEvent(payment))
117        return False, msg, log
118    if round(payment.r_amount_approved, 0) != round(payment.amount_auth, 0):
119        msg = _('Callback amount does not match.')
120        log = 'wrong callback for %s payment %s: %s' % (
121            payment.p_category, payment.p_id, str(jr))
122        payment.p_state = 'failed'
123        notify(grok.ObjectModifiedEvent(payment))
124        return False, msg, log
125    if jr['orderId'] != payment.p_id:
126        msg = _('Callback order id does not match.')
127        log = 'wrong callback for %s payment %s: %s' % (
128            payment.p_category, payment.p_id, str(jr))
129        payment.p_state = 'failed'
130        notify(grok.ObjectModifiedEvent(payment))
131        return False, msg, log
132    payment.p_state = 'paid'
133    if not verify:
134        payment.payment_date = datetime.utcnow()
135    msg = _('Successful callback received')
136    log = 'valid callback for %s payment %s: %s' % (
137        payment.p_category, payment.p_id, str(jr))
138    notify(grok.ObjectModifiedEvent(payment))
139    return True, msg, log
140
141def write_payments_log(id, payment):
142    payment.logger.info(
143        '%s,%s,%s,%s,%s,%s,%s,%s,,,' % (
144        id, payment.p_id, payment.p_category,
145        payment.amount_auth, payment.r_code,
146        payment.provider_amt, payment.gateway_amt,
147        payment.thirdparty_amt))
Note: See TracBrowser for help on using the repository browser.