0001-pass-order-id-to-all-backends-9941.patch
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 |
reference = self.transaction_id(20, string.digits + string.ascii_letters) |
|
471 | ||
472 |
# prepend order id in payment reference |
|
473 |
if orderid: |
|
474 |
reference = orderid + ORDERID_TRANSACTION_SEPARATOR + reference |
|
471 | 475 |
language = language or self.language |
472 | 476 |
# convertir en centimes |
473 | 477 |
amount = Decimal(amount) * 100 |
... | ... | |
527 | 531 |
self.logger.error('response STATUS=%s NCERROR=%s NCERRORPLUS=%s', |
528 | 532 |
status, error, params.get('NCERRORPLUS', '')) |
529 | 533 |
result = ERROR |
534 |
# extract reference from received order id |
|
535 |
if ORDERID_TRANSACTION_SEPARATOR in reference: |
|
536 |
reference, transaction_id = reference.split(ORDERID_TRANSACTION_SEPARATOR, 1) |
|
530 | 537 |
return PaymentResponse( |
531 | 538 |
result=result, |
532 | 539 |
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()).replace('-', '')
|
|
142 | 142 |
params['amount'] = str(int(Decimal(amount) * 100)) |
143 | 143 |
if email: |
144 | 144 |
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 |
kwargs['vads_order_id'] = unicode(orderid) |
|
284 | 287 | |
285 | 288 |
transaction_id = self.transaction_id(6, string.digits, 'systempay', |
286 | 289 |
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 |
- |