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

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

Add requery view and button.

  • Property svn:keywords set to Id
File size: 5.4 KB
RevLine 
[14735]1## $Id: helpers.py 14753 2017-08-03 04:00:00Z 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            }
52    h.request("POST", url, body=json.dumps(data), headers=headers)
53    resp = h.getresponse()
[14737]54    if resp.status!=200:
[14741]55        return {'error': 'Connection error (%s, %s)' % (resp.status, resp.reason)}
[14735]56    jsonout = resp.read()
[14736]57    try:
58        parsed_json = json.loads(jsonout[6:-1])
59    except ValueError:
[14737]60        return {'error': 'No JSON response'}
[14735]61    return parsed_json
62
63def get_payment_status_via_rrr(merchantId, api_key, RRR, host, https):
[14738]64    RRR = RRR.rstrip()
[14735]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()
[14737]77    if resp.status!=200:
[14738]78        return {'error': 'Connection error (%s, %s)' % (resp.status, resp.reason)}
[14735]79    jsonout = resp.read()
[14736]80    try:
81        parsed_json = json.loads(jsonout)
82    except ValueError:
[14737]83        return {'error': 'No JSON response'}
[14735]84    return parsed_json
85
[14737]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'
[14743]111    if payment.r_code not in ('00', '01'):
[14737]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
[14735]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.