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

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

Fix test and typo in helpers.py.

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