SDK Python officiel de Wourapay — vérification serveur des paiements et des webhooks
Project description
wourapay — SDK Python
SDK officiel de Wourapay pour les backends.
Deux usages, et rien d'autre :
- Vérifier un paiement avant de livrer une commande.
- Vérifier la signature d'un callback avant de traiter son contenu.
Encaisser, créer des liens de paiement ou gérer des sous-comptes se fait directement en HTTP — un wrapper y ajouterait une surface à maintenir sans rien simplifier. Voir la documentation API.
pip install wourapay
1. Vérifier un paiement
Après que votre front a affiché « paiement réussi », vérifiez côté serveur. Le navigateur peut affirmer n'importe quoi ; seul cet appel fait autorité.
from wourapay import Wourapay
client = Wourapay(api_key="kpy_…") # ou variable WOURAPAY_API_KEY
result = client.verify(reference="ORDER-2026-001")
if result.verified:
deliver_order()
verified est la seule valeur sur laquelle livrer : elle vaut True
uniquement si la transaction vous appartient et qu'elle est réellement
successful. Un status renseigné ne suffit pas.
Si la transaction n'est pas encore terminale, l'API la revérifie en direct auprès de l'agrégateur avant de répondre.
Recherche par identifiant Wourapay
result = client.verify(transaction_id="e5f2…")
Version asynchrone
from wourapay import AsyncWourapay
async with AsyncWourapay(api_key="kpy_…") as client:
result = await client.verify(reference="ORDER-1")
Le résultat
| Champ | Description |
|---|---|
verified |
True ⇔ transaction à vous et successful |
status |
pending · processing · successful · failed · expired · not_found |
transaction_id, display_id, reference |
Identifiants |
amount, currency, network_code |
Montant et réseau |
client_id |
Sous-compte crédité, le cas échéant |
paid_at |
Horodatage du succès |
raw |
Réponse brute, pour les champs ajoutés après cette version |
2. Vérifier un callback
Wourapay signe chaque callback. Vérifiez la signature avant de traiter le contenu : un callback non vérifié n'est qu'une assertion d'un inconnu sur l'état de votre argent.
from wourapay import verify_webhook_signature
@app.post("/webhooks/wourapay")
async def handle(request):
body = await request.body() # OCTETS BRUTS
header = request.headers["X-Wourapay-Signature"]
if not verify_webhook_signature(body, header, secret=WEBHOOK_SECRET):
return Response(status_code=400)
event = json.loads(body)
...
Votre secret (whsec_…) est lisible dans votre espace marchand, section
Webhooks.
Deux pièges à éviter
Passez le corps brut. Jamais un JSON re-sérialisé : un espace ou un ordre de clés différent invalide la signature.
verify_webhook_signature(await request.body(), header, secret) # ✅
verify_webhook_signature(json.dumps(request.json()), header, secret) # ❌
Ne désactivez pas la tolérance en production. L'horodatage fait partie de la
signature : c'est ce qui empêche le rejeu d'une capture réseau. tolerance=0
est réservé aux tests.
Rotation de secret
Quand vous régénérez votre secret, Wourapay signe pendant 24 h avec l'ancien et le nouveau. Déployez votre nouveau secret quand vous voulez dans cette fenêtre : aucun callback n'est perdu.
Laisser remonter l'erreur
from wourapay import verify_webhook_signature, InvalidSignature
try:
verify_webhook_signature(body, header, secret, raise_on_error=True)
except InvalidSignature as exc:
return Response(str(exc), status_code=400)
Le module de signature ne dépend que de la bibliothèque standard : il reste utilisable dans une fonction serverless qui n'installe rien d'autre.
Erreurs
Toutes dérivent de WourapayError : un seul except suffit à ne rien laisser
passer.
| Exception | Quand |
|---|---|
AuthenticationError |
Clé absente, invalide ou révoquée |
APIError |
L'API a répondu une erreur — porte status_code et payload |
NetworkError |
API injoignable : DNS, TLS, timeout, coupure |
InvalidSignature |
Signature absente, expirée ou ne correspondant pas |
WourapayError |
Base commune |
NetworkError mérite une attention particulière : contrairement à APIError,
elle veut dire « on ne sait pas », pas « le paiement a échoué ». Sur une
vérification, c'est un signal de réessai, jamais de refus de commande.
Développement
pip install -e ".[dev]"
pytest
Les vecteurs de tests/test_webhooks.py font foi : ils doivent rester alignés
sur l'implémentation de référence côté API. Un test qui diverge signifie qu'un
marchand rejettera des callbacks légitimes — ou pire, en acceptera de falsifiés.
Licence
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wourapay-0.1.0.tar.gz.
File metadata
- Download URL: wourapay-0.1.0.tar.gz
- Upload date:
- Size: 10.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
31b185b01506153ff563d46b99c673bf4e85f92330d49f1645f2bf45b1a2eddd
|
|
| MD5 |
d200f33a5ea31a4c4ceadf12dc697c99
|
|
| BLAKE2b-256 |
b52aac25582e7bce6556dc85a90b1b5a51903deb041b2225db0504d1393d2771
|
File details
Details for the file wourapay-0.1.0-py3-none-any.whl.
File metadata
- Download URL: wourapay-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9fe3688a3c9f6938be57b12d380ea5eb1ef10324267e084b25d451c75e9c424d
|
|
| MD5 |
97831e6729ae6ab8b0101052d1b1cbfb
|
|
| BLAKE2b-256 |
6443542eeb333e5453055d199d8cdfbbeeaba33145f9e1b56c0ed916a37c04fd
|