source: main/kofacustom.lpng/trunk/src/kofacustom/lpng/interswitch/browser.py @ 17228

Last change on this file since 17228 was 17228, checked in by Henrik Bettermann, 21 months ago

Configure split payments.

  • Property svn:keywords set to Id
File size: 12.5 KB
Line 
1## $Id: browser.py 17228 2022-12-16 13:40:09Z henrik $
2##
3## Copyright (C) 2012 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##
18import httplib
19import hashlib
20import grok
21from kofacustom.nigeria.interswitch.browser import (
22    module_activated,
23    InterswitchPaymentRequestWebservicePageApplicant,
24    InterswitchPaymentRequestWebservicePageStudent,
25    InterswitchPaymentVerifyWebservicePageApplicant,
26    InterswitchPaymentVerifyWebservicePageStudent,
27    InterswitchPageStudent,
28    InterswitchPageApplicant,)
29from kofacustom.nigeria.interswitch.webcheckoutbrowser import (
30    webcheckout_module_activated,
31    WebCheckoutPageStudent,
32    WebCheckoutPageApplicant,
33    WebCheckoutConfirmTransactionStudent,
34    WebCheckoutConfirmTransactionApplicant,
35    )
36from kofacustom.lpng.students.interfaces import ICustomStudentOnlinePayment
37from kofacustom.lpng.applicants.interfaces import ICustomApplicantOnlinePayment
38from kofacustom.lpng.interfaces import MessageFactory as _
39
40PRODUCT_ID = '' # must be provided by Interswitch
41SITE_NAME = 'lpng.waeup.org'
42PROVIDER_ACCT = '1017032875'
43PROVIDER_BANK_ID = '117'
44PROVIDER_ITEM_NAME = 'WAeAC'
45INSTITUTION_NAME = 'LPNG'
46CURRENCY = '566'
47GATEWAY_AMT = 150.0
48MAC = '' # must be provided by Interswitch
49
50#POST_ACTION = 'https://webpay.interswitchng.com/collections/w/pay'
51POST_ACTION = 'https://sandbox.interswitchng.com/webpay/pay'
52#HOST = 'webpay.interswitchng.com'
53HOST = 'sandbox.interswitchng.com'
54#URL = '/paydirect/api/v1/gettransaction.json'
55URL = '/webpay/api/v1/gettransaction.json'
56
57httplib.HTTPSConnection.debuglevel = 0
58HTTPS = True
59
60class CustomInterswitchPageStudent(InterswitchPageStudent):
61    """ View which sends a POST request to the Interswitch
62    CollegePAY payment gateway.
63    """
64    grok.context(ICustomStudentOnlinePayment)
65    action = POST_ACTION
66    site_name = SITE_NAME
67    currency = CURRENCY
68    product_id = PRODUCT_ID
69    mac = MAC
70    gateway_amt = GATEWAY_AMT
71
72    def update(self):
73        if not module_activated(
74            self.context.student.current_session, self.context):
75            self.flash(_('Forbidden'), type='danger')
76            self.redirect(self.url(self.context, '@@index'))
77            return
78        error = self.init_update()
79        if error:
80            self.flash(error, type='danger')
81            self.redirect(self.url(self.context, '@@index'))
82            return
83        # Already now it becomes an Interswitch payment. We set the net amount
84        # and add the gateway amount.
85        if not self.context.r_company:
86            self.context.net_amt = self.context.amount_auth
87            self.context.amount_auth += self.gateway_amt
88            self.context.gateway_amt = self.gateway_amt
89            self.context.r_company = u'interswitch'
90        student = self.student
91        xmldict = self.xmldict
92        # Provider data
93        xmldict['detail_ref'] = self.context.p_id
94        xmldict['provider_acct'] = PROVIDER_ACCT
95        xmldict['provider_bank_id'] = PROVIDER_BANK_ID
96        xmldict['provider_item_name'] = PROVIDER_ITEM_NAME
97        # Institution data
98        xmldict['institution_acct'] = '00000000'
99        xmldict['institution_bank_id'] = '00'
100        provider_amt = 0.0
101        self.pay_item_id = '0000' # must be provided by Interswitch
102        xmldict['provider_amt'] = 100 * provider_amt
103        xmldict['institution_item_name'] = self.context.category
104        xmldict['institution_name'] = INSTITUTION_NAME
105        xmldict['institution_amt'] = 100 * self.context.net_amt
106        if not self.context.provider_amt:
107            self.context.provider_amt = provider_amt
108            self.context.amount_auth += provider_amt
109        if provider_amt == 0:
110            xmltext = """<payment_item_detail>
111<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s" department="%(department)s" faculty="%(faculty)s">
112<item_detail item_id="1" item_name="%(institution_item_name)s" item_amt="%(institution_amt)d" bank_id="%(institution_bank_id)s" acct_num="%(institution_acct)s" />
113</item_details>
114</payment_item_detail>""" % xmldict
115        else:
116            xmltext = """<payment_item_detail>
117<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s" department="%(department)s" faculty="%(faculty)s">
118<item_detail item_id="1" item_name="%(institution_item_name)s" item_amt="%(institution_amt)d" bank_id="%(institution_bank_id)s" acct_num="%(institution_acct)s" />
119<item_detail item_id="2" item_name="%(provider_item_name)s" item_amt="%(provider_amt)d" bank_id="%(provider_bank_id)s" acct_num="%(provider_acct)s" />
120</item_details>
121</payment_item_detail>""" % xmldict
122        self.xml_data = """<input type="hidden" name="xml_data" value='%s'  />""" % xmltext
123        self.context.provider_amt = provider_amt
124        self.amount_auth = int(100 * self.context.amount_auth)
125        hashargs = (
126            self.context.p_id +
127            PRODUCT_ID +
128            self.pay_item_id +
129            str(int(self.amount_auth)) +
130            self.site_redirect_url +
131            self.mac)
132        self.hashvalue = hashlib.sha512(hashargs).hexdigest()
133        return
134
135class CustomInterswitchPageApplicant(InterswitchPageApplicant):
136    """ View which sends a POST request to the Interswitch
137    CollegePAY payment gateway.
138    """
139    grok.context(ICustomApplicantOnlinePayment)
140    action = POST_ACTION
141    site_name = SITE_NAME
142    currency = CURRENCY
143    pay_item_id = '0000' # must be provided by Interswitch
144    product_id = PRODUCT_ID
145    mac = MAC
146    gateway_amt = GATEWAY_AMT
147
148    def update(self):
149        if not module_activated(
150            self.context.__parent__.__parent__.year, self.context):
151            self.flash(_('Forbidden'), type='danger')
152            self.redirect(self.url(self.context, '@@index'))
153            return
154        error = self.init_update()
155        if error:
156            self.flash(error, type='danger')
157            self.redirect(self.url(self.context, '@@index'))
158            return
159        # Already now it becomes an Interswitch payment. We set the net amount
160        # and add the gateway amount.
161        if not self.context.r_company:
162            self.context.net_amt = self.context.amount_auth
163            self.context.amount_auth += self.gateway_amt
164            self.context.gateway_amt = self.gateway_amt
165            self.context.r_company = u'interswitch'
166        xmldict = {}
167        provider_amt = 400.0
168        xmldict['institution_acct'] = '0010078210'
169        xmldict['institution_bank_id'] = '47'
170        xmldict['detail_ref'] = self.context.p_id
171        xmldict['provider_amt'] = 100 * provider_amt
172        xmldict['provider_acct'] = PROVIDER_ACCT
173        xmldict['provider_bank_id'] = PROVIDER_BANK_ID
174        xmldict['provider_item_name'] = PROVIDER_ITEM_NAME
175        xmldict['institution_item_name'] = self.context.category
176        xmldict['institution_name'] = INSTITUTION_NAME
177        xmldict['institution_amt'] = 100 * self.context.net_amt
178        if not self.context.provider_amt:
179            self.context.provider_amt = provider_amt
180            self.context.amount_auth += provider_amt
181        xmltext = """<payment_item_detail>
182<item_details detail_ref="%(detail_ref)s" college="%(institution_name)s">
183<item_detail item_id="1" item_name="%(institution_item_name)s" item_amt="%(institution_amt)d" bank_id="%(institution_bank_id)s" acct_num="%(institution_acct)s" />
184<item_detail item_id="2" item_name="%(provider_item_name)s" item_amt="%(provider_amt)d" bank_id="%(provider_bank_id)s" acct_num="%(provider_acct)s" />
185</item_details>
186</payment_item_detail>""" % xmldict
187        self.xml_data = """<input type="hidden" name="xml_data" value='%s'  />""" % xmltext
188        self.amount_auth = int(100 * self.context.amount_auth)
189        hashargs = (
190            self.context.p_id +
191            PRODUCT_ID +
192            self.pay_item_id +
193            str(int(self.amount_auth)) +
194            self.site_redirect_url +
195            self.mac)
196        self.hashvalue = hashlib.sha512(hashargs).hexdigest()
197        return
198
199class CustomInterswitchPaymentRequestWebservicePageStudent(
200    InterswitchPaymentRequestWebservicePageStudent):
201    """Request webservice view for the CollegePAY gateway
202    """
203    grok.context(ICustomStudentOnlinePayment)
204    product_id = PRODUCT_ID
205    gateway_host = HOST
206    gateway_url = URL
207    mac = MAC
208
209class CustomInterswitchPaymentVerifyWebservicePageStudent(
210    InterswitchPaymentVerifyWebservicePageStudent):
211    """Payment verify view for the CollegePAY gateway
212    """
213    grok.context(ICustomStudentOnlinePayment)
214    product_id = PRODUCT_ID
215    gateway_host = HOST
216    gateway_url = URL
217    mac = MAC
218
219class CustomInterswitchPaymentRequestWebservicePageApplicant(
220    InterswitchPaymentRequestWebservicePageApplicant):
221    """Request webservice view for the CollegePAY gateway
222    """
223    grok.context(ICustomApplicantOnlinePayment)
224    product_id = PRODUCT_ID
225    gateway_host = HOST
226    gateway_url = URL
227    mac = MAC
228
229class CustomInterswitchPaymentVerifyWebservicePageApplicant(
230    InterswitchPaymentVerifyWebservicePageApplicant):
231    """Payment verify view for the CollegePAY gateway
232    """
233    grok.context(ICustomApplicantOnlinePayment)
234    product_id = PRODUCT_ID
235    gateway_host = HOST
236    gateway_url = URL
237    mac = MAC
238
239
240# WebCheckout customizations
241
242class CustomWebCheckoutPageStudent(WebCheckoutPageStudent):
243    """ View which sends a POST request to the Interswitch
244    WebCheckout payment gateway.
245    """
246    action = 'https://newwebpay.interswitchng.com/collections/w/pay'
247    currency = '566'
248    pay_item_id = 'Default_Payable_MX76823'
249    merchant_code = 'MX76823'
250    gateway_amt = 0.0
251
252class CustomWebCheckoutPageApplicant(WebCheckoutPageApplicant):
253    """ View which sends a POST request to the Interswitch
254    WebCheckout payment gateway.
255    """
256
257    action = 'https://newwebpay.interswitchng.com/collections/w/pay'
258    currency = '566'
259    pay_item_id = 'Default_Payable_MX76823'
260    merchant_code = 'MX76823'
261    gateway_share = 0.015
262    provider_share = 0.05
263
264    @property
265    def split_accounts(self):
266        sa = [
267            {"alias":"bigtentfdn","percentage":"95","description":"Donation","isPrimary":"true"},
268            {"alias":"waeac","percentage":"5","description":"Tech Fee"},
269            ]
270        return str(sa)
271
272    def update(self):
273        if not webcheckout_module_activated(
274            self.context.__parent__.__parent__.year, self.context):
275            self.flash(_('Forbidden'), type='danger')
276            self.redirect(self.url(self.context, '@@index'))
277            return
278        error = self.init_update()
279        if error:
280            self.flash(error, type='danger')
281            self.redirect(self.url(self.context, '@@index'))
282        # Already now it becomes an Interswitch payment. We set the net amount
283        # and add the gateway amount. Fees will be added so that the foundation
284        # receives the whole subscription.
285        if not self.context.r_company:
286            self.context.net_amt = self.context.amount_auth
287            self.context.amount_auth = round(self.context.net_amt/(1-self.gateway_share)/(1-self.provider_share), 2)
288            self.context.gateway_amt = round(self.context.amount_auth *  self.gateway_share, 2)
289            self.context.provider_amt = round((self.context.amount_auth-self.context.gateway_amt) * self.provider_share, 2)
290            self.context.r_company = u'interswitch'
291        self.amount_auth = int(100 * self.context.amount_auth)
292        return
293
294class CustomWebCheckoutConfirmTransactionStudent(WebCheckoutConfirmTransactionStudent):
295    """ Request webservice view for the WebCheckout gateway
296    """
297    merchant_code = 'MX76823'
298    gateway_host = 'webpay.interswitchng.com'
299    gateway_url = '/collections/api/v1/gettransaction.json'
300    https = True
301
302class CustomWebCheckoutConfirmTransactionApplicant(WebCheckoutConfirmTransactionApplicant):
303    """ Request webservice view for the WebCheckout gateway
304    """
305    merchant_code = 'MX76823'
306    gateway_host = 'webpay.interswitchng.com'
307    gateway_url = '/collections/api/v1/gettransaction.json'
308    https = True
309
310
Note: See TracBrowser for help on using the repository browser.