Projet

Général

Profil

0001-pass-order-id-to-all-backends-9941.patch

Serghei Mihai (congés, retour 15/05), 15 février 2016 18:07

Télécharger (12,9 ko)

Voir les différences:

Subject: [PATCH] pass order id to all backends (#9941)

 README.txt               |  9 +++++++++
 eopayment/common.py      |  3 +++
 eopayment/dummy.py       | 10 ++++------
 eopayment/ogone.py       | 14 ++++++++++++--
 eopayment/paybox.py      | 15 +++++++++++----
 eopayment/sips.py        |  7 ++++---
 eopayment/sips2.py       |  6 +++---
 eopayment/spplus.py      |  7 ++++---
 eopayment/systempayv2.py | 13 ++++++++++++-
 eopayment/tipi.py        |  5 +++--
 10 files changed, 65 insertions(+), 24 deletions(-)
README.txt
29 29
The spplus and paybox module also depend upon the python Crypto library for DES
30 30
decoding of the merchant key and RSA signature validation on the responses.
31 31

  
32
Some backends allow to specify the order and transaction ids in different
33
fields, in order to allow to match them in payment system backoffice. They are:
34
- Payzen
35
- SIPS
36
- SystemPay
37

  
38
For other backends, the order and transaction ids, separated by '!' are sent in
39
order id field, so they can be matched in backoffice.
40

  
32 41
Changelog
33 42
=========
34 43

  
eopayment/common.py
23 23
CANCELED = 5  # typo for backward compatibility
24 24
ERROR = 99
25 25

  
26
# separator between order and transaction ids
27
ORDERID_TRANSACTION_SEPARATOR = '!'
28

  
26 29

  
27 30
class PaymentResponse(object):
28 31
    '''Holds a generic view on the result of payment transaction response.
eopayment/dummy.py
72 72
    }
73 73

  
74 74
    def request(self, amount, name=None, address=None, email=None, phone=None,
75
            info1=None, info2=None, info3=None, next_url=None, **kwargs):
75
            orderid=None, info1=None, info2=None, info3=None, next_url=None, **kwargs):
76 76
        self.logger.debug('%s amount %s name %s address %s email %s phone %s'
77 77
                ' next_url %s info1 %s info2 %s info3 %s kwargs: %s',
78 78
                __name__, amount, name, address, email, phone, info1, info2, info3, next_url, kwargs)
......
89 89
                'origin': self.origin
90 90
        }
91 91
        query.update(dict(name=name, address=address, email=email, phone=phone,
92
            info1=info1, info2=info2, info3=info3))
92
            orderid=orderid, info1=info1, info2=info2, info3=info3))
93 93
        for key in query.keys():
94 94
            if query[key] is None:
95 95
                del query[key]
......
128 128
    p = Payment(options)
129 129
    retour = 'http://example.com/retour?amount=10.0&direct_notification_url=http%3A%2F%2Fexample.com%2Fdirect_notification_url&email=toto%40example.com&transaction_id=6Tfw2e1bPyYnz7CedZqvdHt7T9XX6T&return_url=http%3A%2F%2Fexample.com%2Fretour&nok=1'
130 130
    r = p.response(retour.split('?',1)[1])
131
    assert not r[0] 
131
    assert not r[0]
132 132
    assert r[1] == '6Tfw2e1bPyYnz7CedZqvdHt7T9XX6T'
133 133
    assert r[3] is None
134 134
    retour = 'http://example.com/retour?amount=10.0&direct_notification_url=http%3A%2F%2Fexample.com%2Fdirect_notification_url&email=toto%40example.com&transaction_id=6Tfw2e1bPyYnz7CedZqvdHt7T9XX6T&return_url=http%3A%2F%2Fexample.com%2Fretour&ok=1&signed=1'
135 135
    r = p.response(retour.split('?',1)[1])
136
    assert r[0] 
136
    assert r[0]
137 137
    assert r[1] == '6Tfw2e1bPyYnz7CedZqvdHt7T9XX6T'
138 138
    assert r[3] == 'signature ok'
139

  
140

  
eopayment/ogone.py
5 5
from decimal import Decimal, ROUND_HALF_UP
6 6

  
7 7
from common import (PaymentCommon, PaymentResponse, FORM, CANCELLED, PAID,
8
        ERROR, Form, DENIED, ACCEPTED)
8
        ERROR, Form, DENIED, ACCEPTED, ORDERID_TRANSACTION_SEPARATOR)
9 9
def N_(message): return message
10 10

  
11 11
ENVIRONMENT_TEST = 'TEST'
......
467 467

  
468 468
    def request(self, amount, orderid=None, name=None, email=None,
469 469
            language=None, description=None, **kwargs):
470
        reference = orderid or self.transaction_id(20, string.digits + string.ascii_letters)
470

  
471
        reference = self.transaction_id(20, string.digits + string.ascii_letters)
472

  
473
        # prepend order id in payment reference
474
        if orderid:
475
            if len(orderid) > 24:
476
                raise ValueError('orderid length exceed 25 characters')
477
            reference = orderid + ORDERID_TRANSACTION_SEPARATOR + self.transaction_id(29-len(orderid), string.digits + string.ascii_letters)
471 478
        language = language or self.language
472 479
        # convertir en centimes
473 480
        amount = Decimal(amount) * 100
......
527 534
            self.logger.error('response STATUS=%s NCERROR=%s NCERRORPLUS=%s',
528 535
                    status, error, params.get('NCERRORPLUS', ''))
529 536
            result = ERROR
537
        # extract reference from received order id
538
        if ORDERID_TRANSACTION_SEPARATOR in reference:
539
            reference, transaction_id = reference.split(ORDERID_TRANSACTION_SEPARATOR, 1)
530 540
        return PaymentResponse(
531 541
                result=result,
532 542
                signed=signed,
eopayment/paybox.py
15 15
from gettext import gettext as _
16 16
import string
17 17

  
18
from common import PaymentCommon, PaymentResponse, FORM, PAID, ERROR, Form
18
from common import (PaymentCommon, PaymentResponse, FORM, PAID, ERROR, Form,
19
        ORDERID_TRANSACTION_SEPARATOR)
19 20

  
20 21
__all__ = ['sign', 'Payment']
21 22

  
......
192 193
        ]
193 194
    }
194 195

  
195
    def request(self, amount, email, name=None, **kwargs):
196
    def request(self, amount, email, name=None, orderid=None, **kwargs):
196 197
        d = OrderedDict()
197 198
        d['PBX_SITE'] = unicode(self.site)
198 199
        d['PBX_RANG'] = unicode(self.rang).strip()[-2:]
......
203 204
            self.transaction_id(12, string.digits, 'paybox', self.site,
204 205
                                self.rang, self.identifiant)
205 206
        d['PBX_CMD'] = unicode(transaction_id)
207
        # prepend order id command reference
208
        if orderid:
209
            d['PBX_CMD'] = orderid + ORDERID_TRANSACTION_SEPARATOR + d['PBX_CMD']
206 210
        d['PBX_PORTEUR'] = unicode(email)
207 211
        d['PBX_RETOUR'] = 'montant:M;reference:R;code_autorisation:A;erreur:E;signature:K'
208 212
        d['PBX_HASH'] = 'SHA512'
......
252 256
            bank_status = PAYBOX_ERROR_CODES.get(prefix + suffix)
253 257
            if bank_status is not None:
254 258
                break
255

  
259
        orderid = d['reference'][0]
260
        # decode order id from returned reference
261
        if ORDERID_TRANSACTION_SEPARATOR in orderid:
262
            orderid, transaction_id = orderid.split(ORDERID_TRANSACTION_SEPARATOR, 1)
256 263
        return PaymentResponse(
257
            order_id=d['reference'][0],
264
            order_id=orderid,
258 265
            signed=signed,
259 266
            bank_data=d,
260 267
            result=result,
eopayment/sips.py
132 132
        params.update(self.options)
133 133
        return params
134 134

  
135
    def request(self, amount, name=None, address=None, email=None, phone=None, info1=None,
136
            info2=None, info3=None, next_url=None, **kwargs):
135
    def request(self, amount, name=None, address=None, email=None, phone=None, orderid=None,
136
            info1=None, info2=None, info3=None, next_url=None, **kwargs):
137 137
        params = self.get_request_params()
138 138
        transaction_id = self.transaction_id(6, string.digits, 'sips',
139 139
                params[MERCHANT_ID])
140 140
        params[TRANSACTION_ID] = transaction_id
141
        params[ORDER_ID] = str(uuid.uuid4()).replace('-', '')
141
        params[ORDER_ID] = orderid or str(uuid.uuid4())
142
        params[ORDER_ID] = params[ORDER_ID].replace('-', '')
142 143
        params['amount'] = str(int(Decimal(amount) * 100))
143 144
        if email:
144 145
            params['customer_email'] = email
eopayment/sips2.py
135 135
    def get_url(self):
136 136
        return self.URL[self.platform]
137 137

  
138
    def request(self, amount, name=None, address=None, email=None, phone=None, info1=None,
139
                info2=None, info3=None, next_url=None, **kwargs):
138
    def request(self, amount, name=None, address=None, email=None, phone=None,
139
                orderid=None, info1=None, info2=None, info3=None, next_url=None, **kwargs):
140 140
        data = self.get_data()
141 141
        transaction_id = self.transaction_id(6, string.digits, 'sips2', data['merchantId'])
142 142
        data['transactionReference'] = unicode(transaction_id)
143
        data['orderId'] = unicode(uuid.uuid4()).replace('-', '')
143
        data['orderId'] = orderid or unicode(uuid.uuid4()).replace('-', '')
144 144
        data['amount'] = unicode(int(Decimal(amount) * 100))
145 145
        if email:
146 146
            data['billingContact.email'] = email
eopayment/spplus.py
122 122
    }
123 123
    devise = '978'
124 124

  
125
    def request(self, amount, name=None, address=None, email=None, phone=None, info1=None,
126
            info2=None, info3=None, next_url=None, logger=LOGGER, **kwargs):
125
    def request(self, amount, name=None, address=None, email=None, phone=None,
126
            orderid=None, info1=None, info2=None, info3=None, next_url=None,
127
            logger=LOGGER, **kwargs):
127 128
        logger.debug('requesting spplus payment with montant %s email=%s and \
128 129
next_url=%s' % (amount, email, next_url))
129 130
        reference = self.transaction_id(20, ALPHANUM, 'spplus', self.siret)
......
134 135
                'langue': self.langue,
135 136
                'taxe': self.taxe,
136 137
                'montant': str(Decimal(amount)),
137
                REFERENCE: reference,
138
                REFERENCE: orderid or reference,
138 139
                'validite': validite,
139 140
                'version': '1',
140 141
                'modalite': self.modalite,
eopayment/systempayv2.py
252 252
        self.logger = logger or logging.getLogger(__name__)
253 253

  
254 254
    def request(self, amount, name=None, address=None, email=None, phone=None,
255
                info1=None, info2=None, info3=None, next_url=None, **kwargs):
255
                orderid=None, info1=None, info2=None, info3=None,
256
                next_url=None, **kwargs):
256 257
        '''
257 258
           Create the URL string to send a request to SystemPay
258 259
        '''
......
281 282
            kwargs['vads_order_info2'] = unicode(info2)
282 283
        if info3 is not None:
283 284
            kwargs['vads_order_info3'] = unicode(info3)
285
        if orderid is not None:
286
            # check orderid format first
287
            name = 'vads_order_id'
288
            orderid = unicode(orderid)
289
            ptype = 'an-'
290
            p = Parameter(name, ptype, 13, max_length=32)
291
            if not p.check_value(orderid):
292
                raise ValueError('%s value %s is not of the type %s' % (name,
293
                                orderid, ptype))
294
            kwargs[name] = orderid
284 295

  
285 296
        transaction_id = self.transaction_id(6, string.digits, 'systempay',
286 297
                                             self.options[VADS_SITE_ID])
eopayment/tipi.py
48 48
        self.numcli = options.pop('numcli', '')
49 49
        self.logger = logger
50 50

  
51
    def request(self, amount, next_url=None, exer=None, refdet=None,
52
            objet=None, email=None, saisie=None, **kwargs):
51
    def request(self, amount, next_url=None, exer=None, orderid=None,
52
            refdet=None, objet=None, email=None, saisie=None, **kwargs):
53 53
        try:
54 54
            montant = Decimal(amount)
55 55
            if Decimal('0') > montant > Decimal('9999.99'):
......
73 73
        except ValueError:
74 74
            raise ValueError('EXER format invalide')
75 75
        try:
76
            refdet = orderid or refdet
76 77
            refdet = str(refdet)
77 78
            if 6 > len(refdet) > 30:
78 79
                raise ValueError('len(REFDET) < 6 or > 30')
79
-