Projet

Général

Profil

0001-standardise-normal_return_url-and-automatic_return_u.patch

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

Télécharger (20,3 ko)

Voir les différences:

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

 eopayment/__init__.py    |  4 +---
 eopayment/dummy.py       | 52 ++++++++++++++++++++++++++++++++++--------------
 eopayment/ogone.py       | 17 ++++++++++++++++
 eopayment/paybox.py      | 31 +++++++++++++++++++++++++----
 eopayment/sips.py        |  9 +++++++--
 eopayment/sips2.py       | 12 +++++++++--
 eopayment/spplus.py      | 32 +++++++++++++++++++++--------
 eopayment/systempayv2.py | 19 +++++++++++++++++-
 eopayment/tipi.py        | 29 +++++++++++++++++++++------
 9 files changed, 164 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
4 5

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

  
......
77 91
                ' next_url %s info1 %s info2 %s info3 %s kwargs: %s',
78 92
                __name__, amount, name, address, email, phone, info1, info2, info3, next_url, kwargs)
79 93
        transaction_id = self.transaction_id(30, ALPHANUM, 'dummy', self.siret)
80
        if self.next_url:
81
            next_url = self.next_url
94
        normal_return_url = self.normal_return_url
95
        if next_url and not normal_return_url:
96
            warnings.warn("passing next_url to request() is deprecated, "
97
                          "set normal_return_url in options", DeprecationWarning)
98
            normal_return_url = next_url
99
        automatic_return_url = self.automatic_return_url
100
        if self.direct_notification_url and not automatic_return_url:
101
            warnings.warn("direct_notification_url option is deprecated, "
102
                          "use automatic_return_url", DeprecationWarning)
103
            automatic_return_url = self.direct_notification_url
82 104
        query = {
83 105
                'transaction_id': transaction_id,
84 106
                'siret': self.siret,
85 107
                'amount': amount,
86 108
                'email': email,
87
                'return_url': next_url or '',
88
                'direct_notification_url': self.direct_notification_url,
109
                'return_url': normal_return_url or '',
110
                'direct_notification_url': automatic_return_url or '',
89 111
                'origin': self.origin
90 112
        }
91 113
        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': _('Normal return URL'),
413
                'default': '',
414
                'required': True,
415
            },
416
            {
417
                'name': 'automatic_return_url',
418
                'caption': _('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'),
......
480 491
                'LANGUAGE': language,
481 492
                'CURRENCY': self.currency,
482 493
        }
494
        if self.normal_return_url:
495
            params['ACCEPTURL'] = self.normal_return_url
496
            params['BACKURL'] = self.normal_return_url
497
            params['CANCELURL'] = self.normal_return_url
498
            params['DECLINEURL'] = self.normal_return_url
499
            params['EXCEPTIONURL'] = self.normal_return_url
483 500
        if name:
484 501
            params['CN'] = name
485 502
        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

  
......
126 127
    '''Paybox backend for eopayment.
127 128

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

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

  
......
143 144
        'caption': _('Paybox'),
144 145
        'parameters': [
145 146
            {
147
                'name': 'normal_return_url',
148
                'caption': _('Normal return URL'),
149
                'default': '',
150
                'required': False,
151
            },
152
            {
153
                'name': 'automatic_return_url',
154
                'caption': _('Automatic return URL'),
155
                'required': False,
156
            },
157
            {
146 158
                'name': 'platform',
147 159
                'caption': _('Plateforme cible'),
148 160
                'default': 'test',
......
188 200
            {
189 201
                'name': 'callback',
190 202
                'caption': _('Callback URL'),
203
                'deprecated': True,
191 204
            },
192 205
        ]
193 206
    }
......
208 221
        d['PBX_HASH'] = 'SHA512'
209 222
        d['PBX_TIME'] = kwargs.get('time') or (unicode(datetime.datetime.utcnow().isoformat('T')).split('.')[0]+'+00:00')
210 223
        d['PBX_ARCHIVAGE'] = transaction_id
211
        if self.callback:
212
            d['PBX_REPONDRE_A'] = unicode(self.callback)
224
        if self.normal_return_url:
225
            d['PBX_EFFECTUE'] = self.normal_return_url
226
            d['PBX_REFUSE'] = self.normal_return_url
227
            d['PBX_ANNULE'] = self.normal_return_url
228
            d['PBX_ATTENTE'] = self.normal_return_url
229
        automatic_return_url = self.automatic_return_url
230
        if not automatic_return_url and self.callback:
231
            warnings.warn("callback option is deprecated, "
232
                          "use automatic_return_url", DeprecationWarning)
233
            automatic_return_url = self.callback
234
        if automatic_return_url:
235
            d['PBX_REPONDRE_A'] = unicode(automatic_return_url)
213 236
        d = d.items()
214 237
        d = sign(d, self.shared_secret.decode('hex'))
215 238
        url = URLS[self.platform]
eopayment/sips.py
142 142
        params['amount'] = str(int(Decimal(amount) * 100))
143 143
        if email:
144 144
            params['customer_email'] = email
145
        if next_url:
146
            params['normal_return_url'] = next_url
145
        normal_return_url = self.normal_return_url
146
        if next_url and not normal_return_url:
147
            warnings.warn("passing next_url to request() is deprecated, "
148
                          "set normal_return_url in options", DeprecationWarning)
149
            normal_return_url = next_url
150
        if normal_return_url:
151
            params['normal_return_url'] = normal_return_url
147 152
        code, error, form = self.execute('request', params)
148 153
        if int(code) == 0:
149 154
            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
......
92 93
    description = {
93 94
            'caption': "SPPlus payment service of French bank Caisse d'epargne",
94 95
            'parameters': [
96
                {
97
                    'name': 'normal_return_url',
98
                    'caption': _('Normal return URL'),
99
                    'default': '',
100
                    'required': True,
101
                },
102
                {
103
                    'name': 'automatic_return_url',
104
                    'caption': _('Automatic return URL'),
105
                    'required': False,
106
                },
95 107
                {   'name': 'cle',
96 108
                    'caption': 'Secret key, a 40 digits hexadecimal number',
97 109
                    'regexp': re.compile('^ *((?:[a-fA-F0-9] *){40}) *$')
......
124 136

  
125 137
    def request(self, amount, name=None, address=None, email=None, phone=None, info1=None,
126 138
            info2=None, info3=None, next_url=None, logger=LOGGER, **kwargs):
127
        logger.debug('requesting spplus payment with montant %s email=%s and \
128
next_url=%s' % (amount, email, next_url))
139
        logger.debug('requesting spplus payment with montant %s email=%s' % (amount, email))
129 140
        reference = self.transaction_id(20, ALPHANUM, 'spplus', self.siret)
130 141
        validite = dt.date.today()+dt.timedelta(days=1)
131 142
        validite = validite.strftime('%d/%m/%Y')
......
141 152
                'moyen': self.moyen }
142 153
        if email:
143 154
            fields['email'] = email
144
        if next_url:
145
            if (not next_url.startswith('http://') \
146
                    and not next_url.startswith('https://')) \
147
                       or '?' in next_url:
148
                   raise ValueError('next_url must be an absolute URL without parameters')
149
            fields['urlretour'] = next_url
155
        normal_return_url = self.normal_return_url
156
        if next_url and not normal_return_url:
157
            warnings.warn("passing next_url to request() is deprecated, "
158
                          "set normal_return_url in options", DeprecationWarning)
159
            normal_return_url = next_url
160
        if normal_return_url:
161
            if (not normal_return_url.startswith('http://') \
162
                    and not normal_return_url.startswith('https://')) \
163
                       or '?' in normal_return_url:
164
                   raise ValueError('normal_return_url must be an absolute URL without parameters')
165
            fields['urlretour'] = normal_return_url
150 166
        logger.debug('sending fields %s' % fields)
151 167
        query = urllib.urlencode(fields)
152 168
        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'),
......
265 277
        kwargs.update(add_vads({'amount': unicode(amount)}))
266 278
        if amount < 0:
267 279
            raise ValueError('amount must be an integer >= 0')
280
        normal_return_url = self.normal_return_url
268 281
        if next_url:
269
            kwargs[VADS_URL_RETURN] = unicode(next_url)
282
            warnings.warn("passing next_url to request() is deprecated, "
283
                          "set normal_return_url in options", DeprecationWarning)
284
            normal_return_url = next_url
285
        if normal_return_url:
286
            kwargs[VADS_URL_RETURN] = unicode(normal_return_url)
270 287
        if name is not None:
271 288
            kwargs['vads_cust_name'] = unicode(name)
272 289
        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:
......
116 133
        }
117 134
        if exer:
118 135
            params['exer'] = exer
119
        if next_url:
120
            params['urlcl'] = next_url
136
        if automatic_return_url:
137
            params['urlcl'] = automatic_return_url
121 138
        url = '%s?%s' % (self.service_url, urlencode(params))
122 139
        return transaction_id, URL, url
123 140

  
124
-