python-redsys 2.0.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.
@@ -0,0 +1,187 @@
1
+ Metadata-Version: 2.4
2
+ Name: python-redsys
3
+ Version: 2.2.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>=50
25
+ Requires-Dist: pydantic>=2.13
26
+ Provides-Extra: http
27
+ Requires-Dist: httpx>=0.26; extra == "http"
28
+ Dynamic: license-file
29
+
30
+ # 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 lightweight client for the RedSys TPV Virtual: it builds signed requests and verifies and parses responses, for the *redirect connection* (browser form) and the *direct connection* (server-to-server REST). For Django, see [django-redsys](https://github.com/ddiazpinto/django-redsys).
35
+
36
+ ## Installation
37
+
38
+ ```bash
39
+ pip install python-redsys
40
+ pip install "python-redsys[http]" # optional: sends direct-connection requests with httpx
41
+ ```
42
+
43
+ Python 3.10 or later. Runtime dependencies: `cryptography` and `pydantic` 2.
44
+
45
+ ## Redirect connection
46
+
47
+ ```python
48
+ from decimal import Decimal
49
+ from redsys import generate_order
50
+ from redsys.clients import RedirectClient
51
+
52
+ client = RedirectClient(secret_key="...", merchant_code="999008881", terminal=1, sandbox=True)
53
+
54
+ # 1. Build the signed request.
55
+ request = client.payment(
56
+ order=generate_order(),
57
+ amount=Decimal("10.56"), # euros unless currency= says otherwise
58
+ merchant_url="https://example.com/redsys/notification",
59
+ url_ok="https://example.com/ok",
60
+ url_ko="https://example.com/ko",
61
+ )
62
+
63
+ # 2. The browser POSTs request.to_dict() (three fields) to request.endpoint.
64
+
65
+ # 3. Verify and read the notification RedSys posts to merchant_url.
66
+ response = client.parse_response(received_fields)
67
+ if response.is_paid():
68
+ ...
69
+ else:
70
+ print(response.response_code, response.describe("en"))
71
+ ```
72
+
73
+ The redirect connection takes `payment()`, `preauthorization()`, `authentication()` and `refund_without_original()`.
74
+
75
+ ## Direct connection
76
+
77
+ ```python
78
+ from redsys.clients import DirectClient
79
+
80
+ client = DirectClient(secret_key="...", merchant_code="999008881", terminal=1, sandbox=True)
81
+
82
+ response = client.refund(order="000000001", amount=Decimal("10.56")).send() # signs, posts, verifies
83
+ response.is_refunded()
84
+ ```
85
+
86
+ - `AsyncDirectClient` has the same methods; `await request.send()`.
87
+ - Without the `http` extra, POST `request.to_dict()` to `request.endpoint` with any HTTP client and pass the JSON answer to `client.parse_response()`.
88
+ - Operations: `payment`, `preauthorization`, `confirmation`, `partial_confirmation`, `refund`, `refund_without_original`, `void`, `payment_cancellation`, `authentication`, `authentication_confirmation`, `pay_gold`, and `request(transaction_type, ...)` for any other type in `redsys.transactions`.
89
+
90
+ ## 3-D Secure
91
+
92
+ Card data sent by the merchant goes through EMV3DS. The library builds each call; the browser steps (3DSMethod iframe, challenge form) are the integrator's.
93
+
94
+ ```python
95
+ from redsys import emv3ds, threeds
96
+
97
+ card = dict(pan="4548810000000003", expiry_date="4912", cvv2="123")
98
+ operation = dict(order=generate_order(), amount=Decimal("10.56"))
99
+
100
+ config = client.inicia_payment(**operation, **card).send()
101
+ # Optional 3DSMethod: the browser posts threeds.method_data(...) to config.three_ds_method_url.
102
+
103
+ authentication = threeds.authentication_data(
104
+ three_ds_server_trans_id=config.three_ds_server_trans_id,
105
+ notification_url="https://example.com/redsys/3ds",
106
+ protocol_version=config.protocol_version,
107
+ browser=threeds.browser_info(...), # collected by the merchant page
108
+ three_ds_comp_ind=emv3ds.METHOD_COMPLETED,
109
+ )
110
+ response = client.payment(emv3ds=authentication, **operation, **card).send()
111
+
112
+ if response.requires_challenge():
113
+ # The browser posts response.creq to response.acs_url; the ACS posts cres back to notification_url.
114
+ response = client.challenge_response(
115
+ cres=cres, protocol_version=response.protocol_version, **operation, **card
116
+ ).send()
117
+ ```
118
+
119
+ ## Stored cards and merchant-initiated payments
120
+
121
+ ```python
122
+ from redsys import cof, options, sca
123
+
124
+ first = client.payment(..., identifier=cof.REQUEST_TOKEN, cof_ini=cof.INITIAL, cof_type=cof.RECURRING)
125
+ # After 3-D Secure: first.identifier is the token, first.cof_txnid the network transaction id.
126
+
127
+ client.payment(
128
+ order=generate_order(), amount=Decimal("10.56"),
129
+ identifier=token, cof_txnid=cof_txnid, cof_ini=cof.SUBSEQUENT, cof_type=cof.RECURRING,
130
+ excep_sca=sca.MIT, direct_payment=options.DIRECT_PAYMENT,
131
+ ).send()
132
+ ```
133
+
134
+ ## Payment methods
135
+
136
+ - **Bizum, redirect:** `pay_methods=pay_methods.BIZUM` on `payment()`.
137
+ - **Bizum Request-to-Pay, direct:** the same, plus `bizum_mobile_number` and `endpoint=client.url(environments.RTP_TRATA_PATH)`; read `response.rtp_status` and `response.rtp_response` (`redsys.bizum`).
138
+ - **PayGold link:** `pay_gold(customer_mobile=..., customer_sms_text=f"{paygold.SMS_AMOUNT} {paygold.SMS_URL}")`; the link is `response.url_pago_2_fases`.
139
+ - **Google Pay and Apple Pay:** `xpay_data` (or `xpay_decoded_data`) with `xpay_type=xpay.GOOGLE` and `xpay_origen=xpay.WEB`.
140
+ - **inSite:** `idoper=` with the token from RedSys's JavaScript, on a direct `payment()`.
141
+
142
+ ## Configuration
143
+
144
+ | Option | Use |
145
+ |---|---|
146
+ | `environment=` | `environments.TEST`, `PROD`, `INTE` or `DESA`; `sandbox=True` is `TEST` |
147
+ | `Client.from_api_key(api_key)` | Reads the environment, merchant code, terminal and secret key from a RedSys API key |
148
+ | `currency=` | Default currency of the client (`currencies.EUR` unless set); a call can override it |
149
+ | `signature_version=` | `HMAC_SHA512_V2` (default), `HMAC_SHA512_V1` or legacy `HMAC_SHA256_V1`, from `redsys.clients` |
150
+ | `module=` | `Ds_Merchant_Module` of every request: `python-redsys/<version>` by default, another text, or `None` to leave it out |
151
+ | `endpoint=` on an operation | Sends that request to another HTTPS URL; `client.url(path)` builds one |
152
+
153
+ Every documented value has a named constant in `redsys` (`transactions`, `currencies`, `languages`, `pay_methods`, `cof`, `sca`, `options`, `emv3ds`, `cards`, `responses`, ...). Use them instead of literals.
154
+
155
+ ## Errors
156
+
157
+ Fields are validated when the operation method is called, before anything is signed or sent. Any invalid parameter raises a `ValueError` subclass:
158
+
159
+ | Problem | Raised |
160
+ |---|---|
161
+ | A field with the wrong type or format, a missing required field, a misspelled or 1.x field name, an unknown currency or transaction type | `pydantic.ValidationError`; `.errors()` lists each field |
162
+ | A transaction type that contradicts the operation or the redirect connection, a non-HTTPS `endpoint`, an invalid API key or environment | `redsys.exceptions.ValidationError` |
163
+ | A signature that does not match in `parse_response()` | `ValueError` |
164
+ | RedSys answers with an error code instead of a signed result | `redsys.exceptions.ResponseError`; `.error_code` holds the `SISnnnn` code |
165
+ | An HTTP error status from RedSys in `send()` | `httpx.HTTPStatusError` |
166
+
167
+ A parameter the library does not model yet can be passed by its wire name (`Ds_Merchant_...`): it is sent as given, with an `UnknownParameterWarning`.
168
+
169
+ ## Response codes
170
+
171
+ `response.response_code` is the integer `Ds_Response`; `response.is_paid()` (0 to 99), `is_refunded()` (900), `is_canceled()` (400) and `is_authorized()` (any of them) cover the common outcomes. `response.describe(language)` and `redsys.codes.describe(code, language)` give the meaning of any `Ds_Response`, `SISnnnn` or Bizum `BIZnnnnn` code. Table: [`docs/response-codes.md`](docs/response-codes.md).
172
+
173
+ ## Status
174
+
175
+ | | |
176
+ |---|---|
177
+ | Version | 2.2.0; 1.x receives fixes until 2026-12-31 ([migration guide](docs/migration-1x-to-2x.md)) |
178
+ | Python | 3.10 to 3.15 |
179
+ | RedSys documents followed | Redirection guide 4.2, REST guide 4.0.1, Bizum guide 2.6, inSite guide 4.1, PayGold guide 1.8.2, Google Pay guide 1.9, Apple Pay guide 3.2, "Parámetros de entrada y salida" page |
180
+ | Verified against the RedSys test environment | Redirect in a browser with the 3DS challenge; direct end to end (frictionless and challenged 3DS, 3DSMethod, refund, void, payment cancellation, stored-card merchant-initiated charge), in all three signature versions |
181
+
182
+ ## Reference
183
+
184
+ - [`docs/redirect-connection.md`](docs/redirect-connection.md) and [`docs/direct-connection.md`](docs/direct-connection.md): protocol reference for each connection.
185
+ - [`docs/response-codes.md`](docs/response-codes.md): response, SIS and Bizum codes.
186
+ - [`docs/official-libraries.md`](docs/official-libraries.md): equivalences for integrators of RedSys's PHP and Java libraries.
187
+ - [`CONTRIBUTING.md`](CONTRIBUTING.md): development setup, checks and live tests.
@@ -0,0 +1,34 @@
1
+ python_redsys-2.2.0.dist-info/licenses/LICENSE,sha256=qsc7MUj20dcRHbyjIJn2jSbGRMaBOuHk8F9leaomY_4,11360
2
+ python_redsys-2.2.0.dist-info/licenses/NOTICE,sha256=6tlv5QuzsbfmGxsQNEcN7Uopzyp7vgD54xb-_L4DGyE,201
3
+ redsys/__init__.py,sha256=pLpynJ40Qpr4yM9TX8MZ0pTrbl7TkbVp9cQog1NA-hI,605
4
+ redsys/_code_texts.py,sha256=NLkVpNRNphxWIbvBYBJ96xFwrb_fbioEYXkBfKdKxEI,197037
5
+ redsys/clients.py,sha256=mqcSZHeOklXTDxjlpptdGWmlqkB9fwc6rMtImvyv3uc,20266
6
+ redsys/codes.py,sha256=wxoV9h85zwNbsRDcZI3gpc9Q3JBSsVuybHeqtg7xrn4,2508
7
+ redsys/crypto.py,sha256=FJxYzhqarhaIDwFxTlk7JFNOEXM2_AZ1TAh325sHC7k,5438
8
+ redsys/exceptions.py,sha256=wPHuuaHvAp9TriOMXnzaFAF3mCAWKQUu7LlWMjUoOk4,763
9
+ redsys/models.py,sha256=aIM8q02EQCNizWf6kuPuv8OL3pEiiiUpQUt4lAgnxVQ,27507
10
+ redsys/orders.py,sha256=ryYlu8wnbudQNeaUB1bKXg2WxHTzWjv-h_iu3ZguV60,786
11
+ redsys/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
12
+ redsys/request.py,sha256=5SxS3s2URXS_dVk5HaYO-o9tyw4PkWwsKKaQC9J-5GY,2356
13
+ redsys/threeds.py,sha256=wtGcduv9a84S7CKL8k1kA_q_5o98L5AGYM32OeGNQ9I,2589
14
+ redsys/api/__init__.py,sha256=ORl2UtMhq3z51luED3tFr7n98KEl9IpuDHUfxJ_F8So,81
15
+ redsys/api/bizum.py,sha256=WkfhGx5pmvIxFG9-NkjaBnC3ccKH37Kf1zbaFbdpB4k,1934
16
+ redsys/api/cards.py,sha256=iGRQDf6sjSEhmsgbpM3DlRcnLk-OhGbWHQSlAT4OmjM,1069
17
+ redsys/api/cof.py,sha256=fEf9ugVvOMs-jAzXkXDQl4NshyZuSYvbYfqnRH8otrk,660
18
+ redsys/api/currencies.py,sha256=pjJf64k5nVuvG3N99AUjPN2BBTzlwUBEO9Co76CGRus,999
19
+ redsys/api/emv3ds.py,sha256=U3nfkOIobMBk8UPCjt_6yZcAEpvOM6J0Tq4B_h02T_c,3160
20
+ redsys/api/environments.py,sha256=-aY5hP-WOr3mRl0p-J4da64XcPss8ewEaN7o1cwYjPs,1142
21
+ redsys/api/languages.py,sha256=fl4mG6cBFNSOMcAMY1mj4w19NeZ1HyAwEGYt_oIe2KU,1043
22
+ redsys/api/options.py,sha256=2Bw_IIlso8Lep7mpOMMHK7OzMLdlmhYRT-WSkTFa1GM,1156
23
+ redsys/api/pay_methods.py,sha256=LTjmAf0fKDZg6HEDhRHyGdtB8fOjeK99exQbF8oMbug,730
24
+ redsys/api/paygold.py,sha256=YGEnbOpjpt6PKG8zkUTwLQ6w5198BJSJ4yzt6T7SJXs,1125
25
+ redsys/api/processed_pay_methods.py,sha256=ZxN4GRi7iLbXldcoBbD1bIpXkzeYpyOX4QTzHE56xpo,3805
26
+ redsys/api/responses.py,sha256=qrS3YaM-NxBmXjRKPZlUgtcFl5aMWGADFKGIwEfCeXM,7333
27
+ redsys/api/sca.py,sha256=521jL7B_GZF-gymx3xDpEJCYhZVu5NSPM51TGEt0J34,1039
28
+ redsys/api/secure_payment.py,sha256=QxzhFMLHbCQdb1-J9kbfuWq4rp6URPUrY1yVMZ3Kv3c,403
29
+ redsys/api/transactions.py,sha256=PMDMlsrxgjoWUOZLpi2BsJK1Mrdvc0Ihjdz1icodvKE,2146
30
+ redsys/api/xpay.py,sha256=KRojPBEkS3yhvrVJCUBP_8L8gxfVImS13tbmESe46ew,693
31
+ python_redsys-2.2.0.dist-info/METADATA,sha256=wOUEzK-ejf_xMs4wUtlkO7gGBHOnALKPdRI9hbelHUg,9904
32
+ python_redsys-2.2.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
33
+ python_redsys-2.2.0.dist-info/top_level.txt,sha256=79TrHj--FP5SDyZO42-NUsiYJmHiQX42txZigHOqghY,7
34
+ python_redsys-2.2.0.dist-info/RECORD,,
redsys/__init__.py CHANGED
@@ -1,3 +1,39 @@
1
- from redsys.api import cof, currencies, languages, sca, transactions
1
+ from redsys.api import (
2
+ bizum,
3
+ cards,
4
+ cof,
5
+ currencies,
6
+ emv3ds,
7
+ environments,
8
+ languages,
9
+ options,
10
+ pay_methods,
11
+ paygold,
12
+ processed_pay_methods,
13
+ responses,
14
+ sca,
15
+ secure_payment,
16
+ transactions,
17
+ xpay,
18
+ )
19
+ from redsys.orders import generate_order
2
20
 
3
- __all__ = ['cof', 'currencies', 'languages', 'sca', 'transactions']
21
+ __all__ = [
22
+ 'bizum',
23
+ 'cards',
24
+ 'cof',
25
+ 'currencies',
26
+ 'emv3ds',
27
+ 'environments',
28
+ 'generate_order',
29
+ 'languages',
30
+ 'options',
31
+ 'pay_methods',
32
+ 'paygold',
33
+ 'processed_pay_methods',
34
+ 'responses',
35
+ 'sca',
36
+ 'secure_payment',
37
+ 'transactions',
38
+ 'xpay',
39
+ ]