0002-systempayv2-allow-arbitrary-date-for-deferred-paymen.patch
eopayment/__init__.py | ||
---|---|---|
104 | 104 |
''' |
105 | 105 |
logger.debug(u'%r' % kwargs) |
106 | 106 |
for param in kwargs: |
107 |
# encode all input params to unicode |
|
108 |
kwargs[param] = force_text(kwargs[param]) |
|
107 |
if param != 'capture_date': |
|
108 |
# encode all input params to unicode |
|
109 |
kwargs[param] = force_text(kwargs[param]) |
|
109 | 110 |
return self.backend.request(amount, **kwargs) |
110 | 111 | |
111 | 112 |
def response(self, query_string, **kwargs): |
eopayment/systempayv2.py | ||
---|---|---|
4 | 4 |
import hashlib |
5 | 5 |
import logging |
6 | 6 |
import string |
7 |
import pytz |
|
7 | 8 |
from six.moves.urllib import parse as urlparse |
8 | 9 |
import warnings |
9 | 10 |
from gettext import gettext as _ |
... | ... | |
266 | 267 | |
267 | 268 |
def request(self, amount, name=None, first_name=None, last_name=None, |
268 | 269 |
address=None, email=None, phone=None, orderid=None, info1=None, |
269 |
info2=None, info3=None, next_url=None, **kwargs): |
|
270 |
info2=None, info3=None, next_url=None, capture_date=None, **kwargs):
|
|
270 | 271 |
''' |
271 | 272 |
Create the URL string to send a request to SystemPay |
272 | 273 |
''' |
273 | 274 |
self.logger.debug('%s amount %s name %s address %s email %s phone %s ' |
274 |
'next_url %s info1 %s info2 %s info3 %s kwargs: %s', |
|
275 |
'next_url %s info1 %s info2 %s info3 %s capture_date %s kwargs: %s',
|
|
275 | 276 |
__name__, amount, name, address, email, phone, info1, |
276 |
info2, info3, next_url, kwargs) |
|
277 |
info2, info3, next_url, capture_date, kwargs)
|
|
277 | 278 |
# amount unit is cents |
278 | 279 |
amount = '%.0f' % (100 * amount) |
279 | 280 |
kwargs.update(add_vads({'amount': force_text(amount)})) |
... | ... | |
332 | 333 |
fields[name] = parameter.default() |
333 | 334 |
else: |
334 | 335 |
fields[name] = parameter.default |
336 | ||
337 |
if capture_date: |
|
338 |
if not isinstance(capture_date, dt.date): |
|
339 |
raise ValueError('capture_date should be a date object.') |
|
340 | ||
341 |
paris_tz = pytz.timezone('Europe/Paris') |
|
342 |
utc_tz = pytz.timezone('Etc/UTC') |
|
343 |
paris_trans_date = utc_tz.localize( |
|
344 |
dt.datetime.strptime(fields[VADS_TRANS_DATE], "%Y%m%d%H%M%S") |
|
345 |
).astimezone(paris_tz) |
|
346 |
vads_capture_delay = ( |
|
347 |
capture_date - paris_trans_date.date() |
|
348 |
).days |
|
349 |
if vads_capture_delay <= 0: |
|
350 |
raise ValueError("capture_date needs to be superior to the transaction date") |
|
351 |
fields['vads_capture_delay'] = force_text(vads_capture_delay) |
|
352 | ||
335 | 353 |
check_vads(fields) |
336 | 354 |
fields[SIGNATURE] = force_text(self.signature(fields)) |
337 | 355 |
self.logger.debug('%s request contains fields: %s', __name__, fields) |
tests/test_base_payment.py | ||
---|---|---|
1 |
from datetime import datetime |
|
2 |
import mock |
|
3 | ||
4 | ||
5 |
def test_cature_date_not_forced_to_unicode(monkeypatch): |
|
6 |
mock_backend = mock.Mock() |
|
7 | ||
8 |
def get_backend(*args, **kwargs): |
|
9 |
def backend(*args, **kwargs): |
|
10 |
return mock_backend |
|
11 |
return backend |
|
12 | ||
13 |
import eopayment |
|
14 |
monkeypatch.setattr(eopayment, 'get_backend', get_backend) |
|
15 |
now = datetime.now() |
|
16 |
payement = eopayment.Payment('kind', None) |
|
17 |
payement.request(12, capture_date=now) |
|
18 |
mock_backend.request.assert_called_with(12, capture_date=now) |
tests/test_systempayv2.py | ||
---|---|---|
1 | 1 |
# -*- coding: utf-8 -*- |
2 | 2 | |
3 |
from datetime import datetime, date, timedelta |
|
3 | 4 |
import pytest |
4 | 5 |
from six.moves.urllib import parse as urlparse |
5 | 6 | |
... | ... | |
14 | 15 |
'vads_trans_date': u'20090501193530', |
15 | 16 |
} |
16 | 17 | |
18 | ||
19 |
def get_field(form, field_name): |
|
20 |
for field in form.fields: |
|
21 |
if field['name'] == field_name: |
|
22 |
return field |
|
23 | ||
24 | ||
17 | 25 |
def test_systempayv2(): |
18 | 26 |
p = Payment(PARAMS) |
19 | 27 |
data = {'amount': 15.24, 'orderid': '654321', |
... | ... | |
49 | 57 |
# bad response |
50 | 58 |
with pytest.raises(ResponseError, match='missing signature, vads_ctx_mode or vads_auth_result'): |
51 | 59 |
p.response('foo=bar') |
60 | ||
61 | ||
62 |
def test_systempayv2_deferred_payment(): |
|
63 |
default_params = { |
|
64 |
'secret_test': u'1122334455667788', |
|
65 |
'vads_site_id': u'12345678', |
|
66 |
'vads_ctx_mode': u'TEST', |
|
67 |
} |
|
68 |
default_data = { |
|
69 |
'amount': 15.24, 'orderid': '654321', 'first_name': u'John', |
|
70 |
'last_name': u'Doe' |
|
71 |
} |
|
72 |
p = Payment(default_params.copy()) |
|
73 |
data = default_data.copy() |
|
74 |
data['capture_date'] = (datetime.now().date() + timedelta(days=3)) |
|
75 |
transaction_id, f, form = p.request(**data) |
|
76 |
assert get_field(form, 'vads_capture_delay')['value'] == '3' |
|
77 | ||
78 |
# default vads_capture_delay used if no capture date |
|
79 |
params = default_params.copy() |
|
80 |
params['vads_capture_delay'] = 1 |
|
81 |
p = Payment(params) |
|
82 |
transaction_id, f, form = p.request(**default_data.copy()) |
|
83 |
assert get_field(form, 'vads_capture_delay')['value'] == '1' |
|
84 | ||
85 |
# capture date override vads_capture_delay |
|
86 |
params = default_params.copy() |
|
87 |
params['vads_capture_delay'] = 1 |
|
88 |
p = Payment(params) |
|
89 |
data = default_data.copy() |
|
90 |
data['capture_date'] = (datetime.now().date() + timedelta(days=3)) |
|
91 |
transaction_id, f, form = p.request(**data) |
|
92 |
assert get_field(form, 'vads_capture_delay')['value'] == '3' |
|
93 | ||
94 |
# capture date can't be inferior to the transaction date |
|
95 |
params = default_params.copy() |
|
96 |
params['vads_trans_date'] = (datetime.utcnow() + timedelta(days=3)).strftime("%Y%m%d%H%M%S") |
|
97 |
p = Payment(params) |
|
98 |
data = default_data.copy() |
|
99 |
data['capture_date'] = (datetime.now().date()) |
|
100 | ||
101 |
with pytest.raises( |
|
102 |
ValueError, match='capture_date needs to be superior to the transaction date'): |
|
103 |
transaction_id, f, form = p.request(**data) |
|
104 | ||
105 |
# capture date should have the right format |
|
106 |
p = Payment(params) |
|
107 |
data = default_data.copy() |
|
108 |
data['capture_date'] = 'not a date' |
|
109 |
with pytest.raises( |
|
110 |
ValueError, match='capture_date should be a date object.'): |
|
111 |
transaction_id, f, form = p.request(**data) |
|
112 | ||
113 | ||
114 |
@pytest.mark.freeze_time('2018-10-02 23:50:00') |
|
115 |
def test_paris_timezone(): |
|
116 |
params = { |
|
117 |
'secret_test': u'1122334455667788', |
|
118 |
'vads_site_id': u'12345678', |
|
119 |
'vads_ctx_mode': u'TEST', |
|
120 |
} |
|
121 |
data = { |
|
122 |
'amount': 15.24, 'orderid': '654321', 'first_name': u'John', |
|
123 |
'last_name': u'Doe', 'capture_date': date(year=2018, month=10, day=3), |
|
124 |
} |
|
125 | ||
126 |
p = Payment(params) |
|
127 |
with pytest.raises( |
|
128 |
ValueError, match='capture_date needs to be superior to the transaction date'): |
|
129 |
# utcnow will return 2018-10-02 23:50:00, |
|
130 |
# converted to Europe/Paris is already 2018-10-03 ... |
|
131 |
# so 2018-10-03 for capture_date is invalid |
|
132 |
transaction_id, f, form = p.request(**data) |
tox.ini | ||
---|---|---|
16 | 16 |
usedevelop = True |
17 | 17 |
deps = coverage |
18 | 18 |
pytest |
19 |
pytest-freezegun |
|
19 | 20 |
py2: pytest-cov |
20 | 21 |
mock |
21 |
- |