python-redsys 2.1.0__py3-none-any.whl → 2.2.0__py3-none-any.whl

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.
@@ -1,225 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: python-redsys
3
- Version: 2.1.0
4
- Summary: A simple, lightweight client to handle payments through the RedSys platform.
5
- Author-email: David Díaz <d.diazp@gmail.com>
6
- License-Expression: Apache-2.0
7
- Project-URL: Homepage, https://github.com/ddiazpinto/python-redsys
8
- Project-URL: Source, https://github.com/ddiazpinto/python-redsys
9
- Keywords: redsys,sermepa,tpv,payments,psd2
10
- Classifier: Intended Audience :: Developers
11
- Classifier: Operating System :: OS Independent
12
- Classifier: Programming Language :: Python :: 3
13
- Classifier: Programming Language :: Python :: 3.10
14
- Classifier: Programming Language :: Python :: 3.11
15
- Classifier: Programming Language :: Python :: 3.12
16
- Classifier: Programming Language :: Python :: 3.13
17
- Classifier: Programming Language :: Python :: 3.14
18
- Classifier: Programming Language :: Python :: 3.15
19
- Classifier: Topic :: Office/Business :: Financial
20
- Requires-Python: >=3.10
21
- Description-Content-Type: text/markdown
22
- License-File: LICENSE
23
- License-File: NOTICE
24
- Requires-Dist: cryptography>=49
25
- Requires-Dist: pydantic>=2.13
26
- Provides-Extra: http
27
- Requires-Dist: httpx>=0.26; extra == "http"
28
- Dynamic: license-file
29
-
30
- # Welcome to python-redsys!
31
-
32
- [![CI](https://github.com/ddiazpinto/python-redsys/actions/workflows/ci.yml/badge.svg)](https://github.com/ddiazpinto/python-redsys/actions/workflows/ci.yml) [![Coverage](https://codecov.io/gh/ddiazpinto/python-redsys/branch/master/graph/badge.svg)](https://codecov.io/gh/ddiazpinto/python-redsys) [![PyPI](https://img.shields.io/pypi/v/python-redsys.svg)](https://pypi.org/project/python-redsys/) ![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg) [![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0)
33
-
34
- A simple, lightweight client to handle payments through the RedSys platform, covering both connection types it defines: *redirect connection* (browser form POST) and *direct connection* (server-to-server REST).
35
-
36
- The library builds the signed request and verifies and parses the response. The redirect form is submitted by the cardholder's browser; the direct REST call is made by the integrator's HTTP client or by the optional `http` extra (`httpx`).
37
-
38
- For Django, see [django-redsys](https://github.com/ddiazpinto/django-redsys).
39
-
40
- ## Installation
41
-
42
- ```bash
43
- pip install python-redsys
44
-
45
- # optional: the direct-connection sender (httpx)
46
- pip install "python-redsys[http]"
47
- ```
48
-
49
- Requires Python 3.10+. Runtime dependencies: `cryptography` and `pydantic` (v2).
50
-
51
- ## Status
52
-
53
- | | |
54
- |---|---|
55
- | Version | 2.1.0; 1.x receives fixes until 2026-12-31 |
56
- | Python | 3.10 to 3.15 |
57
- | RedSys documents followed | Redirection guide 4.2 (2026-02-04), REST guide 4.0.1 (2025-10-17), Bizum guide 2.6 (2026-08-25) |
58
- | Signature versions | `HMAC_SHA512_V2` (default), `HMAC_SHA512_V1`, `HMAC_SHA256_V1` |
59
- | Verified against the RedSys test environment | Redirect connection in a browser, with the 3DS challenge, for all three signature versions (2026-10-25); direct connection end to end (3DS initialization, challenged payment, refund, stored-card token charged as a merchant-initiated payment) on demand by the *Live* workflow |
60
- | Not yet verified live | Frictionless 3DS and the 3DSMethod step |
61
-
62
- ## Upgrading from 1.x
63
-
64
- 2.0 has a new API. The [migration guide](docs/migration-1x-to-2x.md) lists every change; 1.x receives fixes until 2026-12-31.
65
-
66
- ## Usage
67
-
68
- The client is the single entry point: an operation method (`payment`, `preauthorization`, `confirmation`, `refund`, `cancellation`) returns a `Request`, with `.to_dict()` for the redirect POST fields and `.send()` for the direct REST call. Fields are validated on construction; `amount` is a `Decimal`. A parameter the library does not model yet is passed by its wire name (`Ds_Merchant_...`), sent as given, with an `UnknownParameterWarning`.
69
-
70
- ## Using *redirect connection*
71
-
72
- ### 1. Build a signed request
73
-
74
- ```python
75
- from decimal import Decimal, ROUND_HALF_UP
76
- from redsys import currencies
77
- from redsys.clients import RedirectClient
78
-
79
- client = RedirectClient(
80
- secret_key="123456789abcdef",
81
- merchant_code="100000001",
82
- terminal=1,
83
- sandbox=False,
84
- )
85
-
86
- post_parameters = client.payment(
87
- order="000000001",
88
- currency=currencies.EUR,
89
- # The amount is a Decimal; pre-quantize to two decimals.
90
- amount=Decimal("10.56489").quantize(Decimal(".01"), ROUND_HALF_UP),
91
- merchant_url="https://example.com/redsys/response",
92
- url_ok="https://example.com/ok",
93
- url_ko="https://example.com/ko",
94
- merchant_name="Example Commerce",
95
- product_description="Products of Example Commerce",
96
- ).to_dict() # Ds_SignatureVersion / Ds_MerchantParameters / Ds_Signature
97
- ```
98
-
99
- Bizum: add `pay_methods="z"` (and optionally `bizum_mobile_number`) to the payment.
100
-
101
- ### 2. Communication step
102
-
103
- Auto-submit an HTML form (`method="POST"`) to `client.endpoint` with the three `post_parameters` fields. RedSys notifies the result both as a server-to-server POST to `merchant_url` and as a browser redirect to `url_ok` / `url_ko`.
104
-
105
- ### 3. Verify and read the response
106
-
107
- `parse_response()` accepts the received parameters (callback form fields or REST JSON body) and raises `ValueError` on signature mismatch.
108
-
109
- ```python
110
- response = client.parse_response(received) # received: the Ds_* dict RedSys posted back
111
-
112
- if response.is_paid():
113
- ... # actions after a successful payment
114
- else:
115
- raise Exception(f"declined with code {response.response_code}")
116
- ```
117
-
118
- Response predicates (per the RedSys documentation):
119
-
120
- - `response.is_paid()`: response code between 0 and 99.
121
- - `response.is_canceled()`: response code 400.
122
- - `response.is_refunded()`: response code 900.
123
- - `response.is_authorized()`: paid, refunded or canceled.
124
-
125
- `response.response_code` is the raw RedSys code; meanings are listed in [`docs/response-codes.md`](docs/response-codes.md). Decoded fields (`response.order`, `response.amount` as a `Decimal`, ...) read off the model; parameters the library does not list are kept under their wire name in `response.model_extra`.
126
-
127
- ## Using *direct connection* (REST)
128
-
129
- The direct connection exchanges the same signed envelope server-to-server as JSON. Build the operation with the same methods: `.send()` performs the call, `.to_dict()` returns the JSON body for your own HTTP client.
130
-
131
- With the optional sender (`pip install "python-redsys[http]"`):
132
-
133
- ```python
134
- from decimal import Decimal
135
- from redsys import currencies
136
- from redsys.clients import DirectClient
137
-
138
- client = DirectClient(secret_key="123456789abcdef", merchant_code="100000001",
139
- terminal=1, sandbox=True)
140
-
141
- response = client.refund(
142
- order="000000001", amount=Decimal("10.56"), currency=currencies.EUR,
143
- ).send() # signs, POSTs, verifies, parses
144
- response.is_refunded()
145
- ```
146
-
147
- Asynchronous (`httpx.AsyncClient`), with `send()` awaitable:
148
-
149
- ```python
150
- from redsys.clients import AsyncDirectClient
151
-
152
- client = AsyncDirectClient(secret_key="123456789abcdef", merchant_code="100000001",
153
- terminal=1, sandbox=True)
154
- response = await client.payment(
155
- order="000000001", amount=Decimal("10.56"), currency=currencies.EUR,
156
- pan="...", expiry_date="2512", cvv2="...",
157
- ).send()
158
- ```
159
-
160
- Transport-agnostic (do your own HTTP):
161
-
162
- ```python
163
- body = client.refund(order="000000001", amount=Decimal("10.56"),
164
- currency=currencies.EUR).to_dict() # JSON body to POST
165
- # ... POST body to client.endpoint with your HTTP client ...
166
- response = client.parse_response(received_json) # verifies and parses
167
- ```
168
-
169
- `parse_response()` raises `redsys.exceptions.ResponseError` when RedSys answers with an error code instead of a signed result.
170
-
171
- ## inSite (hosted fields)
172
-
173
- inSite captures the card in the browser via RedSys's JavaScript and yields an `idoper` token, keeping the PAN off your server. The card-capture JS is the front-end's responsibility; the backend completes the operation as a direct payment carrying the token:
174
-
175
- ```python
176
- client.payment(order="000000001", amount=Decimal("10.56"), currency=currencies.EUR,
177
- idoper="<token from the inSite JS>").send()
178
- ```
179
-
180
- ## Tokenization and recurring (COF / MIT)
181
-
182
- Store a card on the first payment and charge it later without card data. The first payment requests a token and flags the credential-on-file intent; RedSys returns a token and a COF transaction id that subsequent merchant-initiated charges reuse.
183
-
184
- ```python
185
- from decimal import Decimal
186
- from redsys import cof, currencies, sca
187
- from redsys.clients import DirectClient
188
-
189
- client = DirectClient(secret_key="123456789abcdef", merchant_code="100000001",
190
- terminal=1, sandbox=True)
191
-
192
- # 1. First payment, request a token (cardholder present)
193
- response = client.payment(
194
- order="000000001", amount=Decimal("10.56"), currency=currencies.EUR,
195
- pan="...", expiry_date="YYMM", cvv2="...",
196
- identifier=cof.REQUEST_TOKEN, cof_ini=cof.INITIAL, cof_type=cof.RECURRING,
197
- ).send()
198
- token, cof_txnid = response.identifier, response.cof_txnid
199
-
200
- # 2. Later merchant-initiated charge, no card data
201
- client.payment(
202
- order="000000002", amount=Decimal("10.56"), currency=currencies.EUR,
203
- identifier=token, cof_ini=cof.SUBSEQUENT, cof_type=cof.RECURRING, cof_txnid=cof_txnid,
204
- excep_sca=sca.MIT, direct_payment="true",
205
- ).send()
206
- ```
207
-
208
- `redsys.cof` provides the indicator constants (`INITIAL`/`SUBSEQUENT`, `RECURRING`/`INSTALLMENT`/...) and the `REQUEST_TOKEN` sentinel. The token and COF fields are also accepted by `RedirectClient.payment()`, so the first payment can run on the RedSys page. The periodic fields (`sum_total`, `date_frequency`, `charge_expiry_date`) are accepted by `DirectClient.payment()`. `redsys.sca` holds the PSD2 exemption codes for `excep_sca` (`LWV`, `TRA`, `MIT`, `COR`, `ATD`); `sca.QUERY` on `inicia()` asks which exemptions the card allows, returned in `response.excep_sca`.
209
-
210
- ## Signature versions
211
-
212
- `signature_version` on the client constructor selects the scheme; the constants are in `redsys.clients`.
213
-
214
- - `HMAC_SHA512_V2` (AES-128 + HMAC-SHA512): the default, as in RedSys's redirection guide and libraries.
215
- - `HMAC_SHA512_V1`: the same algorithm with padded encoding, as in the REST guide.
216
- - `HMAC_SHA256_V1` (3DES): legacy, still accepted by RedSys.
217
-
218
- ## Reference
219
-
220
- - [`docs/response-codes.md`](docs/response-codes.md): response-code meanings.
221
- - [`docs/redirect-connection.md`](docs/redirect-connection.md) / [`docs/direct-connection.md`](docs/direct-connection.md): connection-type protocol reference.
222
-
223
- ## Contributing
224
-
225
- Dev setup, checks and live tests are in [`CONTRIBUTING.md`](CONTRIBUTING.md); contributors are listed in [`CONTRIBUTORS.md`](CONTRIBUTORS.md).
@@ -1,20 +0,0 @@
1
- python_redsys-2.1.0.dist-info/licenses/LICENSE,sha256=qsc7MUj20dcRHbyjIJn2jSbGRMaBOuHk8F9leaomY_4,11360
2
- python_redsys-2.1.0.dist-info/licenses/NOTICE,sha256=6tlv5QuzsbfmGxsQNEcN7Uopzyp7vgD54xb-_L4DGyE,201
3
- redsys/__init__.py,sha256=bhpyzXB0Y-3FORBJlV4dZ3vnrz1jSc-sbZ9hyb7itFo,138
4
- redsys/clients.py,sha256=b9K4jCSLC9JNWUS8wVFqkc9im_a5ukSA-JpunbhKEBc,11067
5
- redsys/crypto.py,sha256=GOm8RkDYnD83fMNwey-bxLg3vWf6xbNzWbza6m23M9M,5480
6
- redsys/exceptions.py,sha256=MqknsHm4sI5iAelrYcAuqSC70u1hhqdLyvA27vKcLHY,601
7
- redsys/models.py,sha256=9YqPBUc0LgEEFhvZiwzdM16w2DyqICF5DnXrvrVK4Po,16653
8
- redsys/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
9
- redsys/request.py,sha256=dVAQ0zSVmdyUPjnERo_62xilNQk3-LGJTbR6im_y0fQ,2408
10
- redsys/threeds.py,sha256=IheD2mWVD9Pw7efRP6_a170LVppSSlKpyxhUJVI3LnU,2244
11
- redsys/api/__init__.py,sha256=tjuisAfTqUpk7cdQq8ZayZk1cwaJ1ntqt1zgVbLamyw,111
12
- redsys/api/cof.py,sha256=fEf9ugVvOMs-jAzXkXDQl4NshyZuSYvbYfqnRH8otrk,660
13
- redsys/api/currencies.py,sha256=GufqxjAb941KMZ2S2mJJ980Xz4naJ2GgkcOVwuPx0ms,1043
14
- redsys/api/languages.py,sha256=GPw7JB-CWDyGo6vhcPZDzpjGuwkojFCz1gyfx13wlek,872
15
- redsys/api/sca.py,sha256=09b9LV9dvBADDTfHnReMR3OuM38ViVRqQs_hLQFBEoE,786
16
- redsys/api/transactions.py,sha256=MzBdsgn_27_nayxCavs15tXQShjm4NsGbQVAeTn9oTg,1633
17
- python_redsys-2.1.0.dist-info/METADATA,sha256=Q9DeegOyNcRZ76kari8o2O9Rh_d-DOHt2Qfu7yk9tJk,10632
18
- python_redsys-2.1.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
19
- python_redsys-2.1.0.dist-info/top_level.txt,sha256=79TrHj--FP5SDyZO42-NUsiYJmHiQX42txZigHOqghY,7
20
- python_redsys-2.1.0.dist-info/RECORD,,