Ignore:
Timestamp:
16 Mar 2012, 06:26:17 (13 years ago)
Author:
Henrik Bettermann
Message:

Setup module for Interswitch components.

Do not display the base package callback button in custom pages.

Location:
main/waeup.custom/trunk/src/waeup/custom/students
Files:
2 added
1 deleted
2 edited

Legend:

Unmodified
Added
Removed
  • main/waeup.custom/trunk/src/waeup/custom/students/browser.py

    r7889 r7890  
    1616## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    1717##
    18 from datetime import datetime
    19 from urllib import urlencode
    2018import grok
    2119from zope.formlib.textwidgets import BytesDisplayWidget
     
    2321    FriendlyDateWidget, FriendlyDateDisplayWidget
    2422    )
    25 from waeup.kofa.browser.layout import KofaPage, UtilityView
    26 from waeup.kofa.accesscodes import create_accesscode
    27 from waeup.kofa.students.interfaces import IStudentOnlinePayment
    2823from waeup.kofa.students.browser import (
    2924    StudentPersonalDisplayFormPage, StudentPersonalManageFormPage,
    3025    StudentClearanceManageFormPage, StudentClearanceEditFormPage,
    31     StudentClearanceDisplayFormPage, write_log_message,
    32     OnlinePaymentDisplayFormPage)
     26    StudentClearanceDisplayFormPage)
    3327from waeup.kofa.students.viewlets import RequestCallbackActionButton
    3428from waeup.custom.students.interfaces import (
    35     IStudent, IStudentPersonal, IStudentClearance, IStudentClearanceEdit
     29    IStudent, IStudentPersonal, IStudentClearance, IStudentClearanceEdit,
    3630    )
    3731from waeup.custom.interfaces import MessageFactory as _
     
    7266    form_fields['date_of_birth'].custom_widget = FriendlyDateWidget('le-year')
    7367
    74 #class OnlinePaymentDisplayFormPage(OnlinePaymentDisplayFormPage):
    75 #    """ Page to view an online payment ticket.
    76 
    77 #    The customized version provides also product data for
    78 #    payment providers
    79 #    """
    80 
    81 
    82 class InterswitchActionButton(RequestCallbackActionButton):
    83     grok.order(2)
    84     icon = 'actionicon_pay.png'
    85     text = _('CollegePAY')
    86     target = 'goto_interswitch'
     68class RequestCallbackActionButton(RequestCallbackActionButton):
     69    """ Do not display the base package callback button in custom pages.
     70    """
    8771
    8872    @property
    8973    def target_url(self):
    90         if self.context.p_state != 'unpaid':
    91             return ''
    92         return self.view.url(self.view.context, self.target)
    93 
    94 class RequestCallbackActionButton(RequestCallbackActionButton):
    95     grok.order(3)
    96     icon = 'actionicon_call.png'
    97     text = _('Request CollegePAY callback')
    98     product_id = '57'
    99    
    100     def target_url(self):
    101         if self.context.p_state != 'unpaid':
    102             return ''
    103         site_redirect_url = self.view.url(self.view.context, 'callback')
    104         query_url = "https://testwebpay.interswitchng.com/test_paydirect/services/TransactionQueryURL.aspx"
    105         args = {
    106             'transRef':self.context.p_id,
    107             'prodID':self.product_id,
    108             'redirectURL':site_redirect_url}
    109         return query_url + '?%s' % urlencode(args)
    110 
    111 class InterswitchPage(KofaPage):
    112     """ View which sends a POST request to the Interswitch
    113     CollegePAY payment gateway.
    114     """
    115     grok.context(IStudentOnlinePayment)
    116     grok.name('goto_interswitch')
    117     grok.template('goto_interswitch')
    118     grok.require('waeup.payStudent')
    119     label = _('Submit data to CollegePAY (Interswitch Payment Gateway)')
    120     submit_button = _('Submit')
    121     action = 'https://testwebpay.interswitchng.com/test_paydirect/webpay/pay.aspx'
    122     site_name = 'xyz.waeup.org'
    123     provider_acct = '2345'
    124     provider_bank_id = '8'
    125     provider_item_name = 'Kofa Provider Fee'
    126     institution_acct = '1234'
    127     institution_bank_id = '9'
    128     institution_name = 'Sample University'
    129     currency = '566'
    130     pay_item_id = '5700'
    131     product_id = '57'
    132 
    133     def update(self):
    134         if self.context.p_state != 'unpaid':
    135             self.flash(_("Payment ticket can't be re-send to CollegePAY."))
    136             self.redirect(self.url(self.context, '@@index'))
    137             return
    138         xmldict = {}
    139         self.student = self.context.getStudent()
    140         self.amount = (self.context.amount_auth + self.context.surcharge_1 +
    141             self.context.surcharge_2 + self.context.surcharge_3)
    142         self.amount_100 = 100 * self.amount
    143         self.local_date_time = str(self.context.creation_date)
    144         self.site_redirect_url = self.url(self.context, 'callback')
    145         certificate = getattr(self.student['studycourse'],'certificate',None)
    146         if certificate is not None:
    147             xmldict['department'] = certificate.__parent__.__parent__.code
    148             xmldict['faculty'] = certificate.__parent__.__parent__.__parent__.code
    149         else:
    150             xmldict['department'] = None
    151             xmldict['faculty'] = None
    152         xmldict['detail_ref'] = self.context.p_id
    153         xmldict['provider_amt'] = 100 * self.context.surcharge_1
    154         xmldict['provider_acct'] = self.provider_acct
    155         xmldict['provider_bank_id'] = self.provider_bank_id
    156         xmldict['provider_item_name'] = self.provider_item_name
    157         xmldict['institution_amt'] = 100 * self.context.amount_auth
    158         xmldict['institution_acct'] = self.institution_acct
    159         xmldict['institution_bank_id'] = self.institution_bank_id
    160         xmldict['institution_item_name'] = self.context.p_category
    161         xmldict['institution_name'] = self.institution_name
    162         # Interswitch amount is not part of the xml data
    163         xmltext = """<payment_item_detail>
    164 <item_details detail_ref="%(detail_ref)s" college="%(institution_name)s" department="%(department)s" faculty="%(faculty)s">
    165 <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" />
    166 <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" />
    167 </item_details>
    168 </payment_item_detail>""" % xmldict
    169         self.xml_data = """<input type="hidden" name="xml_data" value='%s'  />""" % xmltext
    170         return
    171 
    172 class OnlinePaymentCallbackPage(UtilityView, grok.View):
    173     """ Callback view for the CollegePAY gateway
    174     """
    175     grok.context(IStudentOnlinePayment)
    176     grok.name('callback')
    177     grok.require('waeup.payStudent')
    178 
    179     # This view is not yet working for offline querying transactions
    180     # since the the query string differs from the query string sent after
    181     # posting transactions. This Interswitch bug must be removed first.
    182     # Alternatively, we could use the webservice only and replace
    183     # the RequestCallbackActionButton by a RequestWebserviceActionButton
    184 
    185     def update(self):
    186         if self.context.p_state == 'paid':
    187             self.flash(_('This ticket has already been paid.'))
    188             return
    189         student = self.context.getStudent()
    190         query = self.request.form
    191         # Should be logged instead of printed
    192         print query
    193         if query.get('resp', None) != '00':
    194             self.flash(_('Unsuccessful callback: ${a}',
    195                 mapping = {'a': query.get('desc', _('No query string'))}))
    196             write_log_message(self,'invalid callback: %s' % self.context.p_id)
    197             self.context.r_card_num = query.get('cardNum', None)
    198             self.context.r_code = query.get('resp', None)
    199             self.context.p_state = 'failed'
    200             return
    201 
    202         # Add amount checking
    203 
    204 
    205         # Add webservice validation
    206 
    207 
    208         write_log_message(self,'valid callback: %s' % self.context.p_id)
    209         self.context.r_amount_approved = self.context.amount_auth
    210         self.context.r_card_num = query.get('cardNum', None)
    211         self.context.r_code = query.get('resp', None)
    212         self.context.r_desc = query.get('desc', None)
    213         self.context.r_pay_reference  = query.get('payRef', None)
    214         self.context.p_state = 'paid'
    215         self.context.payment_date = datetime.now()
    216 
    217         if self.context.p_category == 'clearance':
    218             # Create CLR access code
    219             pin, error = create_accesscode('CLR',0,student.student_id)
    220             if error:
    221                 self.flash(_('Valid callback received. ${a}',
    222                     mapping = {'a':error}))
    223                 return
    224             self.context.ac = pin
    225         elif self.context.p_category == 'schoolfee':
    226             # Create SFE access code
    227             pin, error = create_accesscode('SFE',0,student.student_id)
    228             if error:
    229                 self.flash(_('Valid callback received. ${a}',
    230                     mapping = {'a':error}))
    231                 return
    232             self.context.ac = pin
    233         elif self.context.p_category == 'bed_allocation':
    234             # Create HOS access code
    235             pin, error = create_accesscode('HOS',0,student.student_id)
    236             if error:
    237                 self.flash(_('Valid callback received. ${a}',
    238                     mapping = {'a':error}))
    239                 return
    240             self.context.ac = pin
    241         self.flash(_('Valid callback received.'))
    242         return
    243 
    244     def render(self):
    245         self.redirect(self.url(self.context, '@@index'))
    246         return
    247 
    248 
    249 
     74        return ''
  • main/waeup.custom/trunk/src/waeup/custom/students/tests.py

    r7889 r7890  
    152152        self.browser.getControl("Create ticket").click()
    153153        ctrl = self.browser.getControl(name='val_id')
    154 
    155         #value = ctrl.options[1]
    156         #self.browser.getLink(value).click()
    157         #self.assertMatches('...Amount Authorized...',
    158         #                   self.browser.contents)
    159         #payment_url = self.browser.url
    160 
    161154        self.browser.open(payment_url + '/callback')
    162         self.assertMatches('...Unsuccessful callback: No query string...',
     155        self.assertMatches('...Unsuccessful callback: Incomplete query string...',
    163156                          self.browser.contents)
    164157        self.assertMatches('...Failed...',
    165158                           self.browser.contents)
    166         #print self.browser.contents
    167159        self.browser.open(self.callback_url(payment_url, '00', '300'))
    168160        self.assertMatches('...Valid callback received...',
Note: See TracChangeset for help on using the changeset viewer.