Projet

Général

Profil

0001-standardise-normal_return_url-and-automatic_return_u.patch

Frédéric Péters, 16 février 2016 18:18

Télécharger (20,9 ko)

Voir les différences:

Subject: [PATCH] standardise normal_return_url and automatic_return_url
 options (#9998)

 eopayment/__init__.py    |  4 +---
 eopayment/dummy.py       | 54 ++++++++++++++++++++++++++++++++++--------------
 eopayment/ogone.py       | 17 +++++++++++++++
 eopayment/paybox.py      | 31 +++++++++++++++++++++++----
 eopayment/sips.py        | 10 +++++++--
 eopayment/sips2.py       | 12 +++++++++--
 eopayment/spplus.py      | 35 ++++++++++++++++++++++++-------
 eopayment/systempayv2.py | 19 ++++++++++++++++-
 eopayment/tipi.py        | 29 ++++++++++++++++++++------
 9 files changed, 170 insertions(+), 41 deletions(-)
eopayment/__init__.py
45 45
                   'siret': '00000000000001-01', \
46 46
               }
47 47
           >>> p = Payment(kind=SPPLUS, options=spplus_options)
48
           >>> transaction_id, kind, data = p.request('10.00', email='bob@example.com', \
49
                   next_url='https://my-site.com')
48
           >>> transaction_id, kind, data = p.request('10.00', email='bob@example.com')
50 49
           >>> print (transaction_id, kind, data) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
51 50
           ('...', 1, 'https://www.spplus.net/paiement/init.do?...')
52 51

  
......
86 85
          Arguments:
87 86
          amount -- the amount of money to ask
88 87
          email -- the email of the customer (optional)
89
          next_url -- the URL where the customer will be returned (optional),
90 88
          usually redundant with the hardwired settings in the bank
91 89
          configuration panel. At this url you must use the Payment.response
92 90
          method to analyze the bank returned values.
eopayment/dummy.py
1 1
import urllib
2 2
import string
3 3
import logging
4
import warnings
5

  
6
def N_(message): return message
4 7

  
5 8
try:
6 9
    from cgi import parse_qs
......
27 30
       You must pass the following keys inside the options dictionnary:
28 31
        - dummy_service_url, the URL of the dummy payment service, it defaults
29 32
          to the one operated by Entr'ouvert.
30
        - direct_notification_url: where to POST to notify the service of a
33
        - automatic_return_url: where to POST to notify the service of a
31 34
          payment
32 35
        - origin: a human string to display to the user about the origin of
33 36
          the request.
34 37
        - siret: an identifier for the eCommerce site, fake.
35
        - next_url: the return URL for the user (can be overriden on a per
36
          request basis).
38
        - normal_return_url: the return URL for the user (can be overriden on a
39
          per request basis).
37 40
    '''
38 41
    description = {
39 42
            'caption': 'Dummy payment backend',
40 43
            'parameters': [
44
                {
45
                    'name': 'normal_return_url',
46
                    'caption': N_('Normal return URL'),
47
                    'default': '',
48
                    'required': True,
49
                },
50
                {
51
                    'name': 'automatic_return_url',
52
                    'caption': N_('Automatic return URL'),
53
                    'required': False,
54
                },
41 55
                {   'name': 'dummy_service_url',
42 56
                    'caption': 'URL of the dummy payment service',
43 57
                    'default': SERVICE_URL,
44 58
                    'type': str,
45 59
                },
46
                {   'name': 'direct_notification_url',
47
                    'caption': 'direct notification url',
48
                    'type': str,
49
                },
50 60
                {   'name': 'origin',
51 61
                    'caption': 'name of the requesting service, '
52 62
                               'to present in the user interface',
......
57 67
                    'caption': 'dummy siret parameter',
58 68
                    'type': str,
59 69
                },
60
                {   'name': 'next_url',
61
                    'caption': 'Return URL for the user',
62
                    'type': str,
63
                },
64 70
                {   'name': 'consider_all_response_signed',
65 71
                    'caption': 'All response will be considered as signed '
66 72
                         '(to test payment locally for example, as you '
......
68 74
                    'type': bool,
69 75
                    'default': False,
70 76
                },
77
                {   'name': 'direct_notification_url',
78
                    'caption': 'direct notification url (replaced by automatic_return_url)',
79
                    'type': str,
80
                    'deprecated': True,
81
                },
82
                {   'name': 'next_url (replaced by normal_return_url)',
83
                    'caption': 'Return URL for the user',
84
                    'type': str,
85
                    'deprecated': True,
86
                },
71 87
            ],
72 88
    }
73 89

  
......
77 93
                ' next_url %s info1 %s info2 %s info3 %s kwargs: %s',
78 94
                __name__, amount, name, address, email, phone, info1, info2, info3, next_url, kwargs)
79 95
        transaction_id = self.transaction_id(30, ALPHANUM, 'dummy', self.siret)
80
        if self.next_url:
81
            next_url = self.next_url
96
        normal_return_url = self.normal_return_url
97
        if next_url and not normal_return_url:
98
            warnings.warn("passing next_url to request() is deprecated, "
99
                          "set normal_return_url in options", DeprecationWarning)
100
            normal_return_url = next_url
101
        automatic_return_url = self.automatic_return_url
102
        if self.direct_notification_url and not automatic_return_url:
103
            warnings.warn("direct_notification_url option is deprecated, "
104
                          "use automatic_return_url", DeprecationWarning)
105
            automatic_return_url = self.direct_notification_url
82 106
        query = {
83 107
                'transaction_id': transaction_id,
84 108
                'siret': self.siret,
85 109
                'amount': amount,
86 110
                'email': email,
87
                'return_url': next_url or '',
88
                'direct_notification_url': self.direct_notification_url,
111
                'return_url': normal_return_url or '',
112
                'direct_notification_url': automatic_return_url or '',
89 113
                'origin': self.origin
90 114
        }
91 115
        query.update(dict(name=name, address=address, email=email, phone=phone,
eopayment/ogone.py
407 407
    description = {
408 408
        'caption': N_('Système de paiement Ogone / Ingenico Payment System e-Commerce'),
409 409
        'parameters': [
410
            {
411
                'name': 'normal_return_url',
412
                'caption': N_('Normal return URL'),
413
                'default': '',
414
                'required': True,
415
            },
416
            {
417
                'name': 'automatic_return_url',
418
                'caption': N_('Automatic return URL (ignored, must be set in Ogone backoffice)'),
419
                'required': False,
420
            },
410 421
            {'name': 'environment',
411 422
                'default': ENVIRONMENT_TEST,
412 423
                'caption': N_(u'Environnement'),
......
487 498
                'LANGUAGE': language,
488 499
                'CURRENCY': self.currency,
489 500
        }
501
        if self.normal_return_url:
502
            params['ACCEPTURL'] = self.normal_return_url
503
            params['BACKURL'] = self.normal_return_url
504
            params['CANCELURL'] = self.normal_return_url
505
            params['DECLINEURL'] = self.normal_return_url
506
            params['EXCEPTIONURL'] = self.normal_return_url
490 507
        if name:
491 508
            params['CN'] = name
492 509
        if email:
eopayment/paybox.py
14 14
import base64
15 15
from gettext import gettext as _
16 16
import string
17
import warnings
17 18

  
18 19
from common import (PaymentCommon, PaymentResponse, FORM, PAID, ERROR, Form,
19 20
        ORDERID_TRANSACTION_SEPARATOR)
......
127 128
    '''Paybox backend for eopayment.
128 129

  
129 130
       If you want to handle Instant Payment Notification, you must pass
130
       a callback parameter to the request() method specifying the URL of
131
       the callback endpoint.
131
       provide a automatic_return_url option specifying the URL of the
132
       callback endpoint.
132 133

  
133 134
       Email is mandatory to emit payment requests with paybox.
134 135

  
......
144 145
        'caption': _('Paybox'),
145 146
        'parameters': [
146 147
            {
148
                'name': 'normal_return_url',
149
                'caption': _('Normal return URL'),
150
                'default': '',
151
                'required': False,
152
            },
153
            {
154
                'name': 'automatic_return_url',
155
                'caption': _('Automatic return URL'),
156
                'required': False,
157
            },
158
            {
147 159
                'name': 'platform',
148 160
                'caption': _('Plateforme cible'),
149 161
                'default': 'test',
......
189 201
            {
190 202
                'name': 'callback',
191 203
                'caption': _('Callback URL'),
204
                'deprecated': True,
192 205
            },
193 206
        ]
194 207
    }
......
212 225
        d['PBX_HASH'] = 'SHA512'
213 226
        d['PBX_TIME'] = kwargs.get('time') or (unicode(datetime.datetime.utcnow().isoformat('T')).split('.')[0]+'+00:00')
214 227
        d['PBX_ARCHIVAGE'] = transaction_id
215
        if self.callback:
216
            d['PBX_REPONDRE_A'] = unicode(self.callback)
228
        if self.normal_return_url:
229
            d['PBX_EFFECTUE'] = self.normal_return_url
230
            d['PBX_REFUSE'] = self.normal_return_url
231
            d['PBX_ANNULE'] = self.normal_return_url
232
            d['PBX_ATTENTE'] = self.normal_return_url
233
        automatic_return_url = self.automatic_return_url
234
        if not automatic_return_url and self.callback:
235
            warnings.warn("callback option is deprecated, "
236
                          "use automatic_return_url", DeprecationWarning)
237
            automatic_return_url = self.callback
238
        if automatic_return_url:
239
            d['PBX_REPONDRE_A'] = unicode(automatic_return_url)
217 240
        d = d.items()
218 241
        d = sign(d, self.shared_secret.decode('hex'))
219 242
        url = URLS[self.platform]
eopayment/sips.py
7 7
import os
8 8
import os.path
9 9
import uuid
10
import warnings
10 11

  
11 12
from common import PaymentCommon, HTML, PaymentResponse
12 13
from cb import CB_RESPONSE_CODES
......
143 144
        params['amount'] = str(int(Decimal(amount) * 100))
144 145
        if email:
145 146
            params['customer_email'] = email
146
        if next_url:
147
            params['normal_return_url'] = next_url
147
        normal_return_url = self.normal_return_url
148
        if next_url and not normal_return_url:
149
            warnings.warn("passing next_url to request() is deprecated, "
150
                          "set normal_return_url in options", DeprecationWarning)
151
            normal_return_url = next_url
152
        if normal_return_url:
153
            params['normal_return_url'] = normal_return_url
148 154
        code, error, form = self.execute('request', params)
149 155
        if int(code) == 0:
150 156
            return params[ORDER_ID], HTML, form
eopayment/sips2.py
5 5
import uuid
6 6
import hashlib
7 7
from gettext import gettext as _
8
import warnings
8 9

  
9 10
from common import PaymentCommon, FORM, Form, PaymentResponse, PAID, ERROR, CANCELED
10 11

  
......
92 93
            {
93 94
                'name': 'normal_return_url',
94 95
                'caption': _('Normal return URL'),
95
                'default': 'http://www.example.com/',
96
                'default': '',
96 97
                'required': True,
97 98
            },
98 99
            {
......
129 130
        data['merchantId'] = self.merchand_id
130 131
        data['keyVersion'] = self.key_version
131 132
        data['normalReturnUrl'] = self.normal_return_url
133
        if self.automatic_return_url:
134
            date['automaticReturnUrl'] = self.automatic_return_url
132 135
        data['currencyCode'] = self.currency_code
133 136
        return data
134 137

  
......
144 147
        data['amount'] = unicode(int(Decimal(amount) * 100))
145 148
        if email:
146 149
            data['billingContact.email'] = email
147
        if next_url:
150
        normal_return_url = self.normal_return_url
151
        if next_url and not normal_return_url:
152
            warnings.warn("passing next_url to request() is deprecated, "
153
                          "set normal_return_url in options", DeprecationWarning)
154
            normal_return_url = next_url
155
        if normal_return_url:
148 156
            data['normalReturnUrl'] = next_url
149 157
        form = Form(
150 158
            url=self.get_url(),
eopayment/spplus.py
1 1
# -*- coding: utf-8 -*-
2 2
from decimal import Decimal
3 3
import binascii
4
from gettext import gettext as _
4 5
import hmac
5 6
import hashlib
6 7
import urlparse
......
9 10
import datetime as dt
10 11
import logging
11 12
import re
13
import warnings
12 14

  
13 15
import Crypto.Cipher.DES
14 16
from common import (PaymentCommon, URL, PaymentResponse, RECEIVED, ACCEPTED,
15 17
        PAID, ERROR)
16 18

  
19
def N_(message): return message
20

  
17 21
__all__ = ['Payment']
18 22

  
19 23
KEY_DES_KEY = '\x45\x1f\xba\x4f\x4c\x3f\xd4\x97'
......
92 96
    description = {
93 97
            'caption': "SPPlus payment service of French bank Caisse d'epargne",
94 98
            'parameters': [
99
                {
100
                    'name': 'normal_return_url',
101
                    'caption': N_('Normal return URL'),
102
                    'default': '',
103
                    'required': True,
104
                },
105
                {
106
                    'name': 'automatic_return_url',
107
                    'caption': N_('Automatic return URL'),
108
                    'required': False,
109
                },
95 110
                {   'name': 'cle',
96 111
                    'caption': 'Secret key, a 40 digits hexadecimal number',
97 112
                    'regexp': re.compile('^ *((?:[a-fA-F0-9] *){40}) *$')
......
125 140
    def request(self, amount, name=None, address=None, email=None, phone=None,
126 141
            orderid=None, info1=None, info2=None, info3=None, next_url=None,
127 142
            logger=LOGGER, **kwargs):
128
        logger.debug('requesting spplus payment with montant %s email=%s and \
129
next_url=%s' % (amount, email, next_url))
143
        logger.debug('requesting spplus payment with montant %s email=%s' % (amount, email))
130 144
        reference = self.transaction_id(20, ALPHANUM, 'spplus', self.siret)
131 145
        validite = dt.date.today()+dt.timedelta(days=1)
132 146
        validite = validite.strftime('%d/%m/%Y')
......
142 156
                'moyen': self.moyen }
143 157
        if email:
144 158
            fields['email'] = email
145
        if next_url:
146
            if (not next_url.startswith('http://') \
147
                    and not next_url.startswith('https://')) \
148
                       or '?' in next_url:
149
                   raise ValueError('next_url must be an absolute URL without parameters')
150
            fields['urlretour'] = next_url
159
        normal_return_url = self.normal_return_url
160
        if next_url and not normal_return_url:
161
            warnings.warn("passing next_url to request() is deprecated, "
162
                          "set normal_return_url in options", DeprecationWarning)
163
            normal_return_url = next_url
164
        if normal_return_url:
165
            if (not normal_return_url.startswith('http://') \
166
                    and not normal_return_url.startswith('https://')) \
167
                       or '?' in normal_return_url:
168
                   raise ValueError('normal_return_url must be an absolute URL without parameters')
169
            fields['urlretour'] = normal_return_url
151 170
        logger.debug('sending fields %s' % fields)
152 171
        query = urllib.urlencode(fields)
153 172
        url = '%s?%s&hmac=%s' % (SERVICE_URL, query, sign_url_paiement(self.cle,
eopayment/systempayv2.py
5 5
import logging
6 6
import string
7 7
import urlparse
8
import warnings
8 9
from gettext import gettext as _
9 10

  
10 11
from common import PaymentCommon, PaymentResponse, PAID, ERROR, FORM, Form
......
214 215
    description = {
215 216
        'caption': 'SystemPay, système de paiment du groupe BPCE',
216 217
        'parameters': [
218
            {
219
                'name': 'normal_return_url',
220
                'caption': _('Normal return URL'),
221
                'default': '',
222
                'required': True,
223
            },
224
            {
225
                'name': 'automatic_return_url',
226
                'caption': _('Automatic return URL (ignored, must be set in Payzen/SystemPay backoffice)'),
227
                'required': False,
228
            },
217 229
            {'name': 'service_url',
218 230
                'default': service_url,
219 231
                'caption': _(u'URL du service de paiment'),
......
266 278
        kwargs.update(add_vads({'amount': unicode(amount)}))
267 279
        if amount < 0:
268 280
            raise ValueError('amount must be an integer >= 0')
281
        normal_return_url = self.normal_return_url
269 282
        if next_url:
270
            kwargs[VADS_URL_RETURN] = unicode(next_url)
283
            warnings.warn("passing next_url to request() is deprecated, "
284
                          "set normal_return_url in options", DeprecationWarning)
285
            normal_return_url = next_url
286
        if normal_return_url:
287
            kwargs[VADS_URL_RETURN] = unicode(normal_return_url)
271 288
        if name is not None:
272 289
            kwargs['vads_cust_name'] = unicode(name)
273 290
        if address is not None:
eopayment/tipi.py
7 7
from urlparse import parse_qs
8 8
from gettext import gettext as _
9 9
import logging
10
import warnings
10 11

  
11 12
from systempayv2 import isonow
12 13

  
......
39 40
                    'help_text': _(u'ne pas modifier si vous ne savez pas'),
40 41
                    'validation': lambda x: x.startswith('http'),
41 42
                    'required': True,
42
                }
43
                },
44
                {
45
                    'name': 'normal_return_url',
46
                    'caption': _('Normal return URL (unused by TIPI)'),
47
                    'required': False,
48
                },
49
                {
50
                    'name': 'automatic_return_url',
51
                    'caption': _('Automatic return URL'),
52
                    'required': True,
53
                },
43 54
            ],
44 55
    }
45 56

  
......
61 72
                    'a decimal integer with less than 4 digits '
62 73
                    'before and 2 digits after the decimal point '
63 74
                    ', here it is %s' % repr(amount))
64
        if next_url is not None:
65
            if not isinstance(next_url, str) or \
66
                not next_url.startswith('http'):
75

  
76
        automatic_return_url = self.automatic_return_url
77
        if next_url and not automatic_return_url:
78
            warnings.warn("passing next_url to request() is deprecated, "
79
                          "set automatic_return_url in options", DeprecationWarning)
80
            automatic_return_url = next_url
81
        if automatic_return_url is not None:
82
            if not isinstance(automatic_return_url, str) or \
83
                not automatic_return_url.startswith('http'):
67 84
                raise ValueError('URLCL invalid URL format')
68 85
        try:
69 86
            if exer is not None:
......
117 134
        }
118 135
        if exer:
119 136
            params['exer'] = exer
120
        if next_url:
121
            params['urlcl'] = next_url
137
        if automatic_return_url:
138
            params['urlcl'] = automatic_return_url
122 139
        url = '%s?%s' % (self.service_url, urlencode(params))
123 140
        return transaction_id, URL, url
124 141

  
125
-