Ignore:
Timestamp:
4 Nov 2015, 09:16:13 (9 years ago)
Author:
Henrik Bettermann
Message:

Implement Interswitch JSON transaction query. This webservice is
automatically used if a mac key is set in the request webservice
view.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • main/kofacustom.nigeria/trunk/src/kofacustom/nigeria/interswitch/helpers.py

    r11914 r13387  
    2020from datetime import datetime
    2121import httplib
     22import hashlib
     23import json
     24from urllib import urlencode
    2225import grok
    2326from xml.dom.minidom import parseString
     
    4447    response = h.getresponse()
    4548    return response
     49
    4650
    4751def get_SOAP_response(product_id, transref, host, url, https):
     
    6468    return response
    6569
    66 def query_interswitch(payment, product_id, host, url, https=False):
     70
     71def get_JSON_response(product_id, transref, host, url, https, mac, amount):
     72    hashargs = product_id + transref + mac
     73    hashvalue = hashlib.sha512(hashargs).hexdigest()
     74    headers={
     75        'Content-Type':'text/xml; charset=utf-8',
     76        'Hash':hashvalue,
     77    }
     78    if https:
     79        h = httplib.HTTPSConnection(host)
     80    else:
     81        h = httplib.HTTPConnection(host)
     82    amount = int(100 * amount)
     83    args = {'productid': product_id,
     84            'transactionreference': transref,
     85            'amount': amount}
     86    url = '%s?' % url + urlencode(args)
     87    h.request("GET", url, headers=headers)
     88    response = h.getresponse()
     89    if response.status!=200:
     90        return {'error': 'Connection error (%s, %s)' % (response.status, response.reason)}
     91    jsonout = response.read()
     92    parsed_json = json.loads(jsonout)
     93    return parsed_json
     94
     95def query_interswitch_SOAP(payment, product_id, host, url, https):
    6796    sr = get_SOAP_response(product_id, payment.p_id, host, url, https)
    6897    if sr.startswith('Connection error'):
     
    110139    return True, msg, log
    111140
     141def query_interswitch(payment, product_id, host, url, https, mac):
     142    # If no mac mac key is given, fall back to deprecated SOAP method
     143    # (Uniben, AAUA, FCEOkene).
     144    if mac == None:
     145        return query_interswitch_SOAP(payment, product_id, host, url, https)
     146    jr = get_JSON_response(product_id, payment.p_id, host, url,
     147                           https, mac, payment.amount_auth)
     148    error = jr.get('error')
     149    if error:
     150        msg = log = error
     151        return False, msg, log
     152
     153    # A typical JSON response
     154    #  {u'SplitAccounts': [],
     155    #   u'MerchantReference':u'p4210665523377',
     156    #   u'PaymentReference':u'GTB|WEB|KPOLY|12-01-2015|013138',
     157    #   u'TransactionDate':u'2015-01-12T13:43:39.27',
     158    #   u'RetrievalReferenceNumber':u'000170548791',
     159    #   u'ResponseDescription': u'Approved Successful',
     160    #   u'Amount': 2940000,
     161    #   u'CardNumber': u'2507',
     162    #   u'ResponseCode': u'00',
     163    #   u'LeadBankCbnCode': None,
     164    #   u'LeadBankName': None}
     165
     166    if len(jr) != 11:
     167        msg = _('Invalid callback: ${a}', mapping = {'a': str(jr)})
     168        log = 'invalid callback for payment %s: %s' % (payment.p_id, str(jr))
     169        return False, msg, log
     170    payment.r_code = jr['ResponseCode']
     171    payment.r_desc = jr['ResponseDescription']
     172    payment.r_amount_approved = jr['Amount'] / 100.0
     173    payment.r_card_num = jr['CardNumber']
     174    payment.r_pay_reference = jr['PaymentReference']
     175    payment.r_company = u'interswitch'
     176    if payment.r_code != '00':
     177        msg = _('Unsuccessful callback: ${a}', mapping = {'a': payment.r_desc})
     178        log = 'unsuccessful callback for %s payment %s: %s' % (
     179            payment.p_category, payment.p_id, payment.r_desc)
     180        payment.p_state = 'failed'
     181        notify(grok.ObjectModifiedEvent(payment))
     182        return False, msg, log
     183    if round(payment.r_amount_approved, 2) != round(payment.amount_auth, 2):
     184        msg = _('Callback amount does not match.')
     185        log = 'wrong callback for %s payment %s: %s' % (
     186            payment.p_category, payment.p_id, str(jr))
     187        payment.p_state = 'failed'
     188        notify(grok.ObjectModifiedEvent(payment))
     189        return False, msg, log
     190    if jr['MerchantReference'] != payment.p_id:
     191        msg = _('Callback transaction id does not match.')
     192        log = 'wrong callback for %s payment %s: %s' % (
     193            payment.p_category, payment.p_id, str(jr))
     194        payment.p_state = 'failed'
     195        notify(grok.ObjectModifiedEvent(payment))
     196        return False, msg, log
     197    payment.p_state = 'paid'
     198    payment.payment_date = datetime.utcnow()
     199    msg = _('Successful callback received')
     200    log = 'valid callback for %s payment %s: %s' % (
     201        payment.p_category, payment.p_id, str(jr))
     202    notify(grok.ObjectModifiedEvent(payment))
     203    return True, msg, log
     204
    112205def write_payments_log(id, payment):
    113206    payment.logger.info(
Note: See TracChangeset for help on using the changeset viewer.