diff --git a/eopayment/sips.py b/eopayment/sips.py index a4d1510..b638854 100644 --- a/eopayment/sips.py +++ b/eopayment/sips.py @@ -5,6 +5,7 @@ from decimal import Decimal import logging import os import os.path +import uuid from common import PaymentCommon, HTML @@ -35,10 +36,21 @@ REQUEST_VALID_PARAMS = ['merchant_id', 'merchant_country', 'amount', 'capture_day', 'capture_mode', 'bgcolor', 'block_align', 'block_order', 'textcolor', 'receipt_complement', 'caddie', 'customer_id', 'customer_email', 'customer_ip_address', 'data', 'return_context', 'target', 'order_id'] + +RESPONSE_PARAMS = [ 'code', 'error', 'merchant_id', 'merchant_country', + 'amount', 'transaction_id', 'payment_means', 'transmission_date', + 'payment_time', 'payment_date', 'response_code', 'payment_certificate', + 'authorisation_id', 'currency_code', 'card_number', 'cvv_flag', + 'cvv_response_code', 'bank_response_code', 'complementary_code', + 'complementary_info', 'return_context', 'caddie', 'receipt_complement', + 'merchant_language', 'language', 'customer_id', 'order_id', 'customer_email', + 'customer_ip_address', 'capture_day', 'capture_mode', 'data', ] + DATA = 'DATA' PARAMS = 'params' TRANSACTION_ID = 'transaction_id' +ORDER_ID = 'order_id' MERCHANT_ID = 'merchant_id' RESPONSE_CODE = 'response_code' @@ -75,6 +87,7 @@ class Payment(PaymentCommon): transaction_id = self.transaction_id(6, string.digits, 'sips', params[MERCHANT_ID]) params[TRANSACTION_ID] = transaction_id + params[ORDER_ID] = str(uuid.uuid4()).replace('-','') params['amount'] = str(Decimal(amount)*100) if email: params['customer_email'] = email @@ -82,7 +95,7 @@ class Payment(PaymentCommon): params['normal_return_url'] = next_url code, error, form = self.execute('request', params) if int(code) == 0: - return transaction_id, HTML, form + return params[ORDER_ID], HTML, form else: raise RuntimeError('sips/request returned -1: %s' % error) @@ -90,6 +103,6 @@ class Payment(PaymentCommon): form = urlparse.parse_qs(query_string) params = {'message': form[DATA]} result = self.execute('response', params) - d = dict([p.split('=',1) for p in result]) + d = dict(zip(RESPONSE_PARAMS, result)) LOGGER.debug('response contains fields %s' % d) - return result.get(RESPONSE_CODE) == '00', form.get(TRANSACTION_ID), d + return result.get(RESPONSE_CODE) == '00', form.get(ORDER_ID), d, None diff --git a/eopayment/spplus.py b/eopayment/spplus.py index e8bc12b..d659379 100644 --- a/eopayment/spplus.py +++ b/eopayment/spplus.py @@ -11,12 +11,15 @@ import logging import Crypto.Cipher.DES from common import PaymentCommon, URL +__all__ = ['Payment'] + KEY_DES_KEY = '\x45\x1f\xba\x4f\x4c\x3f\xd4\x97' IV = '\x30\x78\x30\x62\x2c\x30\x78\x30' REFERENCE = 'reference' ETAT = 'etat' ETAT_PAIEMENT_ACCEPTE = '1' SPCHECKOK = 'spcheckok' +LOGGER = logging.getLogger(__name__) def decrypt_ntkey(ntkey): key = binascii.unhexlify(ntkey.replace(' ','')) @@ -49,6 +52,7 @@ LOGGER = logging.getLogger(__name__) class Payment(PaymentCommon): def __init__(self, options): + LOGGER.debug('initializing spplus payment with %s' % options) self.cle = options['cle'] self.siret = options['siret'] self.devise = '978' @@ -56,6 +60,8 @@ class Payment(PaymentCommon): self.taxe = options.get('taxe', '0.00') def request(self, montant, email=None, next_url=None): + LOGGER.debug('requesting spplus payment with montant %s email=%s and \ +next_url=%s' % (montant, email, next_url)) reference = self.transaction_id(20, ALPHANUM, 'spplus', self.siret) validite = dt.date.today()+dt.timedelta(days=1) validite = validite.strftime('%d/%m/%Y') @@ -75,9 +81,12 @@ class Payment(PaymentCommon): or '?' in next_url: raise ValueError('next_url must be an absolute URL without parameters') fields['urlretour'] = next_url + LOGGER.debug('sending fields %s' % fields) query = urllib.urlencode(fields) - return reference, URL, '%s?%s&hmac=%s' % (SERVICE_URL, query, - sign_ntkey_query(self.cle, query)) + url = '%s?%s&hmac=%s' % (SERVICE_URL, query, sign_ntkey_query(self.cle, + query)) + LOGGER.debug('full url %s' % url) + return reference, URL, url def response(self, query_string): form = urlparse.parse_qs(query_string) diff --git a/eopayment/systempayv2.py b/eopayment/systempayv2.py index c436200..246ff59 100644 --- a/eopayment/systempayv2.py +++ b/eopayment/systempayv2.py @@ -15,6 +15,7 @@ __all__ = ['Payment'] PAYMENT_URL = "https://systempay.cyberpluspaiement.com/vads-payment/" LOGGER = logging.getLogger(__name__) SERVICE_URL = '???' +VADS_TRANS_DATE = 'vads_trans_date' def isonow(): return dt.datetime.now() \ @@ -97,7 +98,7 @@ PARAMETERS = [ Parameter('signature', 'an', None, length=40), Parameter('vads_site_id', 'n', 02, length=8, needed=True), Parameter('vads_theme_config', 'ans', 32, max_length=255), - Parameter('vads_trans_date', 'n', 04, length=14, needed=True, + Parameter(VADS_TRANS_DATE, 'n', 04, length=14, needed=True, default=isonow), Parameter('vads_trans_id', 'n', 03, length=6, needed=True), Parameter('vads_validation_mode', 'n', 5, max_length=1, choices=('', 0, 1), @@ -205,8 +206,8 @@ class Payment(PaymentCommon): if next_url: kwargs['vads_url_return'] = next_url - transaction_id = self.transaction_id(6, string.digits, - 'systempay', self.options['vads_site_id']) + transaction_id = self.transaction_id(6, + string.digits, 'systempay', self.options['vads_site_id']) kwargs['vads_trans_id'] = transaction_id fields = kwargs for parameter in PARAMETERS: @@ -232,6 +233,7 @@ parameters received: %s' % (name, kwargs)) parameter.ptype)) fields['signature'] = self.signature(fields) url = '%s?%s' % (SERVICE_URL, urllib.urlencode(fields)) + transaction_id = '%s_%s' % (fields[VADS_TRANS_DATE], transaction_id) return transaction_id, URL, fields def response(self, query_string): @@ -239,27 +241,32 @@ parameters received: %s' % (name, kwargs)) copy = fields.copy() if 'vads_auth_result' in fields: v = copy['vads_auth_result'] - copy['vads_auth_result'] = '%s: %s' % (v, AUTH_RESULT_MAP.get(v, 'Code inconnu')) + ctx = (v, AUTH_RESULT_MAP.get(v, 'Code inconnu')) + copy['vads_auth_result'] = '%s: %s' % ctx if 'vads_result' in copy: v = copy['vads_result'] - copy['vads_result'] = '%s: %s' % (v, RESULT_MAP.get(v, 'Code inconnu')) + ctx = (v, RESULT_MAP.get(v, 'Code inconnu')) + copy['vads_result'] = '%s: %s' % ctx if v == '30': if 'vads_extra_result' in fields: v = fields['vads_extra_result'] if v.isdigit(): for parameter in PARAMETERS: if int(v) == parameter.code: - fields['vads_extra_result'] = 'erreur dans le champ %s' % parameter.name + s ='erreur dans le champ %s' % parameter.name + fields['vads_extra_result'] = s elif v in ('05', '00'): v = fields['vads_extra_result'] - fields['vads_extra_result'] = '%s: %s' % (v, EXTRA_RESULT_MAP.get(v, 'Code inconnu')) + fields['vads_extra_result'] = '%s: %s' % (v, + EXTRA_RESULT_MAP.get(v, 'Code inconnu')) LOGGER.debug('checking systempay response on:') for key in sorted(fields.keys): LOGGER.debug(' %s: %s' % (key, copy[key])) signature = self.signature(fields) result = signature == fields['signature'] LOGGER.debug('signature check result: %s' % result) - return result + transaction_id = '%s_%s' % (copy[VADS_TRANS_DATE], copy[VADS_TRANS_ID]) + return result, transaction_id, copy, None def signature(self, fields): LOGGER.debug('got fields %s to sign' % fields )