source: main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/remita/webservices.py @ 14788

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

The callback is a JSON response.

Do not trigger any action on students or applicants if payment was already paid.

  • Property svn:keywords set to Id
File size: 4.8 KB
Line 
1## $Id: webservices.py 14788 2017-08-09 14:03:33Z 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
19import grok
20import json
21from zope.component import getUtility
22from zope.catalog.interfaces import ICatalog
23from waeup.kofa.interfaces import IUniversity
24from kofacustom.nigeria.remita.helpers import query_remita, write_payments_log
25
26class PaymentNotificationListenerWebservice(grok.View):
27    """A webservice to receive payment notifications from
28    accepted IP addresses without authentication which trigger
29    a query of a Remita transaction status.
30    """
31    grok.context(IUniversity)
32    grok.name('paymentnotificationlistener')
33    grok.require('waeup.Public')
34
35    ACCEPTED_IP = None
36
37    # Here we use Remita test portal data
38    merchantId = '2547916'
39    host = 'www.remitademo.net'
40    https = False
41    api_key = '1946'
42
43    def update(self, P_ID=None):
44
45        # Remita sends a JSON POST request with an array with
46        # multiple JSON objects:
47        # [
48        #    {
49        #       "rrr": "A39359490",
50        #       "channnel": "BRANCH",
51        #       "amount": "6500.00",
52        #       "transactiondate": "19/01/2015",
53        #       "debitdate": "19/01/2015",
54        #       "bank": "033",
55        #       "branch": "033152763",
56        #       "serviceTypeId": "4430731",
57        #       "dateSent": "20/01/2015",
58        #       "dateRequested": "19/01/2015",
59        #       "orderRef": "4086852511",
60        #       "payerName": "mujib ishola",
61        #       "payerEmail": "ishola@specs.com",
62        #       "payerPhoneNumber": "08141376868",
63        #       "uniqueIdentifier": 10001
64        #    },
65        #    {...}
66        # ]
67
68        real_ip = self.request.get('HTTP_X_FORWARDED_FOR', None)
69        if real_ip:
70            self.context.logger.info(
71                'PaymentNotificationListenerWebservice called from %s' % real_ip)
72        if real_ip and self.ACCEPTED_IP:
73            if real_ip not in self.ACCEPTED_IP:
74                self.output = '-1'
75                return
76        resp = self.request.bodyStream.read()
77        self.context.logger.info(
78            'PaymentNotificationListenerWebservice response: %s' % resp)
79        try:
80            parsed_json = json.loads(resp)
81        except ValueError:
82            self.output = '-2'
83            return
84        successful = 0
85        failed = 0
86        for payment in parsed_json:
87            orderRef =  payment.get('orderRef')
88            rrr = payment.get('rrr')
89            if not orderRef or not rrr:
90                failed += 1
91                continue
92            cat = getUtility(ICatalog, name='payments_catalog')
93            results = list(cat.searchResults(p_id=(orderRef, orderRef)))
94            if len(results) != 1:
95                failed += 1
96                continue
97            ticket = results[0]
98            if ticket.p_state == 'waived':
99                failed += 1
100                continue
101            waspaid = (ticket.p_state == 'paid')
102            success, msg, log = query_remita(
103                ticket, self.merchantId, self.api_key,
104                rrr, self.host, self.https, False)
105            if not success:
106                failed += 1
107                continue
108            if hasattr(ticket, 'doAfterStudentPayment'):
109                ticket.student.writeLogMessage(self, log)
110                successful += 1
111                if not waspaid:
112                    write_payments_log(ticket.student.student_id, ticket)
113                    flashtype, msg, log = ticket.doAfterStudentPayment()
114                    if log is not None:
115                        ticket.student.writeLogMessage(self, log)
116            else:
117                applicant = ticket.__parent__
118                applicant.writeLogMessage(self, log)
119                successful += 1
120                if not waspaid:
121                    write_payments_log(applicant.applicant_id, ticket)
122                    flashtype, msg, log = ticket.doAfterApplicantPayment()
123                    if log is not None:
124                        applicant.writeLogMessage(self, log)
125        self.output = '%s (%s)' % (successful, failed + successful)
126        return
127
128    def render(self):
129        return self.output
Note: See TracBrowser for help on using the repository browser.