diff --git a/eopayment/paybox.py b/eopayment/paybox.py index 15ea18e..4333173 100644 --- a/eopayment/paybox.py +++ b/eopayment/paybox.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 +import codecs from collections import OrderedDict import datetime import logging @@ -10,6 +11,7 @@ from Crypto.Signature import PKCS1_v1_5 from Crypto.PublicKey import RSA from Crypto.Hash import SHA +import six from six.moves.urllib import parse as urlparse from six.moves.urllib import parse as urllib @@ -19,7 +21,7 @@ import string import warnings from .common import (PaymentCommon, PaymentResponse, FORM, PAID, ERROR, Form, - ORDERID_TRANSACTION_SEPARATOR, ResponseError) + ORDERID_TRANSACTION_SEPARATOR, ResponseError, force_text) __all__ = ['sign', 'Payment'] @@ -111,9 +113,10 @@ def sign(data, key): algo = ALGOS[v] break assert algo, 'Missing or invalid PBX_HASH' - tosign = ['%s=%s' % (k, unicode(v).encode('utf-8')) for k, v in data] + tosign = ['%s=%s' % (k, force_text(v)) for k, v in data] tosign = '&'.join(tosign) logger.debug('signed string %r', tosign) + tosign = tosign.encode('utf-8') signature = hmac.new(key, tosign, algo) return tuple(data) + (('PBX_HMAC', signature.hexdigest().upper()),) @@ -210,22 +213,22 @@ class Payment(PaymentCommon): def request(self, amount, email, name=None, orderid=None, **kwargs): d = OrderedDict() - d['PBX_SITE'] = unicode(self.site) - d['PBX_RANG'] = unicode(self.rang).strip()[-2:] - d['PBX_IDENTIFIANT'] = unicode(self.identifiant) + d['PBX_SITE'] = force_text(self.site) + d['PBX_RANG'] = force_text(self.rang).strip()[-2:] + d['PBX_IDENTIFIANT'] = force_text(self.identifiant) d['PBX_TOTAL'] = (amount * Decimal(100)).to_integral_value(ROUND_DOWN) - d['PBX_DEVISE'] = unicode(self.devise) + d['PBX_DEVISE'] = force_text(self.devise) transaction_id = kwargs.get('transaction_id') or \ self.transaction_id(12, string.digits, 'paybox', self.site, self.rang, self.identifiant) - d['PBX_CMD'] = unicode(transaction_id) + d['PBX_CMD'] = force_text(transaction_id) # prepend order id command reference if orderid: d['PBX_CMD'] = orderid + ORDERID_TRANSACTION_SEPARATOR + d['PBX_CMD'] - d['PBX_PORTEUR'] = unicode(email) + d['PBX_PORTEUR'] = force_text(email) d['PBX_RETOUR'] = 'montant:M;reference:R;code_autorisation:A;erreur:E;signature:K' d['PBX_HASH'] = 'SHA512' - d['PBX_TIME'] = kwargs.get('time') or (unicode(datetime.datetime.utcnow().isoformat('T')).split('.')[0]+'+00:00') + d['PBX_TIME'] = kwargs.get('time') or (force_text(datetime.datetime.utcnow().isoformat('T')).split('.')[0]+'+00:00') d['PBX_ARCHIVAGE'] = transaction_id if self.normal_return_url: d['PBX_EFFECTUE'] = self.normal_return_url @@ -238,16 +241,21 @@ class Payment(PaymentCommon): "use automatic_return_url", DeprecationWarning) automatic_return_url = self.callback if automatic_return_url: - d['PBX_REPONDRE_A'] = unicode(automatic_return_url) + d['PBX_REPONDRE_A'] = force_text(automatic_return_url) d = d.items() - d = sign(d, self.shared_secret.decode('hex')) + + if six.PY3: + shared_secret = codecs.decode(bytes(self.shared_secret, 'ascii'), 'hex') + else: + shared_secret = codecs.decode(bytes(self.shared_secret), 'hex') + d = sign(d, shared_secret) url = URLS[self.platform] fields = [] for k, v in d: fields.append({ 'type': u'hidden', - 'name': unicode(k), - 'value': unicode(v), + 'name': force_text(k), + 'value': force_text(v), }) form = Form(url, 'POST', fields, submit_name=None, submit_value=u'Envoyer', encoding='utf-8') diff --git a/tests/test_paybox.py b/tests/test_paybox.py index 2e9156b..bedcb69 100644 --- a/tests/test_paybox.py +++ b/tests/test_paybox.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- +import codecs from unittest import TestCase from decimal import Decimal import base64 @@ -19,7 +20,8 @@ BACKEND_PARAMS = { class PayboxTests(TestCase): def test_sign(self): - key = '0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF'.decode('hex') + key = b'0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF' + key = codecs.decode(key, 'hex') d = dict(paybox.sign([ ['PBX_SITE', u'12345678'], ['PBX_RANG', u'32'], @@ -97,7 +99,7 @@ UX4D2A/QcMvkEcRVXFx5tQqcE9/JnMqE41TF/ebn7jC/MBxxtPFkUN7+EZoeMN7x OWzAMDm/xsCWRvvel4GGixgm3aQRUPyTrlm4Ksy32Ya0rNnEDMAvB3dxOn7cp8GR ZdzrudBlevZXpr6iYwIDAQAB -----END PUBLIC KEY-----''' - data = 'coin\n' + data = b'coin\n' sig64 = '''VCt3sgT0ecacmDEWWNVXJ+jGmIPBMApK42tBJV0FlDjpllOGPy8MsAmLW4/QjTtx z0Dkz0NjxvU+5WzQZh9Uuxr/egRCwV4NMRWqu0zaVVioeBvl4/5CWm4f4/1L9+0m FBFKOZhgBJnkC+l6+XhT4aYWKaQ4ocmOMV92yjeXTE4='''