mangopay4-python-sdk 3.54.0__tar.gz → 3.55.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/PKG-INFO +1 -1
  2. mangopay4_python_sdk-3.55.0/README.md +127 -0
  3. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/mangopay/__init__.py +2 -0
  4. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/mangopay/api.py +21 -12
  5. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/mangopay/fields.py +20 -1
  6. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/mangopay/resources.py +8 -1
  7. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/mangopay/utils.py +14 -0
  8. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/mangopay4_python_sdk.egg-info/PKG-INFO +1 -1
  9. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/setup.py +1 -1
  10. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_base.py +62 -40
  11. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_cards.py +1 -0
  12. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_conversion.py +1 -1
  13. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_deposits.py +1 -0
  14. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_payins.py +15 -10
  15. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_payouts.py +1 -0
  16. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_preauthorizations.py +2 -1
  17. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_users.py +2 -1
  18. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_wallets.py +3 -1
  19. mangopay4_python_sdk-3.54.0/README.md +0 -53
  20. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/DESCRIPTION.md +0 -0
  21. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/LICENSE +0 -0
  22. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/MANIFEST.in +0 -0
  23. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/Makefile +0 -0
  24. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/mangopay/auth.py +0 -0
  25. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/mangopay/base.py +0 -0
  26. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/mangopay/compat.py +0 -0
  27. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/mangopay/constants.py +0 -0
  28. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/mangopay/exceptions.py +0 -0
  29. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/mangopay/page.py +0 -0
  30. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/mangopay/query.py +0 -0
  31. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/mangopay/ratelimit.py +0 -0
  32. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/mangopay/signals.py +0 -0
  33. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/mangopay4_python_sdk.egg-info/SOURCES.txt +0 -0
  34. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/mangopay4_python_sdk.egg-info/dependency_links.txt +0 -0
  35. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/mangopay4_python_sdk.egg-info/entry_points.txt +0 -0
  36. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/mangopay4_python_sdk.egg-info/requires.txt +0 -0
  37. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/mangopay4_python_sdk.egg-info/top_level.txt +0 -0
  38. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/setup.cfg +0 -0
  39. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/__init__.py +0 -0
  40. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/card.json +0 -0
  41. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/cardregistrations.json +0 -0
  42. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/cardregistrations_update.json +0 -0
  43. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/declarative_user.json +0 -0
  44. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/legal_user.json +0 -0
  45. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/legal_user_wallet.json +0 -0
  46. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/legal_user_wallet_89.json +0 -0
  47. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/legal_user_wallet_99.json +0 -0
  48. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/list_ubo_declarations.json +0 -0
  49. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/natural_user.json +0 -0
  50. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/natural_user_wallet.json +0 -0
  51. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/natural_user_wallet_9.json +0 -0
  52. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/ubo.json +0 -0
  53. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/ubo_declaration.json +0 -0
  54. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/ubo_declaration_submit.json +0 -0
  55. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/ubo_update.json +0 -0
  56. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/user_list_2_per_page.json +0 -0
  57. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/user_list_2_per_page_page1.json +0 -0
  58. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/user_list_3_per_page_page2.json +0 -0
  59. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/user_list_full.json +0 -0
  60. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/user_list_page1.json +0 -0
  61. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/fixtures/user_wallet.json +0 -0
  62. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/images/image.jpg +0 -0
  63. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/mocks.py +0 -0
  64. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/resources/TestKycPageFile.png +0 -0
  65. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/resources/settlement_sample.csv +0 -0
  66. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/resources/settlement_sample_bad.csv +0 -0
  67. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/resources.py +0 -0
  68. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/settings.py +0 -0
  69. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_bankaccounts.py +0 -0
  70. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_banking_aliases.py +0 -0
  71. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_client_wallets.py +0 -0
  72. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_clients.py +0 -0
  73. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_country_authorizations.py +0 -0
  74. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_disputes.py +0 -0
  75. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_documentconsult.py +0 -0
  76. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_emoney.py +0 -0
  77. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_idempotency.py +0 -0
  78. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_identity_verification.py +0 -0
  79. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_kyc_document.py +0 -0
  80. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_kycs.py +0 -0
  81. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_mandates.py +0 -0
  82. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_notifications.py +0 -0
  83. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_rate_limit.py +0 -0
  84. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_recipients.py +0 -0
  85. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_refunds.py +0 -0
  86. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_reports.py +0 -0
  87. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_reports_v2.py +0 -0
  88. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_repudiations.py +0 -0
  89. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_settlements.py +0 -0
  90. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_tokens.py +0 -0
  91. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_transactions.py +0 -0
  92. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_transfers.py +0 -0
  93. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_ubos.py +0 -0
  94. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_utils.py +0 -0
  95. {mangopay4_python_sdk-3.54.0 → mangopay4_python_sdk-3.55.0}/tests/test_virtual_account.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mangopay4-python-sdk
3
- Version: 3.54.0
3
+ Version: 3.55.0
4
4
  Summary: A client library written in python to work with mangopay v2 api
5
5
  Home-page: https://github.com/Mangopay/mangopay2-python-sdk
6
6
  Author: Mangopay (www.mangopay.com)
@@ -0,0 +1,127 @@
1
+ Mangopay Python SDK
2
+ =================================================
3
+
4
+ MangopaySDK is a Python client library to work with
5
+ [Mangopay REST API](http://docs.mangopay.com/api-references/).
6
+
7
+
8
+ Installation
9
+ ------------
10
+
11
+ mangopaysdk requires:
12
+
13
+ * [requests](https://pypi.python.org/pypi/requests)
14
+ * [blinker](https://pypi.python.org/pypi/blinker)
15
+
16
+ To install the package:
17
+
18
+ ```
19
+ pip install mangopay4-python-sdk
20
+ ```
21
+
22
+ By installing this package with [pip](https://pypi.python.org/pypi/pip), all dependencies will be installed for you.
23
+
24
+
25
+ Documentation
26
+ -------------
27
+
28
+ For documentation and examples of usage for the Mangopay API please refer to: [API references](https://docs.mangopay.com/api-references/)
29
+
30
+ See [docs](https://github.com/Mangopay/mangopay2-python-sdk/blob/master/docs/usage.rst) to find examples.
31
+
32
+ mTLS certificates
33
+ -----------------
34
+
35
+ ### Set the base URL for mTLS
36
+
37
+ Using mTLS authentication requires your integration to call a base URL with a different hostname from the standard API:
38
+
39
+ * Sandbox: `https://api-mtls.sandbox.mangopay.com`
40
+ * Production: `https://api-mtls.mangopay.com`
41
+
42
+ If using mTLS, your integration should use the `api-mtls` URLs for all API calls, including OAuth token generation.
43
+
44
+ **Caution:** Ensure you set the mTLS base URL, as shown in the configuration examples below. If you don’t, the mTLS certificate will not be transferred to Mangopay. When mTLS is enforced, your integration will result in an error.
45
+
46
+ ### Configure the SDK’s mTLS properties
47
+
48
+ The Python SDK allows you to load the `.pem` and `.key` file paths in the global configuration or in the per-request handler.
49
+
50
+ | Property (global / per-request) | Type | Description |
51
+ | ------------------------------- | ------ | ------------------------------------ |
52
+ | `mtls_cert` / `cert` | string | Path to the certificate `.pem` file. |
53
+ | `mtls_private_key` / `key` | string | Path to the private `.key` file. |
54
+
55
+ **Caution:** The per-request properties `cert` and `key` take precedence if set and the global ones are ignored (`mangopay.mtls_cert` and `mangopay.mtls_private_key`).
56
+
57
+ The certificate files must be accessible at runtime; the SDK does not validate their content at initialization time.
58
+
59
+ When both are provided, the SDK sets `session.cert = (cert, key)` on the underlying `requests.Session`. If a combined certificate is provided (bundling the key), the SDK sets `session.cert = cert`.
60
+
61
+ #### Global configuration
62
+
63
+ The global properties allow you to set the certificate and key before making any API calls. The certificate is used for all requests made through the default handler.
64
+
65
+ ```python theme={null}
66
+ import mangopay
67
+
68
+ mangopay.client_id = 'your-mangopay-client-id'
69
+ mangopay.apikey = 'your-mangopay-api-key'
70
+ mangopay.api_sandbox_url = 'https://api-mtls.sandbox.mangopay.com/v2.01/'
71
+ sandbox = True
72
+ # mangopay.api_url = 'https://api-mtls.mangopay.com/v2.01/'
73
+ mangopay.mtls_cert = '/path/to/certificate.pem'
74
+ mangopay.mtls_private_key = '/path/to/private.key'
75
+ ```
76
+
77
+ #### Per-request handler
78
+
79
+ **Caution:** The per-request values take precedence over the global values.
80
+
81
+ Each `APIRequest` instance maintains its own `requests.Session`, so mTLS certificates are scoped to that instance and do not leak between handlers.
82
+
83
+ ```python theme={null}
84
+ from mangopay.api import APIRequest
85
+
86
+ handler = APIRequest(
87
+ client_id='your-mangopay-client-id',
88
+ apikey='your-mangopay-api-key',
89
+ api_sandbox_url = 'https://api-mtls.sandbox.mangopay.com/v2.01/' # mTlS base URL
90
+ sandbox = True
91
+ # mangopay.api_url = 'https://api-mtls.mangopay.com/v2.01/'
92
+ cert='/path/to/certificate.pem',
93
+ key='/path/to/private.key'
94
+ )
95
+ ```
96
+
97
+ Then pass the handler when making API calls:
98
+
99
+ ```python theme={null}
100
+ from mangopay.resources import NaturalUser, Wallet
101
+
102
+ user = NaturalUser.get(user_id, handler=handler)
103
+ wallet = Wallet.get(wallet_id, handler=handler)
104
+ ```
105
+
106
+ License
107
+ -------------------------------------------------
108
+ MangopaySDK is distributed under MIT license, see LICENSE file.
109
+
110
+ Contact
111
+ -------------------------------------------------
112
+ Report bugs or suggest features using [issue tracker at GitHub](https://github.com/Mangopay/mangopay2-python-sdk/issues).
113
+
114
+
115
+ Account creation
116
+ -------------------------------------------------
117
+ You can get yourself a free sandbox account or sign up for a production account by [registering on the Mangopay site](https://www.mangopay.com/start/) (note that validation of your production account involves several steps, so think about doing it in advance of when you actually want to go live).
118
+
119
+ Inspiration
120
+ -----------
121
+
122
+ The data model of python-mangopay is highly inspired by [peewee](https://github.com/coleifer/peewee).
123
+
124
+ Credits
125
+ -----------
126
+
127
+ The inital basis of this SDK was generously coded and donated by [Ulule](https://www.ulule.com/)
@@ -6,6 +6,8 @@ temp_dir = None
6
6
  api_version = 2.01
7
7
  sandbox = True
8
8
  uk_header_flag = False
9
+ mtls_cert = None # Path to client certificate file for mTLS
10
+ mtls_private_key = None # Path to client private key file for mTLS
9
11
 
10
12
  package_version = None
11
13
  try:
@@ -30,14 +30,14 @@ except ImportError:
30
30
 
31
31
  logger = logging.getLogger('mangopay')
32
32
 
33
- requests_session = requests.Session()
34
33
  rate_limits = None
35
34
 
36
35
 
37
36
  class APIRequest(object):
38
37
 
39
38
  def __init__(self, client_id=None, apikey=None, api_url=None, api_sandbox_url=None, sandbox=None,
40
- timeout=30.0, storage_strategy=None, proxies=None, uk_header_flag=False):
39
+ timeout=30.0, storage_strategy=None, proxies=None, uk_header_flag=False,
40
+ cert=None, key=None):
41
41
  global rate_limits
42
42
  rate_limits = None
43
43
  if (sandbox is None and mangopay.sandbox) or sandbox:
@@ -52,6 +52,15 @@ class APIRequest(object):
52
52
  self.proxies = proxies
53
53
  self.uk_header_flag = uk_header_flag or mangopay.uk_header_flag
54
54
 
55
+ self._session = requests.Session()
56
+
57
+ _cert = cert or mangopay.mtls_cert
58
+ _key = key or mangopay.mtls_private_key
59
+ if _cert and _key:
60
+ self._session.cert = (_cert, _key)
61
+ elif _cert:
62
+ self._session.cert = _cert
63
+
55
64
  def set_rate_limit(self, rate_limit):
56
65
  global rate_limits
57
66
  rate_limits = rate_limit
@@ -124,11 +133,11 @@ class APIRequest(object):
124
133
  request_started.send(url=url, data=data, headers=headers, method=method)
125
134
 
126
135
  try:
127
- result = requests_session.request(method, url,
128
- data=data,
129
- headers=headers,
130
- timeout=self.timeout,
131
- proxies=self.proxies)
136
+ result = self._session.request(method, url,
137
+ data=data,
138
+ headers=headers,
139
+ timeout=self.timeout,
140
+ proxies=self.proxies)
132
141
  except ConnectionError as e:
133
142
  msg = '{}'.format(e)
134
143
 
@@ -225,11 +234,11 @@ class APIRequest(object):
225
234
  request_started.send(url=url, data=None, headers=headers, method=method)
226
235
 
227
236
  try:
228
- result = requests_session.request(method, url,
229
- files=files,
230
- headers=headers,
231
- timeout=self.timeout,
232
- proxies=self.proxies)
237
+ result = self._session.request(method, url,
238
+ files=files,
239
+ headers=headers,
240
+ timeout=self.timeout,
241
+ proxies=self.proxies)
233
242
  except ConnectionError as e:
234
243
  msg = f'{type(e).__name__}: {e}' if str(e) else type(e).__name__
235
244
  reraise_as(APIError(msg))
@@ -15,7 +15,7 @@ from .utils import timestamp_from_datetime, timestamp_from_date, Money, DebitedB
15
15
  BusinessRecipient, RecipientPropertySchema, IndividualRecipientPropertySchema, BusinessRecipientPropertySchema, \
16
16
  CompanyNumberValidation, ReportFilter, PayInIntentExternalData, PayInIntentBuyer, SupportedBank, \
17
17
  VerificationOfPayee, PayInIntentRefund, PayInIntentCapture, PayInIntentDispute, CustomFees, MarginsResponse, \
18
- UserMargin, ConsentScope
18
+ UserMargin, ConsentScope, AuthenticationResult
19
19
 
20
20
 
21
21
  class FieldDescriptor(object):
@@ -1502,3 +1502,22 @@ class ConsentScopeField(Field):
1502
1502
  return result
1503
1503
 
1504
1504
  return value
1505
+
1506
+
1507
+ class AuthenticationResultField(Field):
1508
+ def python_value(self, value):
1509
+ if value is not None:
1510
+ return AuthenticationResult(authentication_type=value.get('AuthenticationType', None))
1511
+
1512
+ return value
1513
+
1514
+ def api_value(self, value):
1515
+ value = super(AuthenticationResultField, self).api_value(value)
1516
+
1517
+ if isinstance(value, AuthenticationResult):
1518
+ result = {}
1519
+ if value.authentication_type is not None:
1520
+ result['AuthenticationType'] = value.authentication_type
1521
+ return result
1522
+
1523
+ return value
@@ -21,7 +21,7 @@ from .fields import (PrimaryKeyField, EmailField, CharField,
21
21
  BusinessRecipientPropertySchemaField, CompanyNumberValidationField, ReportFilterField,
22
22
  PayInIntentExternalDataField, PayInIntentBuyerField, SupportedBanksField, VerificationOfPayeeField,
23
23
  PayInIntentRefundField, PayInIntentCaptureField, PayInIntentDisputeField, CustomFeesField,
24
- UserMarginField, MarginsResponseField, ConsentScopeField)
24
+ UserMarginField, MarginsResponseField, ConsentScopeField, AuthenticationResultField)
25
25
  from .query import InsertQuery, UpdateQuery, SelectQuery, ActionQuery, DeleteQuery
26
26
 
27
27
 
@@ -746,6 +746,7 @@ class CardValidation(BaseModel):
746
746
  authorization_date = DateTimeField(api_name='AuthorizationDate')
747
747
  card_info = CardInfoField(api_name='CardInfo')
748
748
  payment_category = CharField(api_name='PaymentCategory')
749
+ authentication_result = AuthenticationResultField(api_name='AuthenticationResult')
749
750
 
750
751
  def validate(self, card_id, **kwargs):
751
752
  insert = InsertQuery(self, **kwargs)
@@ -861,6 +862,7 @@ class PayIn(BaseModel):
861
862
  payment_type = CharField(api_name='PaymentType', choices=constants.PAYIN_PAYMENT_TYPE, default=None)
862
863
  execution_type = CharField(api_name='ExecutionType', choices=constants.EXECUTION_TYPE_CHOICES, default=None)
863
864
  profiling_attempt_reference = CharField(api_name='ProfilingAttemptReference')
865
+ authentication_result = AuthenticationResultField(api_name='AuthenticationResult')
864
866
 
865
867
  def get_refunds(self, *args, **kwargs):
866
868
  kwargs['id'] = self.id
@@ -983,6 +985,7 @@ class RecurringPayInCIT(PayIn):
983
985
  security_info = SecurityInfoField(api_name='SecurityInfo')
984
986
  shipping = ShippingField(api_name='Shipping')
985
987
  card_info = CardInfoField(api_name='CardInfo')
988
+ payment_category = CharField(api_name='PaymentCategory')
986
989
 
987
990
  def get_read_only_properties(self):
988
991
  read_only = ["AuthorId", "Applied3DSVersion", "CardId", "CreationDate", "Culture", "SecureModeNeeded"
@@ -1020,6 +1023,7 @@ class RecurringPayInMIT(PayIn):
1020
1023
  security_info = SecurityInfoField(api_name='SecurityInfo')
1021
1024
  shipping = ShippingField(api_name='Shipping')
1022
1025
  card_info = CardInfoField(api_name='CardInfo')
1026
+ payment_category = CharField(api_name='PaymentCategory')
1023
1027
 
1024
1028
  def get_read_only_properties(self):
1025
1029
  read_only = ["AuthorId", "Applied3DSVersion", "CardId", "CreationDate", "Culture", "SecureModeNeeded"
@@ -1774,6 +1778,7 @@ class PreAuthorization(BaseModel):
1774
1778
  applied_3ds_version = CharField(api_name='Applied3DSVersion')
1775
1779
  card_info = CardInfoField(api_name='CardInfo')
1776
1780
  payment_category = CharField(api_name='PaymentCategory')
1781
+ authentication_result = AuthenticationResultField(api_name='AuthenticationResult')
1777
1782
 
1778
1783
  def get_transactions(self, *args, **kwargs):
1779
1784
  kwargs['id'] = self.id
@@ -1998,6 +2003,7 @@ class BankWirePayOut(BaseModel):
1998
2003
  fallback_reason = FallbackReasonField(api_name='FallbackReason')
1999
2004
  recipient_verification_of_payee = VerificationOfPayeeField(api_name='RecipientVerificationOfPayee')
2000
2005
  recipient = ForeignKeyField(Recipient, api_name='RecipientId')
2006
+ charge_bearer = CharField(api_name='ChargeBearer')
2001
2007
 
2002
2008
  def get_refunds(self, *args, **kwargs):
2003
2009
  kwargs['id'] = self.id
@@ -2855,6 +2861,7 @@ class Deposit(BaseModel):
2855
2861
  shipping = ShippingField(api_name='Shipping')
2856
2862
  requested_3ds_version = CharField(api_name='Requested3DSVersion')
2857
2863
  applied_3ds_version = CharField(api_name='Applied3DSVersion')
2864
+ authentication_result = AuthenticationResultField(api_name='AuthenticationResult')
2858
2865
 
2859
2866
  class Meta:
2860
2867
  verbose_name = 'deposit'
@@ -1721,3 +1721,17 @@ class PayInIntentDispute(object):
1721
1721
  return {
1722
1722
  "Id": self.id
1723
1723
  }
1724
+
1725
+
1726
+ @add_camelcase_aliases
1727
+ class AuthenticationResult(object):
1728
+ def __init__(self, authentication_type=None):
1729
+ self.authentication_type = authentication_type
1730
+
1731
+ def __str__(self):
1732
+ return 'AuthenticationResult: %s' % self.authentication_type
1733
+
1734
+ def to_api_json(self):
1735
+ return {
1736
+ "AuthenticationType": self.authentication_type
1737
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mangopay4-python-sdk
3
- Version: 3.54.0
3
+ Version: 3.55.0
4
4
  Summary: A client library written in python to work with mangopay v2 api
5
5
  Home-page: https://github.com/Mangopay/mangopay2-python-sdk
6
6
  Author: Mangopay (www.mangopay.com)
@@ -10,7 +10,7 @@ with open(path.join(here, 'DESCRIPTION.md'), encoding='utf-8') as f:
10
10
 
11
11
  setup(
12
12
  name='mangopay4-python-sdk',
13
- version='3.54.0',
13
+ version='3.55.0',
14
14
  description='A client library written in python to work with mangopay v2 api',
15
15
  long_description='This SDK is a client library for interacting with the Mangopay API.',
16
16
  url='https://github.com/Mangopay/mangopay2-python-sdk',
@@ -342,29 +342,38 @@ class BaseTestLive(unittest.TestCase):
342
342
  postal_code='11222', country='FR')
343
343
  return user
344
344
 
345
+ @staticmethod
346
+ def get_user_legal_sca_owner_instance(bypass_sca=True):
347
+ user = LegalUserSca()
348
+ user.name = 'Alex Smith'
349
+ user.email = 'alex.smith.services@example.com'
350
+ user.legal_person_type = "SOLETRADER"
351
+ user.terms_and_conditions_accepted = True
352
+ if bypass_sca:
353
+ email = 'alex.smith.services+accept@example.com'
354
+ else:
355
+ email = 'alex.smith.services@example.com'
356
+ user.legal_representative = LegalRepresentative(first_name='Alex', last_name='Smith',
357
+ email=email,
358
+ phone_number='0611111111',
359
+ phone_number_country='FR',
360
+ birthday=652117514,
361
+ nationality='FR',
362
+ country_of_residence='FR')
363
+ user.headquarters_address = Address(address_line_1='AddressLine1', address_line_2='AddressLine2',
364
+ city='City', region='Region',
365
+ postal_code='11222', country='FR')
366
+ user.legal_representative_address = Address(address_line_1='AddressLine1', address_line_2='AddressLine2',
367
+ city='City', region='Region',
368
+ postal_code='11222', country='FR')
369
+ user.company_number = '123456789'
370
+ user.user_category = 'OWNER'
371
+ return user
372
+
345
373
  @staticmethod
346
374
  def get_user_legal_sca_owner(recreate=False):
347
375
  if BaseTestLive._user_legal_sca_owner is None or recreate:
348
- user = LegalUserSca()
349
- user.name = 'Alex Smith'
350
- user.email = 'alex.smith.services@example.com'
351
- user.legal_person_type = "SOLETRADER"
352
- user.terms_and_conditions_accepted = True
353
- user.legal_representative = LegalRepresentative(first_name='Alex', last_name='Smith',
354
- email='alex.smith.services@example.com',
355
- phone_number='0611111111',
356
- phone_number_country='FR',
357
- birthday=652117514,
358
- nationality='FR',
359
- country_of_residence='FR')
360
- user.headquarters_address = Address(address_line_1='AddressLine1', address_line_2='AddressLine2',
361
- city='City', region='Region',
362
- postal_code='11222', country='FR')
363
- user.legal_representative_address = Address(address_line_1='AddressLine1', address_line_2='AddressLine2',
364
- city='City', region='Region',
365
- postal_code='11222', country='FR')
366
- user.company_number = '123456789'
367
- user.user_category = 'OWNER'
376
+ user = BaseTestLive.get_user_legal_sca_owner_instance(False)
368
377
  BaseTestLive._user_legal_sca_owner = LegalUserSca(**user.save())
369
378
  return BaseTestLive._user_legal_sca_owner
370
379
 
@@ -453,12 +462,15 @@ class BaseTestLive(unittest.TestCase):
453
462
  return BaseTestLive._john
454
463
 
455
464
  @staticmethod
456
- def get_john_instance():
465
+ def get_john_instance(bypass_sca=True):
457
466
  user = NaturalUser()
458
467
  user.first_name = 'John'
459
468
  user.last_name = 'Doe'
460
469
  user.birthday = 188352000
461
- user.email = "john.doe@sample.org"
470
+ if bypass_sca:
471
+ user.email = "john.doe+accept@sample.org"
472
+ else:
473
+ user.email = "john.doe@sample.org"
462
474
  user.address = Address(address_line_1='AddressLine1', address_line_2='AddressLine2',
463
475
  city='City', region='Region',
464
476
  postal_code='11222', country='FR')
@@ -493,25 +505,33 @@ class BaseTestLive(unittest.TestCase):
493
505
  postal_code='11222', country='FR')
494
506
  return user
495
507
 
508
+ @staticmethod
509
+ def get_john_sca_owner_instance(bypass_sca=True):
510
+ user = NaturalUserSca()
511
+ user.first_name = 'John SCA'
512
+ user.last_name = 'Doe SCA Review'
513
+ user.birthday = 188352000
514
+ if bypass_sca:
515
+ user.email = "john.doe.sca+accept@sample.org"
516
+ else:
517
+ user.email = "john.doe.sca@sample.org"
518
+ user.address = Address(address_line_1='AddressLine1', address_line_2='AddressLine2',
519
+ city='City', region='Region',
520
+ postal_code='11222', country='FR')
521
+ user.nationality = 'FR'
522
+ user.country_of_residence = 'FR'
523
+ user.occupation = 'programmer'
524
+ user.income_range = '1'
525
+ user.terms_and_conditions_accepted = True
526
+ user.user_category = 'OWNER'
527
+ user.phone_number = '+33611111111'
528
+ user.phone_number_country = 'FR'
529
+ return user
530
+
496
531
  @staticmethod
497
532
  def get_john_sca_owner(recreate=False):
498
533
  if BaseTestLive._john_sca_owner is None or recreate:
499
- user = NaturalUserSca()
500
- user.first_name = 'John SCA'
501
- user.last_name = 'Doe SCA Review'
502
- user.birthday = 188352000
503
- user.email = "john.doe.sca@sample.org"
504
- user.address = Address(address_line_1='AddressLine1', address_line_2='AddressLine2',
505
- city='City', region='Region',
506
- postal_code='11222', country='FR')
507
- user.nationality = 'FR'
508
- user.country_of_residence = 'FR'
509
- user.occupation = 'programmer'
510
- user.income_range = '1'
511
- user.terms_and_conditions_accepted = True
512
- user.user_category = 'OWNER'
513
- user.phone_number = '+33611111111'
514
- user.phone_number_country = 'FR'
534
+ user = BaseTestLive.get_john_sca_owner_instance(False)
515
535
  BaseTestLive._john_sca_owner = NaturalUserSca(**user.save())
516
536
  return BaseTestLive._john_sca_owner
517
537
 
@@ -605,8 +625,10 @@ class BaseTestLive(unittest.TestCase):
605
625
 
606
626
  @staticmethod
607
627
  def get_johns_transfer_sca(sca_context, amount):
608
- valid_john_sca_id = 'user_m_01JRG5WE99JYRCEBHZ8EKBRE8Y'
609
- valid_matrix_sca_id = 'user_m_01JRG4ZWZ85RNZDKKTSFRMG6ZW'
628
+ john_sca_dto = BaseTestLive.get_john_sca_owner_instance(True)
629
+ matrix_sca_dto = BaseTestLive.get_user_legal_sca_owner_instance(True)
630
+ valid_john_sca_id = NaturalUserSca(**john_sca_dto.save()).id
631
+ valid_matrix_sca_id = LegalUserSca(**matrix_sca_dto.save()).id
610
632
  john_sca = NaturalUserSca.get(valid_john_sca_id)
611
633
  matrix_sca = LegalUserSca.get(valid_matrix_sca_id)
612
634
 
@@ -317,6 +317,7 @@ class CardsLiveTest(BaseTestLive):
317
317
  self.assertIsNotNone(validation_response)
318
318
  self.assertIsNotNone(validation_response['id'])
319
319
  self.assertEqual('TelephoneOrder', validation_response['payment_category'])
320
+ self.assertIsNotNone(validation_response['authentication_result'])
320
321
 
321
322
  def test_getCardValidation(self):
322
323
  user = BaseTestLive.get_john()
@@ -1,5 +1,5 @@
1
1
  from mangopay.resources import ConversionQuote, QuotedConversion, InstantConversion, ClientWalletsQuotedConversion, \
2
- ClientWalletsInstantConversion
2
+ ClientWalletsInstantConversion, NaturalUser
3
3
  from mangopay.utils import Money, CustomFees, UserMargin
4
4
  from tests.resources import ConversionRate, Conversion, Wallet
5
5
  from tests.test_base import BaseTestLive
@@ -11,6 +11,7 @@ class DepositsTest(BaseTestLive):
11
11
  def test_create(self):
12
12
  deposit = self.create_new_deposit()
13
13
  self.assertIsNotNone(deposit)
14
+ self.assertIsNotNone(deposit.authentication_result)
14
15
 
15
16
  def test_get(self):
16
17
  deposit = self.create_new_deposit()
@@ -902,6 +902,7 @@ class PayInsTestLive(BaseTestLive):
902
902
  self.assertIsNotNone(security_info)
903
903
  self.assertIsInstance(security_info, SecurityInfo)
904
904
  self.assertEqual(security_info.avs_result, "NO_CHECK")
905
+ self.assertIsNotNone(result['authentication_result'])
905
906
 
906
907
  def test_RecurringPayment(self):
907
908
  user = self.get_john(True)
@@ -934,7 +935,6 @@ class PayInsTestLive(BaseTestLive):
934
935
 
935
936
  created_recurring = RecurringPayInRegistration.get(result.get('id'))
936
937
  self.assertIsNotNone(created_recurring)
937
- print(created_recurring.id)
938
938
  cit = RecurringPayInCIT()
939
939
  cit.recurring_payin_registration_id = created_recurring.id
940
940
  cit.tag = "custom meta"
@@ -947,11 +947,13 @@ class PayInsTestLive(BaseTestLive):
947
947
 
948
948
  created_cit = cit.save()
949
949
  self.assertIsNotNone(created_cit)
950
- cit_id = created_cit.get('id')
950
+ self.assertIsNotNone(created_cit['payment_category'])
951
951
 
952
+ cit_id = created_cit.get('id')
952
953
  got_cit = RecurringPayInCIT.get(cit_id)
953
954
  self.assertIsNotNone(got_cit)
954
955
  self.assertIsInstance(got_cit, RecurringPayInCIT)
956
+ self.assertIsNotNone(got_cit.payment_category)
955
957
 
956
958
  mit = RecurringPayInMIT()
957
959
  mit.recurring_payin_registration_id = created_recurring.id
@@ -961,10 +963,13 @@ class PayInsTestLive(BaseTestLive):
961
963
  mit.fees = Money(1, "EUR")
962
964
  created_mit = mit.save()
963
965
  self.assertIsNotNone(created_mit)
966
+ self.assertIsNotNone(created_mit['payment_category'])
964
967
 
965
- got_cit = RecurringPayInCIT.get(cit_id)
966
- self.assertIsNotNone(got_cit)
967
- # self.assertIsInstance(got_cit, RecurringPayInCIT)
968
+ mit_id = created_mit.get('id')
969
+ got_mit = RecurringPayInMIT.get(mit_id)
970
+ self.assertIsNotNone(got_mit)
971
+ self.assertIsInstance(got_mit, RecurringPayInMIT)
972
+ self.assertIsNotNone(got_mit.payment_category)
968
973
 
969
974
  params = {
970
975
  "author": user,
@@ -979,11 +984,6 @@ class PayInsTestLive(BaseTestLive):
979
984
  self.assertIsInstance(payin_refund, PayInRefund)
980
985
  self.assertEqual(payin_refund.status, 'SUCCEEDED')
981
986
 
982
- mit_id = created_mit.get('id')
983
- got_mit = RecurringPayInMIT.get(mit_id)
984
- self.assertIsNotNone(got_mit)
985
- self.assertIsInstance(got_mit, RecurringPayInMIT)
986
-
987
987
  params = {
988
988
  "author": user,
989
989
  "payin": got_mit
@@ -997,6 +997,9 @@ class PayInsTestLive(BaseTestLive):
997
997
  self.assertIsInstance(payin_refund_mit, PayInRefund)
998
998
  self.assertEqual(payin_refund_mit.status, 'SUCCEEDED')
999
999
 
1000
+ self.assertIsNotNone(created_cit['authentication_result'])
1001
+ self.assertIsNotNone(created_mit['authentication_result'])
1002
+
1000
1003
  def test_RecurringPayment_Get(self):
1001
1004
  user = self.get_john(True)
1002
1005
  wallet = self.get_johns_wallet(True)
@@ -2225,6 +2228,7 @@ class PayInsTestLive(BaseTestLive):
2225
2228
  self.assertIsNotNone(mit_card_info)
2226
2229
  self.assertIsInstance(mit_card_info, CardInfo)
2227
2230
 
2231
+ @unittest.skip("Endpoint removed")
2228
2232
  def test_PayIns_Payconiq_Web_Create(self):
2229
2233
  user = BaseTestLive.get_john(True)
2230
2234
 
@@ -2528,6 +2532,7 @@ class PayInsTestLive(BaseTestLive):
2528
2532
  self.assertIsNotNone(extended)
2529
2533
  self.assertEqual('CARD', extended.payment_type)
2530
2534
  self.assertEqual('WEB', extended.execution_type)
2535
+ self.assertIsNotNone(payin.authentication_result)
2531
2536
 
2532
2537
  def test_create_full_pay_in_intent_dispute(self):
2533
2538
  full_capture = BaseTestLive.create_new_pay_in_intent_full_capture()
@@ -215,6 +215,7 @@ class PayOutsTestLive(BaseTestLive):
215
215
  def test_PayOut_GetRefunds(self):
216
216
  payout = BaseTestLive.get_johns_payout()
217
217
  self.assertIsNotNone(payout.recipient_verification_of_payee)
218
+ self.assertIsNotNone(payout.charge_bearer)
218
219
 
219
220
  refunds = payout.get_refunds()
220
221
 
@@ -847,4 +847,5 @@ class PreAuthorizationsTestLive(BaseTestLive):
847
847
  card_info = saved_pre_authorization['card_info']
848
848
  self.assertIsNotNone(card_info)
849
849
  self.assertIsInstance(card_info, CardInfo)
850
- self.assertEqual('TelephoneOrder', saved_pre_authorization['payment_category'])
850
+ self.assertEqual('TelephoneOrder', saved_pre_authorization['payment_category'])
851
+ self.assertIsNotNone(saved_pre_authorization['authentication_result'])
@@ -955,7 +955,8 @@ class PayInsTestLive(BaseTestLive):
955
955
  self.assertEqual('CLOSED', closed.user_status)
956
956
 
957
957
  def test_users_GetTransactionsSca(self):
958
- user = BaseTestLive.get_john()
958
+ user_dto = BaseTestLive.get_john_instance(False)
959
+ user = NaturalUser(**user_dto.save())
959
960
  with self.assertRaises(APIError):
960
961
  Transaction.all(**{"user_id": user.id, "ScaContext": 'USER_PRESENT'})
961
962
  try:
@@ -337,7 +337,9 @@ class WalletsTestLive(BaseTestLive):
337
337
  self.assertEqual(wallet.id, fetched.id)
338
338
 
339
339
  def test_Wallets_getSca(self):
340
- wallet = BaseTestLive.get_johns_wallet()
340
+ user_dto = BaseTestLive.get_john_instance(False)
341
+ user = NaturalUser(**user_dto.save())
342
+ wallet = BaseTestLive.create_new_wallet(user)
341
343
  with self.assertRaises(APIError):
342
344
  Wallet.get(wallet.id, ScaContext='USER_PRESENT')
343
345
  try:
@@ -1,53 +0,0 @@
1
- Mangopay Python SDK
2
- =================================================
3
-
4
- MangopaySDK is a Python client library to work with
5
- [Mangopay REST API](http://docs.mangopay.com/api-references/).
6
-
7
-
8
- Installation
9
- ------------
10
-
11
- mangopaysdk requires:
12
-
13
- * [requests](https://pypi.python.org/pypi/requests)
14
- * [blinker](https://pypi.python.org/pypi/blinker)
15
-
16
- To install the package:
17
-
18
- ```
19
- pip install mangopay4-python-sdk
20
- ```
21
-
22
- By installing this package with [pip](https://pypi.python.org/pypi/pip), all dependencies will be installed for you.
23
-
24
-
25
- Documentation
26
- -------------
27
-
28
- For documentation and examples of usage for the Mangopay API please refer to: [API references](https://docs.mangopay.com/api-references/)
29
-
30
- See [docs](https://github.com/Mangopay/mangopay2-python-sdk/blob/master/docs/usage.rst) to find examples.
31
-
32
- License
33
- -------------------------------------------------
34
- MangopaySDK is distributed under MIT license, see LICENSE file.
35
-
36
- Contact
37
- -------------------------------------------------
38
- Report bugs or suggest features using [issue tracker at GitHub](https://github.com/Mangopay/mangopay2-python-sdk/issues).
39
-
40
-
41
- Account creation
42
- -------------------------------------------------
43
- You can get yourself a free sandbox account or sign up for a production account by [registering on the Mangopay site](https://www.mangopay.com/start/) (note that validation of your production account involves several steps, so think about doing it in advance of when you actually want to go live).
44
-
45
- Inspiration
46
- -----------
47
-
48
- The data model of python-mangopay is highly inspired by [peewee](https://github.com/coleifer/peewee).
49
-
50
- Credits
51
- -----------
52
-
53
- The inital basis of this SDK was generously coded and donated by [Ulule](https://www.ulule.com/)