paylet 0.1.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.
paylet-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,127 @@
1
+ Metadata-Version: 2.4
2
+ Name: paylet
3
+ Version: 0.1.0
4
+ Summary: SDK Paylet FR — passerelle de micro-paiement M2M (x402 / HTTP 402).
5
+ Author: Paylet FR
6
+ License: MIT
7
+ Keywords: x402,402,payment,m2m,micropayment,paylet
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: MIT License
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: Topic :: Software Development :: Libraries
18
+ Requires-Python: >=3.10
19
+ Description-Content-Type: text/markdown
20
+ Provides-Extra: dev
21
+ Requires-Dist: pytest>=8.0; extra == "dev"
22
+
23
+ # Paylet FR — SDK Python
24
+
25
+ SDK Python de la passerelle Paylet FR, passerelle de micro-paiement
26
+ Machine-to-Machine (M2M) compatible x402 / HTTP 402 Payment Required.
27
+
28
+ Le SDK enveloppe la gateway Paylet et orchestre le flux de paiement à la
29
+ volée : un agent appelle une ressource payante, reçoit un challenge 402, le
30
+ règle, puis rejoue la requête avec la preuve de paiement.
31
+
32
+ - Aucune dépendance runtime (bibliothèque standard uniquement).
33
+ - Montants exacts en micro-crédits (entiers), zéro flottant.
34
+ - Idempotence automatique (`Idempotency-Key`), retries avec backoff.
35
+ - Helpers de signature HMAC-SHA256 côté vendeur.
36
+
37
+ ## Installation
38
+
39
+ ```bash
40
+ pip install ./sdk-python
41
+ # ou, en développement :
42
+ pip install -e ./sdk-python
43
+ ```
44
+
45
+ ## Démarrage rapide
46
+
47
+ ```python
48
+ from paylet import Paylet, Money
49
+
50
+ client = Paylet("ak_live_<votre-cle>") # clé M2M, header X-API-Key
51
+
52
+ # Solde du compte
53
+ solde = client.get_balance()
54
+ print(solde.available) # -> 3.42 EUR
55
+ print(solde.available.minor) # -> 3420000 micro-crédits
56
+
57
+ # Accès à une ressource payante : le 402 est géré automatiquement
58
+ data = client.fetch_paid("GET", "https://vendor.example.com/data/42")
59
+ print(data)
60
+ ```
61
+
62
+ Le flux `fetch_paid` exécute la séquence x402 complète : appel sans preuve
63
+ -> 402 `payment_required` -> règlement (`POST /v1/payments`) -> rejeu avec
64
+ l'en-tête `X-Payment` -> livraison de la ressource.
65
+
66
+ ## Fonctions exposées
67
+
68
+ ### Classe `Paylet` (client gateway + flux x402)
69
+
70
+ | Méthode | Endpoint | Description |
71
+ |------------------------|-----------------------------|--------------------------------------------------|
72
+ | `get_balance()` | GET /v1/balance | solde courant, réservé, disponible |
73
+ | `get_ledger(**f)` | GET /v1/ledger | écritures du grand livre (pagination curseur) |
74
+ | `list_transactions(**f)` | GET /v1/transactions | liste des transactions |
75
+ | `get_transaction(id)` | GET /v1/transactions/{id} | une transaction |
76
+ | `get_payment(id)` | GET /v1/payments/{id} | un paiement |
77
+ | `get_payment_receipt(id)` | GET /v1/payments/{id}/receipt | récupère un reçu signé perdu |
78
+ | `settle(challenge, ...)` | POST /v1/payments | règle un challenge 402, renvoie un `Payment` |
79
+ | `fetch_paid(method, url, ...)` | — (vendeur tiers) | flux x402 de bout en bout |
80
+
81
+ ### Type `Money` (montants exacts, zéro flottant)
82
+
83
+ - `Money.from_minor(1500000)` : depuis un entier de micro-crédits.
84
+ - `Money.from_eur("1.50")` : depuis un prix en euros (chaîne ou `Decimal`).
85
+ - `.minor` : l'entier de micro-crédits.
86
+ - `.to_eur_str()` : la valeur en euros sous forme de chaîne.
87
+
88
+ `1 EUR = 1 000 000 micro-crédits`. Aucune conversion silencieuse : passer un
89
+ flottant à `Money` lève `TypeError`.
90
+
91
+ ### Exceptions (`paylet.errors`)
92
+
93
+ Hiérarchie typée par code d'erreur (contrat section 4.4) :
94
+ `InsufficientFundsError`, `ChallengeExpiredError`, `ChallengeInvalidError`,
95
+ `IdempotencyConflictError`, `AuthenticationError`, `RateLimitedError`,
96
+ `NotFoundError`, etc. Toutes héritent de `PayletError` (attributs
97
+ `code`, `message`, `status_code`, `details`).
98
+
99
+ ### Signature et vendeur (`paylet.signing`, `paylet.vendor`)
100
+
101
+ - `sign_payload` / `verify_payload` : primitives HMAC-SHA256.
102
+ - `compute_payload_hash(body)` : empreinte `sha256:<hex>` du corps payant.
103
+ - `create_challenge` / `verify_challenge` : challenge x402 côté vendeur.
104
+ - `verify_receipt` : vérification locale d'un reçu (ressource, montant,
105
+ bénéficiaire), sans appel réseau.
106
+ - `Vendor` : regroupe ces opérations sous un objet.
107
+
108
+ ## Exemples runnables
109
+
110
+ ```bash
111
+ python exemples/demo_locale.py # démo de bout en bout, 100 % locale
112
+ python exemples/basic.py # usage minimal (clé + gateway réelles)
113
+ ```
114
+
115
+ ## Tests
116
+
117
+ ```bash
118
+ python -m unittest discover -t . -s tests -v
119
+ ```
120
+
121
+ ## Note d'interopérabilité
122
+
123
+ Le format exact du champ de signature des objets signés (challenge et reçu) —
124
+ champ `sig` ajouté au JSON canonique, le tout encodé en base64url — n'est pas
125
+ figé par ARCHITECTURE.md (qui ne précise que « HMAC-SHA256 + base64url »). Ce
126
+ SDK fixe donc une convention, identique en Python et en TypeScript, à valider
127
+ par l'architecte pour garantir l'interopérabilité avec la gateway.
paylet-0.1.0/README.md ADDED
@@ -0,0 +1,105 @@
1
+ # Paylet FR — SDK Python
2
+
3
+ SDK Python de la passerelle Paylet FR, passerelle de micro-paiement
4
+ Machine-to-Machine (M2M) compatible x402 / HTTP 402 Payment Required.
5
+
6
+ Le SDK enveloppe la gateway Paylet et orchestre le flux de paiement à la
7
+ volée : un agent appelle une ressource payante, reçoit un challenge 402, le
8
+ règle, puis rejoue la requête avec la preuve de paiement.
9
+
10
+ - Aucune dépendance runtime (bibliothèque standard uniquement).
11
+ - Montants exacts en micro-crédits (entiers), zéro flottant.
12
+ - Idempotence automatique (`Idempotency-Key`), retries avec backoff.
13
+ - Helpers de signature HMAC-SHA256 côté vendeur.
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ pip install ./sdk-python
19
+ # ou, en développement :
20
+ pip install -e ./sdk-python
21
+ ```
22
+
23
+ ## Démarrage rapide
24
+
25
+ ```python
26
+ from paylet import Paylet, Money
27
+
28
+ client = Paylet("ak_live_<votre-cle>") # clé M2M, header X-API-Key
29
+
30
+ # Solde du compte
31
+ solde = client.get_balance()
32
+ print(solde.available) # -> 3.42 EUR
33
+ print(solde.available.minor) # -> 3420000 micro-crédits
34
+
35
+ # Accès à une ressource payante : le 402 est géré automatiquement
36
+ data = client.fetch_paid("GET", "https://vendor.example.com/data/42")
37
+ print(data)
38
+ ```
39
+
40
+ Le flux `fetch_paid` exécute la séquence x402 complète : appel sans preuve
41
+ -> 402 `payment_required` -> règlement (`POST /v1/payments`) -> rejeu avec
42
+ l'en-tête `X-Payment` -> livraison de la ressource.
43
+
44
+ ## Fonctions exposées
45
+
46
+ ### Classe `Paylet` (client gateway + flux x402)
47
+
48
+ | Méthode | Endpoint | Description |
49
+ |------------------------|-----------------------------|--------------------------------------------------|
50
+ | `get_balance()` | GET /v1/balance | solde courant, réservé, disponible |
51
+ | `get_ledger(**f)` | GET /v1/ledger | écritures du grand livre (pagination curseur) |
52
+ | `list_transactions(**f)` | GET /v1/transactions | liste des transactions |
53
+ | `get_transaction(id)` | GET /v1/transactions/{id} | une transaction |
54
+ | `get_payment(id)` | GET /v1/payments/{id} | un paiement |
55
+ | `get_payment_receipt(id)` | GET /v1/payments/{id}/receipt | récupère un reçu signé perdu |
56
+ | `settle(challenge, ...)` | POST /v1/payments | règle un challenge 402, renvoie un `Payment` |
57
+ | `fetch_paid(method, url, ...)` | — (vendeur tiers) | flux x402 de bout en bout |
58
+
59
+ ### Type `Money` (montants exacts, zéro flottant)
60
+
61
+ - `Money.from_minor(1500000)` : depuis un entier de micro-crédits.
62
+ - `Money.from_eur("1.50")` : depuis un prix en euros (chaîne ou `Decimal`).
63
+ - `.minor` : l'entier de micro-crédits.
64
+ - `.to_eur_str()` : la valeur en euros sous forme de chaîne.
65
+
66
+ `1 EUR = 1 000 000 micro-crédits`. Aucune conversion silencieuse : passer un
67
+ flottant à `Money` lève `TypeError`.
68
+
69
+ ### Exceptions (`paylet.errors`)
70
+
71
+ Hiérarchie typée par code d'erreur (contrat section 4.4) :
72
+ `InsufficientFundsError`, `ChallengeExpiredError`, `ChallengeInvalidError`,
73
+ `IdempotencyConflictError`, `AuthenticationError`, `RateLimitedError`,
74
+ `NotFoundError`, etc. Toutes héritent de `PayletError` (attributs
75
+ `code`, `message`, `status_code`, `details`).
76
+
77
+ ### Signature et vendeur (`paylet.signing`, `paylet.vendor`)
78
+
79
+ - `sign_payload` / `verify_payload` : primitives HMAC-SHA256.
80
+ - `compute_payload_hash(body)` : empreinte `sha256:<hex>` du corps payant.
81
+ - `create_challenge` / `verify_challenge` : challenge x402 côté vendeur.
82
+ - `verify_receipt` : vérification locale d'un reçu (ressource, montant,
83
+ bénéficiaire), sans appel réseau.
84
+ - `Vendor` : regroupe ces opérations sous un objet.
85
+
86
+ ## Exemples runnables
87
+
88
+ ```bash
89
+ python exemples/demo_locale.py # démo de bout en bout, 100 % locale
90
+ python exemples/basic.py # usage minimal (clé + gateway réelles)
91
+ ```
92
+
93
+ ## Tests
94
+
95
+ ```bash
96
+ python -m unittest discover -t . -s tests -v
97
+ ```
98
+
99
+ ## Note d'interopérabilité
100
+
101
+ Le format exact du champ de signature des objets signés (challenge et reçu) —
102
+ champ `sig` ajouté au JSON canonique, le tout encodé en base64url — n'est pas
103
+ figé par ARCHITECTURE.md (qui ne précise que « HMAC-SHA256 + base64url »). Ce
104
+ SDK fixe donc une convention, identique en Python et en TypeScript, à valider
105
+ par l'architecte pour garantir l'interopérabilité avec la gateway.
@@ -0,0 +1,100 @@
1
+ """Paylet FR — SDK Python.
2
+
3
+ Client M2M de la passerelle Paylet, compatible x402 (HTTP 402 Payment
4
+ Required). Fournit :
5
+
6
+ - ``Paylet`` : client gateway (solde, grand livre, transactions, paiements)
7
+ et orchestration du flux x402 (``fetch_paid``).
8
+ - ``Money`` : montants exacts en micro-crédits (entiers, zéro flottant).
9
+ - ``errors`` : hiérarchie d'exceptions typées par code d'erreur.
10
+ - ``signing`` : primitives HMAC-SHA256 (challenge et reçu x402).
11
+ - ``vendor`` : helpers côté marchand vendeur (signer un challenge, vérifier
12
+ un reçu sans appel réseau).
13
+
14
+ Exemple minimal ::
15
+
16
+ from paylet import Paylet
17
+
18
+ client = Paylet("ak_live_<votre-cle>")
19
+ solde = client.get_balance()
20
+ print(solde.available.to_eur_str()) # "1.50"
21
+ """
22
+
23
+ from .client import Paylet, Balance, HTTPResponse, Page, Payment, Transport
24
+ from .errors import (
25
+ PayletAPIError,
26
+ PayletError,
27
+ AuthenticationError,
28
+ ChallengeExpiredError,
29
+ ChallengeInvalidError,
30
+ ForbiddenError,
31
+ IdempotencyConflictError,
32
+ InsufficientFundsError,
33
+ InternalError,
34
+ InvalidRequestError,
35
+ NetworkError,
36
+ NotFoundError,
37
+ PaymentRequiredError,
38
+ RateLimitedError,
39
+ RetryExhaustedError,
40
+ SignatureError,
41
+ )
42
+ from .money import (
43
+ FEE_FLOOR_MINOR,
44
+ FEE_RATE_BASIS_POINTS,
45
+ MICRO_CREDITS_PER_EUR,
46
+ Money,
47
+ compute_fee_minor,
48
+ )
49
+ from .signing import (
50
+ b64url_decode,
51
+ b64url_encode,
52
+ canonical_json,
53
+ compute_payload_hash,
54
+ sign_payload,
55
+ verify_payload,
56
+ )
57
+ from .vendor import Vendor, create_challenge, verify_challenge, verify_receipt
58
+
59
+ __version__ = "0.1.0"
60
+
61
+ __all__ = [
62
+ "Paylet",
63
+ "Balance",
64
+ "Page",
65
+ "Payment",
66
+ "HTTPResponse",
67
+ "Transport",
68
+ "Money",
69
+ "MICRO_CREDITS_PER_EUR",
70
+ "FEE_RATE_BASIS_POINTS",
71
+ "FEE_FLOOR_MINOR",
72
+ "compute_fee_minor",
73
+ "Vendor",
74
+ "create_challenge",
75
+ "verify_challenge",
76
+ "verify_receipt",
77
+ "compute_payload_hash",
78
+ "sign_payload",
79
+ "verify_payload",
80
+ "canonical_json",
81
+ "b64url_encode",
82
+ "b64url_decode",
83
+ "PayletError",
84
+ "PayletAPIError",
85
+ "InvalidRequestError",
86
+ "AuthenticationError",
87
+ "ForbiddenError",
88
+ "NotFoundError",
89
+ "IdempotencyConflictError",
90
+ "InsufficientFundsError",
91
+ "ChallengeExpiredError",
92
+ "ChallengeInvalidError",
93
+ "PaymentRequiredError",
94
+ "RateLimitedError",
95
+ "InternalError",
96
+ "NetworkError",
97
+ "RetryExhaustedError",
98
+ "SignatureError",
99
+ "__version__",
100
+ ]